diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-02-02 12:21:57 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-02-12 08:13:00 +0000 |
commit | 606d85f2a5386472314d39923da28c70c60dc8e7 (patch) | |
tree | a8f4d7bf997f349f45605e6058259fba0630e4d7 /chromium/storage | |
parent | 5786336dda477d04fb98483dca1a5426eebde2d7 (diff) | |
download | qtwebengine-chromium-606d85f2a5386472314d39923da28c70c60dc8e7.tar.gz |
BASELINE: Update Chromium to 96.0.4664.181
Change-Id: I762cd1da89d73aa6313b4a753fe126c34833f046
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/storage')
129 files changed, 3037 insertions, 2006 deletions
diff --git a/chromium/storage/browser/BUILD.gn b/chromium/storage/browser/BUILD.gn index 7013c7b14ee..bead925f060 100644 --- a/chromium/storage/browser/BUILD.gn +++ b/chromium/storage/browser/BUILD.gn @@ -383,6 +383,8 @@ static_library("test_support") { "test/mock_quota_manager_proxy.h", "test/mock_special_storage_policy.cc", "test/mock_special_storage_policy.h", + "test/quota_manager_proxy_sync.cc", + "test/quota_manager_proxy_sync.h", "test/sandbox_database_test_helper.cc", "test/sandbox_database_test_helper.h", "test/sandbox_file_system_test_helper.cc", @@ -399,6 +401,7 @@ static_library("test_support") { ":browser", "//base/test:test_support", "//build:chromeos_buildflags", + "//components/services/storage/public/cpp", "//components/services/storage/public/mojom", "//net:test_support", "//services/network:network_service", diff --git a/chromium/storage/browser/blob/COMMON_METADATA b/chromium/storage/browser/blob/COMMON_METADATA new file mode 100644 index 00000000000..cec432d4207 --- /dev/null +++ b/chromium/storage/browser/blob/COMMON_METADATA @@ -0,0 +1,3 @@ +monorail { + component: "Blink>Storage>FileAPI" +} diff --git a/chromium/storage/browser/blob/DIR_METADATA b/chromium/storage/browser/blob/DIR_METADATA index 30c02fb2b1a..9d48ccf1bed 100644 --- a/chromium/storage/browser/blob/DIR_METADATA +++ b/chromium/storage/browser/blob/DIR_METADATA @@ -6,6 +6,4 @@ # For the schema of this file, see Metadata message: # https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/proto/dir_metadata.proto -monorail { - component: "Blink>Storage>FileAPI" -} +mixins: "//storage/browser/blob/COMMON_METADATA" diff --git a/chromium/storage/browser/blob/blob_builder_from_stream.cc b/chromium/storage/browser/blob/blob_builder_from_stream.cc index 0a05b4e0364..d688f78da36 100644 --- a/chromium/storage/browser/blob/blob_builder_from_stream.cc +++ b/chromium/storage/browser/blob/blob_builder_from_stream.cc @@ -10,6 +10,7 @@ #include "base/metrics/histogram_macros.h" #include "base/task/post_task.h" #include "base/task/thread_pool.h" +#include "mojo/public/c/system/types.h" #include "mojo/public/cpp/bindings/associated_remote.h" #include "storage/browser/blob/blob_data_item.h" #include "storage/browser/blob/blob_storage_context.h" @@ -88,11 +89,28 @@ class DataPipeConsumerHelper { private: void DataPipeReady(MojoResult result, const mojo::HandleSignalsState& state) { + if (result != MOJO_RESULT_OK) { + // We requested a trap on a condition that can never occur. The state of + // `pipe_` likely changed. + DCHECK(result == MOJO_RESULT_FAILED_PRECONDITION); + InvokeDone(mojo::ScopedDataPipeConsumerHandle(), PassProgressClient(), + /*success=*/true, current_offset_); + delete this; + return; + } + while (current_offset_ < max_bytes_to_read_) { const void* data; uint32_t size; - MojoResult result = - pipe_->BeginReadData(&data, &size, MOJO_READ_DATA_FLAG_NONE); + result = pipe_->BeginReadData(&data, &size, MOJO_READ_DATA_FLAG_NONE); + if (result == MOJO_RESULT_INVALID_ARGUMENT) { + // `pipe_` is not actually a ScopedDataPipeConsumerHandle. + InvokeDone(mojo::ScopedDataPipeConsumerHandle(), PassProgressClient(), + /*success=*/false, /*bytes_written=*/0); + delete this; + return; + } + if (result == MOJO_RESULT_SHOULD_WAIT) { watcher_.ArmOrNotify(); return; diff --git a/chromium/storage/browser/blob/blob_builder_from_stream_unittest.cc b/chromium/storage/browser/blob/blob_builder_from_stream_unittest.cc index 3db6bbb9926..050db95440d 100644 --- a/chromium/storage/browser/blob/blob_builder_from_stream_unittest.cc +++ b/chromium/storage/browser/blob/blob_builder_from_stream_unittest.cc @@ -494,10 +494,8 @@ TEST_F(BlobBuilderFromStreamTestWithDelayedLimits, LargeStream) { std::make_unique<mojo::StringDataSource>( kData, mojo::StringDataSource::AsyncWritingMode:: STRING_STAYS_VALID_UNTIL_COMPLETION), - base::BindOnce( - base::DoNothing::Once<std::unique_ptr<mojo::DataPipeProducer>, - MojoResult>(), - std::move(data_producer))); + base::BindOnce([](std::unique_ptr<mojo::DataPipeProducer>, MojoResult) {}, + std::move(data_producer))); loop.Run(); ASSERT_TRUE(result); diff --git a/chromium/storage/browser/blob/blob_data_builder.h b/chromium/storage/browser/blob/blob_data_builder.h index a4ad251e5ca..4d6838d3e8c 100644 --- a/chromium/storage/browser/blob/blob_data_builder.h +++ b/chromium/storage/browser/blob/blob_data_builder.h @@ -41,6 +41,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobDataBuilder { using ItemCopyEntry = BlobEntry::ItemCopyEntry; explicit BlobDataBuilder(const std::string& uuid); + + BlobDataBuilder(const BlobDataBuilder&) = delete; + BlobDataBuilder& operator=(const BlobDataBuilder&) = delete; + ~BlobDataBuilder(); const std::string& uuid() const { return uuid_; } @@ -58,6 +62,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobDataBuilder { public: FutureData(FutureData&&); FutureData& operator=(FutureData&&); + + FutureData(const FutureData&) = delete; + FutureData& operator=(const FutureData&) = delete; + ~FutureData(); // Populates a part of an item previously allocated with AppendFutureData. @@ -80,7 +88,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobDataBuilder { FutureData(scoped_refptr<BlobDataItem>); scoped_refptr<BlobDataItem> item_; - DISALLOW_COPY_AND_ASSIGN(FutureData); }; // Adds an item that is flagged for future data population. The memory is not @@ -93,6 +100,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobDataBuilder { public: FutureFile(FutureFile&&); FutureFile& operator=(FutureFile&&); + + FutureFile(const FutureFile&) = delete; + FutureFile& operator=(const FutureFile&) = delete; + ~FutureFile(); // Populates a part of an item previously allocated with AppendFutureFile. @@ -106,7 +117,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobDataBuilder { FutureFile(scoped_refptr<BlobDataItem>); scoped_refptr<BlobDataItem> item_; - DISALLOW_COPY_AND_ASSIGN(FutureFile); }; // Adds an item that is flagged for future data population. Use @@ -241,8 +251,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobDataBuilder { std::vector<scoped_refptr<ShareableBlobDataItem>> pending_transport_items_; std::set<std::string> dependent_blob_uuids_; std::vector<ItemCopyEntry> copies_; - - DISALLOW_COPY_AND_ASSIGN(BlobDataBuilder); }; #if defined(UNIT_TEST) diff --git a/chromium/storage/browser/blob/blob_entry.h b/chromium/storage/browser/blob/blob_entry.h index 51e0e289fe1..9e8f72e5773 100644 --- a/chromium/storage/browser/blob/blob_entry.h +++ b/chromium/storage/browser/blob/blob_entry.h @@ -35,6 +35,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobEntry { ItemCopyEntry(scoped_refptr<ShareableBlobDataItem> source_item, size_t source_item_offset, scoped_refptr<ShareableBlobDataItem> dest_item); + + ItemCopyEntry(const ItemCopyEntry&) = delete; + ItemCopyEntry& operator=(const ItemCopyEntry&) = delete; + ~ItemCopyEntry(); ItemCopyEntry(ItemCopyEntry&& other); BlobEntry::ItemCopyEntry& operator=(BlobEntry::ItemCopyEntry&& rhs); @@ -42,9 +46,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobEntry { scoped_refptr<ShareableBlobDataItem> source_item; size_t source_item_offset = 0; scoped_refptr<ShareableBlobDataItem> dest_item; - - private: - DISALLOW_COPY_AND_ASSIGN(ItemCopyEntry); }; // Building state for pending blobs. State can include: @@ -58,6 +59,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobEntry { BuildingState(bool transport_items_present, TransportAllowedCallback transport_allowed_callback, size_t num_building_dependent_blobs); + + BuildingState(const BuildingState&) = delete; + BuildingState& operator=(const BuildingState&) = delete; + ~BuildingState(); // Cancels pending memory or file requests, and calls aborted callback if it @@ -93,13 +98,14 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobEntry { // When our blob is no longer in PENDING_CONSTRUCTION state these callbacks // are called. std::vector<BlobStatusCallback> build_started_callbacks; - - private: - DISALLOW_COPY_AND_ASSIGN(BuildingState); }; BlobEntry(const std::string& content_type, const std::string& content_disposition); + + BlobEntry(const BlobEntry&) = delete; + BlobEntry& operator=(const BlobEntry&) = delete; + ~BlobEntry(); // Appends the given shared blob data item to this object. @@ -170,8 +176,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobEntry { // Only populated if our status is PENDING_*. std::unique_ptr<BuildingState> building_state_; - - DISALLOW_COPY_AND_ASSIGN(BlobEntry); }; } // namespace storage diff --git a/chromium/storage/browser/blob/blob_memory_controller.cc b/chromium/storage/browser/blob/blob_memory_controller.cc index 617dfb4d412..f841876f22b 100644 --- a/chromium/storage/browser/blob/blob_memory_controller.cc +++ b/chromium/storage/browser/blob/blob_memory_controller.cc @@ -30,6 +30,7 @@ #include "base/threading/scoped_blocking_call.h" #include "base/time/time.h" #include "base/trace_event/trace_event.h" +#include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "storage/browser/blob/blob_data_builder.h" #include "storage/browser/blob/blob_data_item.h" @@ -63,7 +64,8 @@ File::Error CreateBlobDirectory(const FilePath& blob_storage_dir) { UMA_HISTOGRAM_ENUMERATION("Storage.Blob.CreateDirectoryResult", -error, -File::FILE_ERROR_MAX); DLOG_IF(ERROR, error != File::FILE_OK) - << "Error creating blob storage directory: " << error; + << "Error creating blob storage directory '" + << blob_storage_dir.LossyDisplayName() << "': " << error; return error; } @@ -334,6 +336,10 @@ class BlobMemoryController::MemoryQuotaAllocationTask done_callback_(std::move(done_callback)), allocation_size_(quota_request_size) {} + MemoryQuotaAllocationTask(const MemoryQuotaAllocationTask&) = delete; + MemoryQuotaAllocationTask& operator=(const MemoryQuotaAllocationTask&) = + delete; + ~MemoryQuotaAllocationTask() override = default; void RunDoneCallback(bool success) { @@ -373,7 +379,6 @@ class BlobMemoryController::MemoryQuotaAllocationTask PendingMemoryQuotaTaskList::iterator my_list_position_; base::WeakPtrFactory<MemoryQuotaAllocationTask> weak_factory_{this}; - DISALLOW_COPY_AND_ASSIGN(MemoryQuotaAllocationTask); }; class BlobMemoryController::FileQuotaAllocationTask @@ -434,6 +439,10 @@ class BlobMemoryController::FileQuotaAllocationTask allocation_size_)); controller_->RecordTracingCounters(); } + + FileQuotaAllocationTask(const FileQuotaAllocationTask&) = delete; + FileQuotaAllocationTask& operator=(const FileQuotaAllocationTask&) = delete; + ~FileQuotaAllocationTask() override = default; void RunDoneCallback(std::vector<FileCreationInfo> file_info, bool success) { @@ -530,7 +539,6 @@ class BlobMemoryController::FileQuotaAllocationTask PendingFileQuotaTaskList::iterator my_list_position_; base::WeakPtrFactory<FileQuotaAllocationTask> weak_factory_{this}; - DISALLOW_COPY_AND_ASSIGN(FileQuotaAllocationTask); }; BlobMemoryController::BlobMemoryController( diff --git a/chromium/storage/browser/blob/blob_memory_controller.h b/chromium/storage/browser/blob/blob_memory_controller.h index 85971d5951d..3e5db532356 100644 --- a/chromium/storage/browser/blob/blob_memory_controller.h +++ b/chromium/storage/browser/blob/blob_memory_controller.h @@ -85,6 +85,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobMemoryController { MemoryAllocation(base::WeakPtr<BlobMemoryController> controller, uint64_t item_id, size_t length); + + MemoryAllocation(const MemoryAllocation&) = delete; + MemoryAllocation& operator=(const MemoryAllocation&) = delete; + ~MemoryAllocation(); size_t length() const { return length_; } @@ -95,8 +99,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobMemoryController { base::WeakPtr<BlobMemoryController> controller_; uint64_t item_id_; size_t length_; - - DISALLOW_COPY_AND_ASSIGN(MemoryAllocation); }; class QuotaAllocationTask { diff --git a/chromium/storage/browser/blob/blob_reader.h b/chromium/storage/browser/blob/blob_reader.h index 017f6f2b028..5145ecfd7be 100644 --- a/chromium/storage/browser/blob/blob_reader.h +++ b/chromium/storage/browser/blob/blob_reader.h @@ -72,6 +72,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobReader { }; enum class Status { NET_ERROR, IO_PENDING, DONE }; using StatusCallback = base::OnceCallback<void(Status)>; + + BlobReader(const BlobReader&) = delete; + BlobReader& operator=(const BlobReader&) = delete; + virtual ~BlobReader(); // This calculates the total size of the blob, and initializes the reading @@ -271,7 +275,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobReader { SEQUENCE_CHECKER(sequence_checker_); base::WeakPtrFactory<BlobReader> weak_factory_{this}; - DISALLOW_COPY_AND_ASSIGN(BlobReader); }; } // namespace storage diff --git a/chromium/storage/browser/blob/blob_reader_unittest.cc b/chromium/storage/browser/blob/blob_reader_unittest.cc index 1e63b33444a..3a6c52eacd7 100644 --- a/chromium/storage/browser/blob/blob_reader_unittest.cc +++ b/chromium/storage/browser/blob/blob_reader_unittest.cc @@ -86,6 +86,9 @@ class FakeFileStreamReader : public FileStreamReader { net_error_(net::OK), size_(size) {} + FakeFileStreamReader(const FakeFileStreamReader&) = delete; + FakeFileStreamReader& operator=(const FakeFileStreamReader&) = delete; + ~FakeFileStreamReader() override = default; void SetReturnError(int net_error) { net_error_ = net_error; } @@ -160,8 +163,6 @@ class FakeFileStreamReader : public FileStreamReader { scoped_refptr<base::SingleThreadTaskRunner> async_task_runner_; int net_error_; uint64_t size_; - - DISALLOW_COPY_AND_ASSIGN(FakeFileStreamReader); }; class MockFileStreamReaderProvider @@ -205,6 +206,10 @@ class MockFileStreamReaderProvider class BlobReaderTest : public ::testing::Test { public: BlobReaderTest() = default; + + BlobReaderTest(const BlobReaderTest&) = delete; + BlobReaderTest& operator=(const BlobReaderTest&) = delete; + ~BlobReaderTest() override = default; void SetUp() override { @@ -287,9 +292,6 @@ class BlobReaderTest : public ::testing::Test { MockFileStreamReaderProvider* provider_ = nullptr; std::unique_ptr<BlobReader> reader_; scoped_refptr<FileSystemContext> file_system_context_; - - private: - DISALLOW_COPY_AND_ASSIGN(BlobReaderTest); }; TEST_F(BlobReaderTest, BasicMemory) { diff --git a/chromium/storage/browser/blob/blob_registry_impl.cc b/chromium/storage/browser/blob/blob_registry_impl.cc index ac131afb5e5..f5e6ef4cf36 100644 --- a/chromium/storage/browser/blob/blob_registry_impl.cc +++ b/chromium/storage/browser/blob/blob_registry_impl.cc @@ -76,6 +76,9 @@ class BlobRegistryImpl::BlobUnderConstruction { // collection in the blob service. void StartTransportation(base::WeakPtr<BlobImpl> blob_impl); + BlobUnderConstruction(const BlobUnderConstruction&) = delete; + BlobUnderConstruction& operator=(const BlobUnderConstruction&) = delete; + ~BlobUnderConstruction() = default; const std::string& uuid() const { return uuid_; } @@ -209,7 +212,6 @@ class BlobRegistryImpl::BlobUnderConstruction { size_t ready_dependent_blob_count_ = 0; base::WeakPtrFactory<BlobUnderConstruction> weak_ptr_factory_{this}; - DISALLOW_COPY_AND_ASSIGN(BlobUnderConstruction); }; void BlobRegistryImpl::BlobUnderConstruction::StartTransportation( @@ -640,13 +642,16 @@ void BlobRegistryImpl::GetBlobFromUUID( void BlobRegistryImpl::URLStoreForOrigin( const url::Origin& origin, mojo::PendingAssociatedReceiver<blink::mojom::BlobURLStore> receiver) { - // TODO(mek): Pass origin on to BlobURLStoreImpl so it can use it to generate - // Blob URLs, and verify at this point that the renderer can create URLs for - // that origin. Delegate* delegate = receivers_.current_context().get(); DCHECK(delegate); + if (!origin.opaque() && !delegate->CanCommitURL(origin.GetURL())) { + mojo::ReportBadMessage( + "Cannot access data for origin passed to " + "BlobRegistryImpl::URLStoreForOrigin"); + return; + } auto self_owned_associated_receiver = mojo::MakeSelfOwnedAssociatedReceiver( - std::make_unique<BlobURLStoreImpl>(url_registry_, delegate), + std::make_unique<BlobURLStoreImpl>(origin, url_registry_), std::move(receiver)); if (g_url_store_creation_hook) g_url_store_creation_hook->Run(self_owned_associated_receiver); diff --git a/chromium/storage/browser/blob/blob_registry_impl.h b/chromium/storage/browser/blob/blob_registry_impl.h index 5f626f033e6..09631b0929e 100644 --- a/chromium/storage/browser/blob/blob_registry_impl.h +++ b/chromium/storage/browser/blob/blob_registry_impl.h @@ -38,6 +38,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobRegistryImpl BlobRegistryImpl(base::WeakPtr<BlobStorageContext> context, base::WeakPtr<BlobUrlRegistry> url_registry, scoped_refptr<FileSystemContext> file_system_context); + + BlobRegistryImpl(const BlobRegistryImpl&) = delete; + BlobRegistryImpl& operator=(const BlobRegistryImpl&) = delete; + ~BlobRegistryImpl() override; void Bind(mojo::PendingReceiver<blink::mojom::BlobRegistry> receiver, @@ -103,7 +107,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobRegistryImpl blobs_being_streamed_; base::WeakPtrFactory<BlobRegistryImpl> weak_ptr_factory_{this}; - DISALLOW_COPY_AND_ASSIGN(BlobRegistryImpl); }; } // namespace storage diff --git a/chromium/storage/browser/blob/blob_storage_context.h b/chromium/storage/browser/blob/blob_storage_context.h index 1f7436ab34d..8e5440d79dc 100644 --- a/chromium/storage/browser/blob/blob_storage_context.h +++ b/chromium/storage/browser/blob/blob_storage_context.h @@ -65,6 +65,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobStorageContext BlobStorageContext(const base::FilePath& profile_directory, const base::FilePath& blob_storage_directory, scoped_refptr<base::TaskRunner> file_runner); + + BlobStorageContext(const BlobStorageContext&) = delete; + BlobStorageContext& operator=(const BlobStorageContext&) = delete; + ~BlobStorageContext() override; // The following three methods all lookup a BlobDataHandle based on some @@ -259,8 +263,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobStorageContext BlobMemoryController memory_controller_; mojo::ReceiverSet<mojom::BlobStorageContext> receivers_; base::WeakPtrFactory<BlobStorageContext> ptr_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(BlobStorageContext); }; } // namespace storage 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 b911200bad4..8afd979d45b 100644 --- a/chromium/storage/browser/blob/blob_storage_context_mojo_unittest.cc +++ b/chromium/storage/browser/blob/blob_storage_context_mojo_unittest.cc @@ -170,7 +170,7 @@ TEST_F(BlobStorageContextMojoTest, SaveBlobToFile) { // Create a 'last modified' that is different from now. base::Time last_modified = - TruncateToSeconds(base::Time::Now() - base::TimeDelta::FromDays(1)); + TruncateToSeconds(base::Time::Now() - base::Days(1)); base::RunLoop loop; base::FilePath file_path = temp_dir_.GetPath().AppendASCII("TestFile.txt"); @@ -193,7 +193,7 @@ TEST_F(BlobStorageContextMojoTest, SaveBlobToFile) { // Because Mac rounds file modification time to the nearest second, make sure // the difference is within that range. base::TimeDelta difference = file_info.last_modified - last_modified; - EXPECT_LT(difference.magnitude(), base::TimeDelta::FromSeconds(1)); + EXPECT_LT(difference.magnitude(), base::Seconds(1)); base::DeleteFile(file_path); ASSERT_TRUE(temp_dir_.Delete()); @@ -238,7 +238,7 @@ TEST_F(BlobStorageContextMojoTest, SaveEmptyBlobToFile) { // Create a 'last modified' that is different from now. base::Time last_modified = - TruncateToSeconds(base::Time::Now() - base::TimeDelta::FromDays(1)); + TruncateToSeconds(base::Time::Now() - base::Days(1)); base::RunLoop loop; base::FilePath file_path = temp_dir_.GetPath().AppendASCII("TestFile.txt"); @@ -261,7 +261,7 @@ TEST_F(BlobStorageContextMojoTest, SaveEmptyBlobToFile) { // Because Mac rounds file modification time to the nearest second, make sure // the difference is within that range. base::TimeDelta difference = file_info.last_modified - last_modified; - EXPECT_LT(difference.magnitude(), base::TimeDelta::FromSeconds(1)); + EXPECT_LT(difference.magnitude(), base::Seconds(1)); base::DeleteFile(file_path); ASSERT_TRUE(temp_dir_.Delete()); @@ -276,7 +276,7 @@ TEST_F(BlobStorageContextMojoTest, FileCopyOptimization) { // Create a file to copy from. base::Time modification_time = - TruncateToSeconds(base::Time::Now() - base::TimeDelta::FromDays(1)); + TruncateToSeconds(base::Time::Now() - base::Days(1)); CreateFile(copy_from_file, kData, modification_time); std::unique_ptr<BlobDataBuilder> builder = @@ -313,7 +313,7 @@ TEST_F(BlobStorageContextMojoTest, FileCopyOptimization) { // Because Mac rounds file modification time to the nearest second, make sure // the difference is within that range. base::TimeDelta difference = file_info.last_modified - modification_time; - EXPECT_LT(difference.magnitude(), base::TimeDelta::FromSeconds(1)); + EXPECT_LT(difference.magnitude(), base::Seconds(1)); base::DeleteFile(file_path); ASSERT_TRUE(temp_dir_.Delete()); @@ -330,7 +330,7 @@ TEST_F(BlobStorageContextMojoTest, FileCopyOptimizationOffsetSize) { // Create a file to copy from. base::Time modification_time = - TruncateToSeconds(base::Time::Now() - base::TimeDelta::FromDays(1)); + TruncateToSeconds(base::Time::Now() - base::Days(1)); CreateFile(copy_from_file, kData, modification_time); std::unique_ptr<BlobDataBuilder> builder = @@ -366,7 +366,7 @@ TEST_F(BlobStorageContextMojoTest, FileCopyOptimizationOffsetSize) { // Because Mac rounds file modification time to the nearest second, make sure // the difference is within that range. base::TimeDelta difference = file_info.last_modified - modification_time; - EXPECT_LT(difference.magnitude(), base::TimeDelta::FromSeconds(1)); + EXPECT_LT(difference.magnitude(), base::Seconds(1)); base::DeleteFile(file_path); ASSERT_TRUE(temp_dir_.Delete()); @@ -381,7 +381,7 @@ TEST_F(BlobStorageContextMojoTest, FileCopyEmptyFile) { // Create a file to copy from. base::Time modification_time = - TruncateToSeconds(base::Time::Now() - base::TimeDelta::FromDays(1)); + TruncateToSeconds(base::Time::Now() - base::Days(1)); CreateFile(copy_from_file, kData, modification_time); std::unique_ptr<BlobDataBuilder> builder = @@ -418,7 +418,7 @@ TEST_F(BlobStorageContextMojoTest, FileCopyEmptyFile) { // Because Mac rounds file modification time to the nearest second, make sure // the difference is within that range. base::TimeDelta difference = file_info.last_modified - modification_time; - EXPECT_LT(difference.magnitude(), base::TimeDelta::FromSeconds(1)); + EXPECT_LT(difference.magnitude(), base::Seconds(1)); base::DeleteFile(file_path); ASSERT_TRUE(temp_dir_.Delete()); @@ -433,7 +433,7 @@ TEST_F(BlobStorageContextMojoTest, InvalidInputFileSize) { // Create a file to copy from. base::Time modification_time = - TruncateToSeconds(base::Time::Now() - base::TimeDelta::FromDays(1)); + TruncateToSeconds(base::Time::Now() - base::Days(1)); CreateFile(copy_from_file, kData, modification_time); std::unique_ptr<BlobDataBuilder> builder = @@ -471,14 +471,14 @@ TEST_F(BlobStorageContextMojoTest, InvalidInputFileTimeModified) { temp_dir_.GetPath().AppendASCII("SourceFile.txt"); base::Time file_modified_time = - TruncateToSeconds(base::Time::Now() - base::TimeDelta::FromDays(1)); + TruncateToSeconds(base::Time::Now() - base::Days(1)); CreateFile(copy_from_file, kData, file_modified_time); // Create the blob but give it the wrong modification time. std::unique_ptr<BlobDataBuilder> builder = std::make_unique<BlobDataBuilder>("1234"); base::Time bad_modified_time = - TruncateToSeconds(base::Time::Now() - base::TimeDelta::FromDays(2)); + TruncateToSeconds(base::Time::Now() - base::Days(2)); builder->AppendFile(copy_from_file, 0ll, kData.size(), bad_modified_time); std::unique_ptr<BlobDataHandle> blob_handle = context_->AddFinishedBlob(std::move(builder)); @@ -580,7 +580,7 @@ TEST_F(BlobStorageContextMojoTest, SaveBlobToFileNoDirectory) { // Create a 'last modified' that is different from now. base::Time last_modified = - TruncateToSeconds(base::Time::Now() - base::TimeDelta::FromDays(1)); + TruncateToSeconds(base::Time::Now() - base::Days(1)); base::RunLoop loop; base::FilePath file_path = temp_dir_.GetPath() diff --git a/chromium/storage/browser/blob/blob_storage_context_unittest.cc b/chromium/storage/browser/blob/blob_storage_context_unittest.cc index 6b9fb19789a..d738694fb1a 100644 --- a/chromium/storage/browser/blob/blob_storage_context_unittest.cc +++ b/chromium/storage/browser/blob/blob_storage_context_unittest.cc @@ -35,6 +35,7 @@ #include "storage/browser/test/fake_blob_data_handle.h" #include "storage/browser/test/test_file_system_context.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/abseil-cpp/absl/types/optional.h" namespace storage { namespace { @@ -79,7 +80,7 @@ class BlobStorageContextTest : public testing::Test { void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - base::ThreadRestrictions::SetIOAllowed(false); + disallow_blocking_.emplace(); context_ = std::make_unique<BlobStorageContext>(); file_system_context_ = CreateFileSystemContextForTesting( /*quota_manager_proxy=*/nullptr, base::FilePath()); @@ -88,7 +89,7 @@ class BlobStorageContextTest : public testing::Test { void TearDown() override { base::RunLoop().RunUntilIdle(); RunFileTasks(); - base::ThreadRestrictions::SetIOAllowed(true); + disallow_blocking_.reset(); ASSERT_TRUE(temp_dir_.Delete()); } @@ -140,6 +141,7 @@ class BlobStorageContextTest : public testing::Test { std::vector<FileCreationInfo> files_; base::ScopedTempDir temp_dir_; + absl::optional<base::ScopedDisallowBlocking> disallow_blocking_; scoped_refptr<TestSimpleTaskRunner> file_runner_ = new TestSimpleTaskRunner(); scoped_refptr<FileSystemContext> file_system_context_; diff --git a/chromium/storage/browser/blob/blob_storage_registry.h b/chromium/storage/browser/blob/blob_storage_registry.h index dd3963e47af..6a7656ad1d1 100644 --- a/chromium/storage/browser/blob/blob_storage_registry.h +++ b/chromium/storage/browser/blob/blob_storage_registry.h @@ -27,6 +27,10 @@ class BlobEntry; class COMPONENT_EXPORT(STORAGE_BROWSER) BlobStorageRegistry { public: BlobStorageRegistry(); + + BlobStorageRegistry(const BlobStorageRegistry&) = delete; + BlobStorageRegistry& operator=(const BlobStorageRegistry&) = delete; + ~BlobStorageRegistry(); // Creates the blob entry with a refcount of 1 and a state of PENDING. If @@ -52,8 +56,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobStorageRegistry { friend class ViewBlobInternalsJob; std::unordered_map<std::string, std::unique_ptr<BlobEntry>> blob_map_; - - DISALLOW_COPY_AND_ASSIGN(BlobStorageRegistry); }; } // namespace storage diff --git a/chromium/storage/browser/blob/blob_url_loader.h b/chromium/storage/browser/blob/blob_url_loader.h index 325d2968556..0fed3de09ec 100644 --- a/chromium/storage/browser/blob/blob_url_loader.h +++ b/chromium/storage/browser/blob/blob_url_loader.h @@ -43,6 +43,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobURLLoader const net::HttpRequestHeaders& headers, mojo::PendingRemote<network::mojom::URLLoaderClient> client, std::unique_ptr<BlobDataHandle> blob_handle); + + BlobURLLoader(const BlobURLLoader&) = delete; + BlobURLLoader& operator=(const BlobURLLoader&) = delete; + ~BlobURLLoader() override; private: @@ -95,8 +99,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobURLLoader mojo::ScopedDataPipeConsumerHandle response_body_consumer_handle_; base::WeakPtrFactory<BlobURLLoader> weak_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(BlobURLLoader); }; } // namespace storage diff --git a/chromium/storage/browser/blob/blob_url_registry.h b/chromium/storage/browser/blob/blob_url_registry.h index 104cf9c050a..b30100bfa37 100644 --- a/chromium/storage/browser/blob/blob_url_registry.h +++ b/chromium/storage/browser/blob/blob_url_registry.h @@ -24,6 +24,10 @@ namespace storage { class COMPONENT_EXPORT(STORAGE_BROWSER) BlobUrlRegistry { public: explicit BlobUrlRegistry(base::WeakPtr<BlobUrlRegistry> fallback = nullptr); + + BlobUrlRegistry(const BlobUrlRegistry&) = delete; + BlobUrlRegistry& operator=(const BlobUrlRegistry&) = delete; + ~BlobUrlRegistry(); // Creates a url mapping from blob to the given url. Returns false if @@ -79,7 +83,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobUrlRegistry { token_to_url_and_blob_; base::WeakPtrFactory<BlobUrlRegistry> weak_ptr_factory_{this}; - DISALLOW_COPY_AND_ASSIGN(BlobUrlRegistry); }; } // namespace storage diff --git a/chromium/storage/browser/blob/blob_url_store_impl.cc b/chromium/storage/browser/blob/blob_url_store_impl.cc index 09a93bcf4e1..de637458878 100644 --- a/chromium/storage/browser/blob/blob_url_store_impl.cc +++ b/chromium/storage/browser/blob/blob_url_store_impl.cc @@ -5,6 +5,7 @@ #include "storage/browser/blob/blob_url_store_impl.h" #include "base/bind.h" +#include "base/strings/strcat.h" #include "mojo/public/cpp/bindings/receiver_set.h" #include "storage/browser/blob/blob_impl.h" #include "storage/browser/blob/blob_url_loader_factory.h" @@ -58,9 +59,9 @@ class BlobURLTokenImpl : public blink::mojom::BlobURLToken { const base::UnguessableToken token_; }; -BlobURLStoreImpl::BlobURLStoreImpl(base::WeakPtr<BlobUrlRegistry> registry, - BlobRegistryImpl::Delegate* delegate) - : registry_(std::move(registry)), delegate_(delegate) {} +BlobURLStoreImpl::BlobURLStoreImpl(const url::Origin& origin, + base::WeakPtr<BlobUrlRegistry> registry) + : origin_(origin), registry_(std::move(registry)) {} BlobURLStoreImpl::~BlobURLStoreImpl() { if (registry_) { @@ -75,20 +76,9 @@ void BlobURLStoreImpl::Register( // TODO(https://crbug.com/1224926): Remove this once experiment is over. const base::UnguessableToken& unsafe_agent_cluster_id, RegisterCallback callback) { - if (!url.SchemeIsBlob()) { - mojo::ReportBadMessage("Invalid scheme passed to BlobURLStore::Register"); - std::move(callback).Run(); - return; - } - if (!delegate_->CanCommitURL(url)) { - mojo::ReportBadMessage( - "Non committable URL passed to BlobURLStore::Register"); - std::move(callback).Run(); - return; - } - if (BlobUrlUtils::UrlHasFragment(url)) { - mojo::ReportBadMessage( - "URL with fragment passed to BlobURLStore::Register"); + // TODO(mek): Generate blob URLs here, rather than validating the URLs the + // renderer process generated. + if (!BlobUrlIsValid(url, "Register")) { std::move(callback).Run(); return; } @@ -100,19 +90,8 @@ void BlobURLStoreImpl::Register( } void BlobURLStoreImpl::Revoke(const GURL& url) { - if (!url.SchemeIsBlob()) { - mojo::ReportBadMessage("Invalid scheme passed to BlobURLStore::Revoke"); - return; - } - if (!delegate_->CanCommitURL(url)) { - mojo::ReportBadMessage( - "Non committable URL passed to BlobURLStore::Revoke"); + if (!BlobUrlIsValid(url, "Revoke")) return; - } - if (BlobUrlUtils::UrlHasFragment(url)) { - mojo::ReportBadMessage("URL with fragment passed to BlobURLStore::Revoke"); - return; - } if (registry_) registry_->RemoveUrlMapping(url); @@ -156,4 +135,38 @@ void BlobURLStoreImpl::ResolveForNavigation( std::move(callback).Run(registry_->GetUnsafeAgentClusterID(url)); } +bool BlobURLStoreImpl::BlobUrlIsValid(const GURL& url, + const char* method) const { + if (!url.SchemeIsBlob()) { + mojo::ReportBadMessage( + base::StrCat({"Invalid scheme passed to BlobURLStore::", method})); + return false; + } + url::Origin url_origin = url::Origin::Create(url); + // For file:// origins blink sometimes creates blob URLs with "null" as origin + // and other times "file://" (based on a runtime setting). On the other hand, + // `origin_` will always be a non-opaque file: origin for pages loaded from + // file:// URLs. To deal with this, we treat file:// origins and + // opaque origins separately from non-opaque origins. + bool valid_origin = true; + if (url_origin.scheme() == url::kFileScheme) { + valid_origin = origin_.scheme() == url::kFileScheme; + } else if (url_origin.opaque()) { + valid_origin = origin_.opaque() || origin_.scheme() == url::kFileScheme; + } else { + valid_origin = origin_ == url_origin; + } + if (!valid_origin) { + mojo::ReportBadMessage(base::StrCat( + {"URL with invalid origin passed to BlobURLStore::", method})); + return false; + } + if (BlobUrlUtils::UrlHasFragment(url)) { + mojo::ReportBadMessage( + base::StrCat({"URL with fragment passed to BlobURLStore::", method})); + return false; + } + return true; +} + } // namespace storage diff --git a/chromium/storage/browser/blob/blob_url_store_impl.h b/chromium/storage/browser/blob/blob_url_store_impl.h index 9c6d3bfdc6a..3db3a95d427 100644 --- a/chromium/storage/browser/blob/blob_url_store_impl.h +++ b/chromium/storage/browser/blob/blob_url_store_impl.h @@ -12,8 +12,9 @@ #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" -#include "storage/browser/blob/blob_registry_impl.h" +#include "storage/browser/blob/blob_url_registry.h" #include "third_party/blink/public/mojom/blob/blob_url_store.mojom.h" +#include "url/origin.h" namespace storage { @@ -22,8 +23,12 @@ class BlobUrlRegistry; class COMPONENT_EXPORT(STORAGE_BROWSER) BlobURLStoreImpl : public blink::mojom::BlobURLStore { public: - BlobURLStoreImpl(base::WeakPtr<BlobUrlRegistry> registry, - BlobRegistryImpl::Delegate* delegate); + BlobURLStoreImpl(const url::Origin& origin, + base::WeakPtr<BlobUrlRegistry> registry); + + BlobURLStoreImpl(const BlobURLStoreImpl&) = delete; + BlobURLStoreImpl& operator=(const BlobURLStoreImpl&) = delete; + ~BlobURLStoreImpl() override; void Register( @@ -44,13 +49,16 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobURLStoreImpl ResolveForNavigationCallback callback) override; private: + // Checks if the passed in url is a valid blob url for this blob url store. + // Returns false and reports a bad mojo message if not. + bool BlobUrlIsValid(const GURL& url, const char* method) const; + + const url::Origin origin_; base::WeakPtr<BlobUrlRegistry> registry_; - BlobRegistryImpl::Delegate* delegate_; std::set<GURL> urls_; base::WeakPtrFactory<BlobURLStoreImpl> weak_ptr_factory_{this}; - DISALLOW_COPY_AND_ASSIGN(BlobURLStoreImpl); }; } // namespace storage diff --git a/chromium/storage/browser/blob/blob_url_store_impl_unittest.cc b/chromium/storage/browser/blob/blob_url_store_impl_unittest.cc index daf2ea331ac..04c44794d55 100644 --- a/chromium/storage/browser/blob/blob_url_store_impl_unittest.cc +++ b/chromium/storage/browser/blob/blob_url_store_impl_unittest.cc @@ -19,7 +19,6 @@ #include "storage/browser/blob/blob_impl.h" #include "storage/browser/blob/blob_storage_context.h" #include "storage/browser/blob/blob_url_registry.h" -#include "storage/browser/test/mock_blob_registry_delegate.h" #include "testing/gtest/include/gtest/gtest.h" using blink::mojom::BlobURLStore; @@ -72,9 +71,9 @@ class BlobURLStoreImplTest : public testing::Test { mojo::PendingRemote<BlobURLStore> CreateURLStore() { mojo::PendingRemote<BlobURLStore> result; - mojo::MakeSelfOwnedReceiver(std::make_unique<BlobURLStoreImpl>( - url_registry_.AsWeakPtr(), &delegate_), - result.InitWithNewPipeAndPassReceiver()); + mojo::MakeSelfOwnedReceiver( + std::make_unique<BlobURLStoreImpl>(kOrigin, url_registry_.AsWeakPtr()), + result.InitWithNewPipeAndPassReceiver()); return result; } @@ -110,15 +109,19 @@ class BlobURLStoreImplTest : public testing::Test { } const std::string kId = "id"; - const GURL kValidUrl = GURL("blob:id"); + const url::Origin kOrigin = url::Origin::Create(GURL("https://example.com")); + const GURL kValidUrl = GURL("blob:" + kOrigin.Serialize() + "/id1"); + const GURL kValidUrl2 = GURL("blob:" + kOrigin.Serialize() + "/id2"); const GURL kInvalidUrl = GURL("bolb:id"); - const GURL kFragmentUrl = GURL("blob:id#fragment"); + const GURL kFragmentUrl = GURL(kValidUrl.spec() + "#fragment"); + const url::Origin kWrongOrigin = + url::Origin::Create(GURL("https://test.com")); + const GURL kWrongOriginUrl = GURL("blob:" + kWrongOrigin.Serialize() + "/id"); protected: base::test::TaskEnvironment task_environment_; std::unique_ptr<BlobStorageContext> context_; BlobUrlRegistry url_registry_; - MockBlobRegistryDelegate delegate_; std::vector<std::string> bad_messages_; base::UnguessableToken agent_cluster_id_; }; @@ -128,7 +131,7 @@ TEST_F(BlobURLStoreImplTest, BasicRegisterRevoke) { CreateBlobFromString(kId, "hello world"); // Register a URL and make sure the URL keeps the blob alive. - BlobURLStoreImpl url_store(url_registry_.AsWeakPtr(), &delegate_); + BlobURLStoreImpl url_store(kOrigin, url_registry_.AsWeakPtr()); RegisterURL(&url_store, std::move(blob), kValidUrl); blob = url_registry_.GetBlobFromUrl(kValidUrl); @@ -156,15 +159,13 @@ TEST_F(BlobURLStoreImplTest, RegisterInvalidScheme) { EXPECT_EQ(1u, bad_messages_.size()); } -TEST_F(BlobURLStoreImplTest, RegisterCantCommit) { +TEST_F(BlobURLStoreImplTest, RegisterWrongOrigin) { mojo::PendingRemote<blink::mojom::Blob> blob = CreateBlobFromString(kId, "hello world"); - delegate_.can_commit_url_result = false; - mojo::Remote<BlobURLStore> url_store(CreateURLStore()); - RegisterURL(url_store.get(), std::move(blob), kValidUrl); - EXPECT_FALSE(url_registry_.GetBlobFromUrl(kValidUrl)); + RegisterURL(url_store.get(), std::move(blob), kWrongOriginUrl); + EXPECT_FALSE(url_registry_.GetBlobFromUrl(kWrongOriginUrl)); EXPECT_EQ(1u, bad_messages_.size()); } @@ -179,14 +180,13 @@ TEST_F(BlobURLStoreImplTest, RegisterUrlFragment) { } TEST_F(BlobURLStoreImplTest, ImplicitRevoke) { - const GURL kValidUrl2("blob:id2"); mojo::Remote<blink::mojom::Blob> blob( CreateBlobFromString(kId, "hello world")); mojo::PendingRemote<blink::mojom::Blob> blob2; blob->Clone(blob2.InitWithNewPipeAndPassReceiver()); auto url_store = - std::make_unique<BlobURLStoreImpl>(url_registry_.AsWeakPtr(), &delegate_); + std::make_unique<BlobURLStoreImpl>(kOrigin, url_registry_.AsWeakPtr()); RegisterURL(url_store.get(), blob.Unbind(), kValidUrl); EXPECT_TRUE(url_registry_.GetBlobFromUrl(kValidUrl)); RegisterURL(url_store.get(), std::move(blob2), kValidUrl2); @@ -202,8 +202,8 @@ TEST_F(BlobURLStoreImplTest, RevokeThroughDifferentURLStore) { mojo::PendingRemote<blink::mojom::Blob> blob = CreateBlobFromString(kId, "hello world"); - BlobURLStoreImpl url_store1(url_registry_.AsWeakPtr(), &delegate_); - BlobURLStoreImpl url_store2(url_registry_.AsWeakPtr(), &delegate_); + BlobURLStoreImpl url_store1(kOrigin, url_registry_.AsWeakPtr()); + BlobURLStoreImpl url_store2(kOrigin, url_registry_.AsWeakPtr()); RegisterURL(&url_store1, std::move(blob), kValidUrl); EXPECT_TRUE(url_registry_.GetBlobFromUrl(kValidUrl)); @@ -219,11 +219,9 @@ TEST_F(BlobURLStoreImplTest, RevokeInvalidScheme) { EXPECT_EQ(1u, bad_messages_.size()); } -TEST_F(BlobURLStoreImplTest, RevokeCantCommit) { - delegate_.can_commit_url_result = false; - +TEST_F(BlobURLStoreImplTest, RevokeWrongOrigin) { mojo::Remote<BlobURLStore> url_store(CreateURLStore()); - url_store->Revoke(kValidUrl); + url_store->Revoke(kWrongOriginUrl); url_store.FlushForTesting(); EXPECT_EQ(1u, bad_messages_.size()); } @@ -239,7 +237,7 @@ TEST_F(BlobURLStoreImplTest, Resolve) { mojo::PendingRemote<blink::mojom::Blob> blob = CreateBlobFromString(kId, "hello world"); - BlobURLStoreImpl url_store(url_registry_.AsWeakPtr(), &delegate_); + BlobURLStoreImpl url_store(kOrigin, url_registry_.AsWeakPtr()); RegisterURL(&url_store, std::move(blob), kValidUrl); blob = ResolveURL(&url_store, kValidUrl); @@ -254,7 +252,7 @@ TEST_F(BlobURLStoreImplTest, Resolve) { } TEST_F(BlobURLStoreImplTest, ResolveNonExistentURL) { - BlobURLStoreImpl url_store(url_registry_.AsWeakPtr(), &delegate_); + BlobURLStoreImpl url_store(kOrigin, url_registry_.AsWeakPtr()); mojo::PendingRemote<blink::mojom::Blob> blob = ResolveURL(&url_store, kValidUrl); @@ -264,7 +262,7 @@ TEST_F(BlobURLStoreImplTest, ResolveNonExistentURL) { } TEST_F(BlobURLStoreImplTest, ResolveInvalidURL) { - BlobURLStoreImpl url_store(url_registry_.AsWeakPtr(), &delegate_); + BlobURLStoreImpl url_store(kOrigin, url_registry_.AsWeakPtr()); mojo::PendingRemote<blink::mojom::Blob> blob = ResolveURL(&url_store, kInvalidUrl); @@ -275,7 +273,7 @@ TEST_F(BlobURLStoreImplTest, ResolveAsURLLoaderFactory) { mojo::PendingRemote<blink::mojom::Blob> blob = CreateBlobFromString(kId, "hello world"); - BlobURLStoreImpl url_store(url_registry_.AsWeakPtr(), &delegate_); + BlobURLStoreImpl url_store(kOrigin, url_registry_.AsWeakPtr()); RegisterURL(&url_store, std::move(blob), kValidUrl); mojo::Remote<network::mojom::URLLoaderFactory> factory; @@ -312,7 +310,7 @@ TEST_F(BlobURLStoreImplTest, ResolveForNavigation) { mojo::PendingRemote<blink::mojom::Blob> blob = CreateBlobFromString(kId, "hello world"); - BlobURLStoreImpl url_store(url_registry_.AsWeakPtr(), &delegate_); + BlobURLStoreImpl url_store(kOrigin, url_registry_.AsWeakPtr()); RegisterURL(&url_store, std::move(blob), kValidUrl); base::RunLoop loop0; diff --git a/chromium/storage/browser/blob/scoped_file.h b/chromium/storage/browser/blob/scoped_file.h index 73f06ec1059..35c0adbdbb4 100644 --- a/chromium/storage/browser/blob/scoped_file.h +++ b/chromium/storage/browser/blob/scoped_file.h @@ -47,6 +47,9 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) ScopedFile { return *this; } + ScopedFile(const ScopedFile&) = delete; + ScopedFile& operator=(const ScopedFile&) = delete; + ~ScopedFile(); // The |callback| is fired on |callback_runner| when the final reference @@ -80,8 +83,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) ScopedFile { scoped_refptr<base::TaskRunner> file_task_runner_; std::vector<std::pair<ScopeOutCallback, scoped_refptr<base::TaskRunner>>> scope_out_callbacks_; - - DISALLOW_COPY_AND_ASSIGN(ScopedFile); }; } // namespace storage diff --git a/chromium/storage/browser/blob/shareable_file_reference.cc b/chromium/storage/browser/blob/shareable_file_reference.cc index c126698482d..9179c241c87 100644 --- a/chromium/storage/browser/blob/shareable_file_reference.cc +++ b/chromium/storage/browser/blob/shareable_file_reference.cc @@ -27,6 +27,9 @@ class ShareableFileMap { ShareableFileMap() = default; + ShareableFileMap(const ShareableFileMap&) = delete; + ShareableFileMap& operator=(const ShareableFileMap&) = delete; + ~ShareableFileMap() = default; iterator Find(key_type key) { @@ -59,8 +62,6 @@ class ShareableFileMap { FileMap file_map_; SEQUENCE_CHECKER(sequence_checker_); - - DISALLOW_COPY_AND_ASSIGN(ShareableFileMap); }; base::LazyInstance<ShareableFileMap>::DestructorAtExit g_file_map = diff --git a/chromium/storage/browser/database/database_tracker_unittest.cc b/chromium/storage/browser/database/database_tracker_unittest.cc index f269067c02b..86c10742c59 100644 --- a/chromium/storage/browser/database/database_tracker_unittest.cc +++ b/chromium/storage/browser/database/database_tracker_unittest.cc @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "storage/browser/database/database_tracker.h" + #include <stddef.h> #include <stdint.h> @@ -12,6 +14,7 @@ #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" +#include "base/gtest_prod_util.h" #include "base/memory/ptr_util.h" #include "base/memory/scoped_refptr.h" #include "base/run_loop.h" @@ -22,7 +25,6 @@ #include "base/time/time.h" #include "net/base/net_errors.h" #include "net/base/test_completion_callback.h" -#include "storage/browser/database/database_tracker.h" #include "storage/browser/quota/quota_client_type.h" #include "storage/browser/quota/quota_manager_proxy.h" #include "storage/browser/test/mock_special_storage_policy.h" @@ -263,14 +265,14 @@ class DatabaseTracker_TestHelper_Test { tracker->GetFullDBFilePath(kOrigin1, kDB1), now, now)); EXPECT_TRUE(base::TouchFile( tracker->GetFullDBFilePath(kOrigin2, kDB2), now, now)); - base::Time three_days_ago = now - base::TimeDelta::FromDays(3); + base::Time three_days_ago = now - base::Days(3); EXPECT_TRUE( base::TouchFile(tracker->GetFullDBFilePath(kOrigin2, kDB3), three_days_ago, three_days_ago)); // Delete databases modified since yesterday. db2 is whitelisted. base::Time yesterday = base::Time::Now(); - yesterday -= base::TimeDelta::FromDays(1); + yesterday -= base::Days(1); net::TestCompletionCallback delete_data_modified_since_callback; tracker->DeleteDataModifiedSince( diff --git a/chromium/storage/browser/database/vfs_backend.cc b/chromium/storage/browser/database/vfs_backend.cc index 598064ec64b..98bb007fdc9 100644 --- a/chromium/storage/browser/database/vfs_backend.cc +++ b/chromium/storage/browser/database/vfs_backend.cc @@ -81,11 +81,13 @@ base::File VfsBackend::OpenFile(const base::FilePath& file_path, if (!(desired_flags & SQLITE_OPEN_MAIN_DB)) flags |= base::File::FLAG_EXCLUSIVE_READ | base::File::FLAG_EXCLUSIVE_WRITE; - flags |= ((desired_flags & SQLITE_OPEN_CREATE) ? - base::File::FLAG_OPEN_ALWAYS : base::File::FLAG_OPEN); - - if (desired_flags & SQLITE_OPEN_EXCLUSIVE) - flags |= base::File::FLAG_EXCLUSIVE_READ | base::File::FLAG_EXCLUSIVE_WRITE; + if (desired_flags & SQLITE_OPEN_CREATE) { + flags |= (desired_flags & SQLITE_OPEN_EXCLUSIVE) + ? base::File::FLAG_CREATE + : base::File::FLAG_OPEN_ALWAYS; + } else { + flags |= base::File::FLAG_OPEN; + } if (desired_flags & SQLITE_OPEN_DELETEONCLOSE) { flags |= base::File::FLAG_TEMPORARY | base::File::FLAG_HIDDEN | diff --git a/chromium/storage/browser/file_system/OWNERS b/chromium/storage/browser/file_system/OWNERS index 3fbd89ad98c..740e8c58fe4 100644 --- a/chromium/storage/browser/file_system/OWNERS +++ b/chromium/storage/browser/file_system/OWNERS @@ -1,2 +1,6 @@ +# Primary +asully@chromium.org + +# Secondary mek@chromium.org nhiroki@chromium.org diff --git a/chromium/storage/browser/file_system/async_file_util_adapter.h b/chromium/storage/browser/file_system/async_file_util_adapter.h index 441533a04e4..c04e9b23b26 100644 --- a/chromium/storage/browser/file_system/async_file_util_adapter.h +++ b/chromium/storage/browser/file_system/async_file_util_adapter.h @@ -34,6 +34,9 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) AsyncFileUtilAdapter explicit AsyncFileUtilAdapter( std::unique_ptr<FileSystemFileUtil> sync_file_util); + AsyncFileUtilAdapter(const AsyncFileUtilAdapter&) = delete; + AsyncFileUtilAdapter& operator=(const AsyncFileUtilAdapter&) = delete; + ~AsyncFileUtilAdapter() override; FileSystemFileUtil* sync_file_util() { return sync_file_util_.get(); } @@ -97,8 +100,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) AsyncFileUtilAdapter private: std::unique_ptr<FileSystemFileUtil> sync_file_util_; - - DISALLOW_COPY_AND_ASSIGN(AsyncFileUtilAdapter); }; } // namespace storage diff --git a/chromium/storage/browser/file_system/copy_or_move_file_validator_unittest.cc b/chromium/storage/browser/file_system/copy_or_move_file_validator_unittest.cc index 011d6367c72..6442b318ecd 100644 --- a/chromium/storage/browser/file_system/copy_or_move_file_validator_unittest.cc +++ b/chromium/storage/browser/file_system/copy_or_move_file_validator_unittest.cc @@ -58,6 +58,11 @@ class CopyOrMoveFileValidatorTestHelper { src_type_(src_type), dest_type_(dest_type) {} + CopyOrMoveFileValidatorTestHelper(const CopyOrMoveFileValidatorTestHelper&) = + delete; + CopyOrMoveFileValidatorTestHelper& operator=( + const CopyOrMoveFileValidatorTestHelper&) = delete; + ~CopyOrMoveFileValidatorTestHelper() { file_system_context_ = nullptr; base::RunLoop().RunUntilIdle(); @@ -189,8 +194,6 @@ class CopyOrMoveFileValidatorTestHelper { FileSystemURL copy_dest_; FileSystemURL move_src_; FileSystemURL move_dest_; - - DISALLOW_COPY_AND_ASSIGN(CopyOrMoveFileValidatorTestHelper); }; // For TestCopyOrMoveFileValidatorFactory @@ -203,6 +206,12 @@ class TestCopyOrMoveFileValidatorFactory // TODO(gbillock): switch args to enum or something explicit TestCopyOrMoveFileValidatorFactory(Validity validity) : validity_(validity) {} + + TestCopyOrMoveFileValidatorFactory( + const TestCopyOrMoveFileValidatorFactory&) = delete; + TestCopyOrMoveFileValidatorFactory& operator=( + const TestCopyOrMoveFileValidatorFactory&) = delete; + ~TestCopyOrMoveFileValidatorFactory() override = default; CopyOrMoveFileValidator* CreateCopyOrMoveFileValidator( @@ -221,6 +230,11 @@ class TestCopyOrMoveFileValidatorFactory write_result_(validity == VALID || validity == PRE_WRITE_INVALID ? base::File::FILE_OK : base::File::FILE_ERROR_SECURITY) {} + + TestCopyOrMoveFileValidator(const TestCopyOrMoveFileValidator&) = delete; + TestCopyOrMoveFileValidator& operator=(const TestCopyOrMoveFileValidator&) = + delete; + ~TestCopyOrMoveFileValidator() override = default; void StartPreWriteValidation(ResultCallback result_callback) override { @@ -239,13 +253,9 @@ class TestCopyOrMoveFileValidatorFactory private: base::File::Error result_; base::File::Error write_result_; - - DISALLOW_COPY_AND_ASSIGN(TestCopyOrMoveFileValidator); }; Validity validity_; - - DISALLOW_COPY_AND_ASSIGN(TestCopyOrMoveFileValidatorFactory); }; } // namespace 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 db41f174a58..d77fcad8211 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 @@ -32,6 +32,9 @@ const int64_t kFlushIntervalInBytes = 10 << 20; // 10MB. class CopyOrMoveOperationDelegate::CopyOrMoveImpl { public: + CopyOrMoveImpl(const CopyOrMoveImpl&) = delete; + CopyOrMoveImpl& operator=(const CopyOrMoveImpl&) = delete; + virtual ~CopyOrMoveImpl() = default; virtual void Run(CopyOrMoveOperationDelegate::StatusCallback callback) = 0; virtual void Cancel() = 0; @@ -129,7 +132,6 @@ class CopyOrMoveOperationDelegate::CopyOrMoveImpl { private: const FileSystemOperation::CopyOrMoveProgressCallback progress_callback_; - DISALLOW_COPY_AND_ASSIGN(CopyOrMoveImpl); }; namespace { @@ -587,7 +589,7 @@ class StreamCopyOrMoveImpl dest_url_.mount_option().flush_policy(), kReadBufferSize, base::BindRepeating(&StreamCopyOrMoveImpl::OnCopyOrMoveFileProgress, weak_factory_.GetWeakPtr()), - base::TimeDelta::FromMilliseconds( + base::Milliseconds( kMinProgressCallbackInvocationSpanInMilliseconds)); copy_helper_->Run(base::BindOnce(&StreamCopyOrMoveImpl::RunAfterStreamCopy, weak_factory_.GetWeakPtr(), 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 3b630d7f099..e2501b032c7 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 @@ -49,6 +49,10 @@ class CopyOrMoveOperationDelegate : public RecursiveOperationDelegate { int buffer_size, FileSystemOperation::CopyFileProgressCallback file_progress_callback, const base::TimeDelta& min_progress_callback_invocation_span); + + StreamCopyHelper(const StreamCopyHelper&) = delete; + StreamCopyHelper& operator=(const StreamCopyHelper&) = delete; + ~StreamCopyHelper(); void Run(StatusCallback callback); @@ -82,7 +86,6 @@ class CopyOrMoveOperationDelegate : public RecursiveOperationDelegate { base::TimeDelta min_progress_callback_invocation_span_; bool cancel_requested_; base::WeakPtrFactory<StreamCopyHelper> weak_factory_{this}; - DISALLOW_COPY_AND_ASSIGN(StreamCopyHelper); }; CopyOrMoveOperationDelegate( 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 b666bcd8dbd..0bfe16eeaa7 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 @@ -83,6 +83,10 @@ class TestValidatorFactory : public CopyOrMoveFileValidatorFactory { write_result_(post_copy_valid ? base::File::FILE_OK : base::File::FILE_ERROR_SECURITY), reject_string_(reject_string) {} + + TestValidator(const TestValidator&) = delete; + TestValidator& operator=(const TestValidator&) = delete; + ~TestValidator() override = default; void StartPreWriteValidation(ResultCallback result_callback) override { @@ -107,8 +111,6 @@ class TestValidatorFactory : public CopyOrMoveFileValidatorFactory { base::File::Error result_; base::File::Error write_result_; std::string reject_string_; - - DISALLOW_COPY_AND_ASSIGN(TestValidator); }; }; @@ -149,6 +151,9 @@ class ScopedThreadStopper { public: explicit ScopedThreadStopper(base::Thread* thread) : thread_(thread) {} + ScopedThreadStopper(const ScopedThreadStopper&) = delete; + ScopedThreadStopper& operator=(const ScopedThreadStopper&) = delete; + ~ScopedThreadStopper() { if (thread_) { // Give another chance for deleted streams to perform Close. @@ -164,7 +169,6 @@ class ScopedThreadStopper { private: base::Thread* thread_; - DISALLOW_COPY_AND_ASSIGN(ScopedThreadStopper); }; } // namespace @@ -179,6 +183,10 @@ class CopyOrMoveOperationTestHelper { dest_type_(dest_type), task_environment_(base::test::TaskEnvironment::MainThreadType::IO) {} + CopyOrMoveOperationTestHelper(const CopyOrMoveOperationTestHelper&) = delete; + CopyOrMoveOperationTestHelper& operator=( + const CopyOrMoveOperationTestHelper&) = delete; + ~CopyOrMoveOperationTestHelper() { file_system_context_ = nullptr; quota_manager_ = nullptr; @@ -397,8 +405,6 @@ class CopyOrMoveOperationTestHelper { scoped_refptr<FileSystemContext> file_system_context_; scoped_refptr<MockQuotaManagerProxy> quota_manager_proxy_; scoped_refptr<MockQuotaManager> quota_manager_; - - DISALLOW_COPY_AND_ASSIGN(CopyOrMoveOperationTestHelper); }; TEST(LocalFileSystemCopyOrMoveOperationTest, CopySingleFile) { diff --git a/chromium/storage/browser/file_system/dragged_file_util.h b/chromium/storage/browser/file_system/dragged_file_util.h index 0590b902e7b..9440c077a9b 100644 --- a/chromium/storage/browser/file_system/dragged_file_util.h +++ b/chromium/storage/browser/file_system/dragged_file_util.h @@ -21,6 +21,10 @@ class FileSystemOperationContext; class COMPONENT_EXPORT(STORAGE_BROWSER) DraggedFileUtil : public LocalFileUtil { public: DraggedFileUtil(); + + DraggedFileUtil(const DraggedFileUtil&) = delete; + DraggedFileUtil& operator=(const DraggedFileUtil&) = delete; + ~DraggedFileUtil() override {} // FileSystemFileUtil overrides. @@ -32,9 +36,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) DraggedFileUtil : public LocalFileUtil { FileSystemOperationContext* context, const FileSystemURL& root_url, bool recursive) override; - - private: - DISALLOW_COPY_AND_ASSIGN(DraggedFileUtil); }; } // namespace storage diff --git a/chromium/storage/browser/file_system/dragged_file_util_unittest.cc b/chromium/storage/browser/file_system/dragged_file_util_unittest.cc index 0fcdc2ed7b0..0db456a531d 100644 --- a/chromium/storage/browser/file_system/dragged_file_util_unittest.cc +++ b/chromium/storage/browser/file_system/dragged_file_util_unittest.cc @@ -388,8 +388,7 @@ TEST_F(DraggedFileUtilTest, ReadDirectoryTest) { file_system_context(), url, &entries)); EXPECT_EQ(expected_entry_map.size(), entries.size()); - for (size_t i = 0; i < entries.size(); ++i) { - const filesystem::mojom::DirectoryEntry& entry = entries[i]; + for (const auto& entry : entries) { auto found = expected_entry_map.find(entry.name.value()); EXPECT_TRUE(found != expected_entry_map.end()); EXPECT_EQ(found->second.name, entry.name); diff --git a/chromium/storage/browser/file_system/external_mount_points.cc b/chromium/storage/browser/file_system/external_mount_points.cc index ade12800564..2426477fb66 100644 --- a/chromium/storage/browser/file_system/external_mount_points.cc +++ b/chromium/storage/browser/file_system/external_mount_points.cc @@ -14,6 +14,8 @@ #include "storage/browser/file_system/file_system_url.h" #include "third_party/blink/public/common/storage_key/storage_key.h" +class GURL; + namespace storage { namespace { @@ -69,6 +71,10 @@ class ExternalMountPoints::Instance { : type_(type), path_(path.StripTrailingSeparators()), mount_option_(mount_option) {} + + Instance(const Instance&) = delete; + Instance& operator=(const Instance&) = delete; + ~Instance() = default; FileSystemType type() const { return type_; } @@ -79,8 +85,6 @@ class ExternalMountPoints::Instance { const FileSystemType type_; const base::FilePath path_; const FileSystemMountOption mount_option_; - - DISALLOW_COPY_AND_ASSIGN(Instance); }; //-------------------------------------------------------------------------- @@ -187,23 +191,19 @@ bool ExternalMountPoints::CrackVirtualPath( return true; } -// TODO(https://crbug.com/1221308): conversion of the URL to origin is -// temporary; function will have StorageKey parameter in future CL -FileSystemURL ExternalMountPoints::CrackURL(const GURL& url) const { - FileSystemURL filesystem_url = - FileSystemURL(url, blink::StorageKey(url::Origin::Create(url))); +FileSystemURL ExternalMountPoints::CrackURL( + const GURL& url, + const blink::StorageKey& storage_key) const { + FileSystemURL filesystem_url = FileSystemURL(url, storage_key); if (!filesystem_url.is_valid()) return FileSystemURL(); return CrackFileSystemURL(filesystem_url); } FileSystemURL ExternalMountPoints::CreateCrackedFileSystemURL( - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type, const base::FilePath& virtual_path) const { - // TODO(https://crbug.com/1221308): function will have StorageKey param in - // future CL; conversion from url::Origin is temporary - const blink::StorageKey storage_key = blink::StorageKey(origin); return CrackFileSystemURL(FileSystemURL(storage_key, type, virtual_path)); } @@ -240,11 +240,11 @@ base::FilePath ExternalMountPoints::CreateVirtualRootPath( } FileSystemURL ExternalMountPoints::CreateExternalFileSystemURL( - const url::Origin& origin, + const blink::StorageKey& storage_key, const std::string& mount_name, const base::FilePath& path) const { return CreateCrackedFileSystemURL( - origin, kFileSystemTypeExternal, + storage_key, kFileSystemTypeExternal, // Avoid using FilePath::Append as path may be an absolute path. base::FilePath(CreateVirtualRootPath(mount_name).value() + base::FilePath::kSeparators[0] + path.value())); diff --git a/chromium/storage/browser/file_system/external_mount_points.h b/chromium/storage/browser/file_system/external_mount_points.h index 381592d95bf..660a7c550b5 100644 --- a/chromium/storage/browser/file_system/external_mount_points.h +++ b/chromium/storage/browser/file_system/external_mount_points.h @@ -17,11 +17,16 @@ #include "storage/browser/file_system/mount_points.h" #include "storage/common/file_system/file_system_mount_option.h" #include "storage/common/file_system/file_system_types.h" -#include "url/origin.h" + +class GURL; namespace base { class FilePath; -} +} // namespace base + +namespace blink { +class StorageKey; +} // namespace blink namespace storage { @@ -78,9 +83,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) ExternalMountPoints std::string* cracked_id, base::FilePath* path, FileSystemMountOption* mount_option) const override; - FileSystemURL CrackURL(const GURL& url) const override; + FileSystemURL CrackURL(const GURL& url, + const blink::StorageKey& storage_key) const override; FileSystemURL CreateCrackedFileSystemURL( - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type, const base::FilePath& virtual_path) const override; @@ -107,9 +113,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) ExternalMountPoints // Returns the virtual root path that looks like /<mount_name>. base::FilePath CreateVirtualRootPath(const std::string& mount_name) const; - FileSystemURL CreateExternalFileSystemURL(const url::Origin& origin, - const std::string& mount_name, - const base::FilePath& path) const; + FileSystemURL CreateExternalFileSystemURL( + const blink::StorageKey& storage_key, + const std::string& mount_name, + const base::FilePath& path) const; // Revoke all registered filesystems. Used only by testing (for clean-ups). void RevokeAllFileSystems(); diff --git a/chromium/storage/browser/file_system/external_mount_points_unittest.cc b/chromium/storage/browser/file_system/external_mount_points_unittest.cc index f1cc824674e..5a72caae4b9 100644 --- a/chromium/storage/browser/file_system/external_mount_points_unittest.cc +++ b/chromium/storage/browser/file_system/external_mount_points_unittest.cc @@ -14,6 +14,8 @@ #include "storage/browser/file_system/file_system_url.h" #include "storage/common/file_system/file_system_mount_option.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/storage_key/storage_key.h" +#include "url/gurl.h" #define FPL FILE_PATH_LITERAL @@ -23,6 +25,8 @@ #define DRIVE #endif +class GURL; + namespace storage { TEST(ExternalMountPointsTest, AddMountPoint) { @@ -259,8 +263,8 @@ TEST(ExternalMountPointsTest, CreateCrackedFileSystemURL) { scoped_refptr<ExternalMountPoints> mount_points = ExternalMountPoints::CreateRefCounted(); - const url::Origin kTestOrigin = - url::Origin::Create(GURL("http://chromium.org")); + const blink::StorageKey kTestStorageKey = + blink::StorageKey::CreateFromStringForTesting("http://chromium.org"); mount_points->RegisterFileSystem("c", kFileSystemTypeLocal, FileSystemMountOption(), @@ -275,17 +279,19 @@ TEST(ExternalMountPointsTest, CreateCrackedFileSystemURL) { base::FilePath(DRIVE FPL("/root"))); // Try cracking invalid GURL. - FileSystemURL invalid = mount_points->CrackURL(GURL("http://chromium.og")); + FileSystemURL invalid = mount_points->CrackURL( + GURL("http://chromium.og"), + blink::StorageKey::CreateFromStringForTesting("http://chromium.og")); EXPECT_FALSE(invalid.is_valid()); // Try cracking isolated path. FileSystemURL isolated = mount_points->CreateCrackedFileSystemURL( - kTestOrigin, kFileSystemTypeIsolated, base::FilePath(FPL("c"))); + kTestStorageKey, kFileSystemTypeIsolated, base::FilePath(FPL("c"))); EXPECT_FALSE(isolated.is_valid()); // Try native local which is not cracked. FileSystemURL native_local = mount_points->CreateCrackedFileSystemURL( - kTestOrigin, kFileSystemTypeLocal, base::FilePath(FPL("c"))); + kTestStorageKey, kFileSystemTypeLocal, base::FilePath(FPL("c"))); EXPECT_FALSE(native_local.is_valid()); struct TestCase { @@ -326,7 +332,7 @@ TEST(ExternalMountPointsTest, CreateCrackedFileSystemURL) { for (size_t i = 0; i < base::size(kTestCases); ++i) { FileSystemURL cracked = mount_points->CreateCrackedFileSystemURL( - kTestOrigin, kFileSystemTypeExternal, + kTestStorageKey, kFileSystemTypeExternal, base::FilePath(kTestCases[i].path)); EXPECT_EQ(kTestCases[i].expect_valid, cracked.is_valid()) @@ -335,7 +341,8 @@ TEST(ExternalMountPointsTest, CreateCrackedFileSystemURL) { if (!kTestCases[i].expect_valid) continue; - EXPECT_EQ(kTestOrigin, cracked.origin()) << "Test case index: " << i; + EXPECT_EQ(kTestStorageKey.origin(), cracked.origin()) + << "Test case index: " << i; EXPECT_EQ(kTestCases[i].expect_type, cracked.type()) << "Test case index: " << i; EXPECT_EQ( 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 e48515b60ee..d1877e8ff0e 100644 --- a/chromium/storage/browser/file_system/file_stream_reader_test.h +++ b/chromium/storage/browser/file_system/file_stream_reader_test.h @@ -111,8 +111,7 @@ TYPED_TEST_P(FileStreamReaderTypedTest, GetLengthNormal) { } TYPED_TEST_P(FileStreamReaderTypedTest, GetLengthAfterModified) { - this->TouchFile(std::string(this->kTestFileName), - base::TimeDelta::FromSeconds(10)); + this->TouchFile(std::string(this->kTestFileName), base::Seconds(10)); std::unique_ptr<FileStreamReader> reader( this->CreateFileReader(std::string(this->kTestFileName), 0, @@ -159,8 +158,7 @@ TYPED_TEST_P(FileStreamReaderTypedTest, ReadAfterModified) { // Touch file so that the file's modification time becomes different // from what we expect. Note that the resolution on some filesystems // is 1s so we can't test with deltas less than that. - this->TouchFile(std::string(this->kTestFileName), - base::TimeDelta::FromSeconds(-1)); + this->TouchFile(std::string(this->kTestFileName), base::Seconds(-1)); std::unique_ptr<FileStreamReader> reader( this->CreateFileReader(std::string(this->kTestFileName), 0, @@ -176,8 +174,7 @@ TYPED_TEST_P(FileStreamReaderTypedTest, ReadAfterModifiedLessThanThreshold) { // Due to precision loss converting int64_t->double->int64_t (e.g. through // Blink) the expected/actual time may vary by microseconds. With // modification time delta < 10us this should work. - this->TouchFile(std::string(this->kTestFileName), - base::TimeDelta::FromMicroseconds(1)); + this->TouchFile(std::string(this->kTestFileName), base::Microseconds(1)); std::unique_ptr<FileStreamReader> reader( this->CreateFileReader(std::string(this->kTestFileName), 0, this->test_file_modification_time())); @@ -203,8 +200,7 @@ TYPED_TEST_P(FileStreamReaderTypedTest, ReadAfterModifiedWithMatchingTimes) { } TYPED_TEST_P(FileStreamReaderTypedTest, ReadAfterModifiedWithoutExpectedTime) { - this->TouchFile(std::string(this->kTestFileName), - base::TimeDelta::FromSeconds(-1)); + this->TouchFile(std::string(this->kTestFileName), base::Seconds(-1)); std::unique_ptr<FileStreamReader> reader(this->CreateFileReader( std::string(this->kTestFileName), 0, base::Time())); int result = 0; diff --git a/chromium/storage/browser/file_system/file_system_backend.h b/chromium/storage/browser/file_system/file_system_backend.h index ead78eb0375..dd7662d7284 100644 --- a/chromium/storage/browser/file_system/file_system_backend.h +++ b/chromium/storage/browser/file_system/file_system_backend.h @@ -96,7 +96,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemBackend { // |error_code| correspondingly. // This method is usually dispatched by // FileSystemContext::CreateFileSystemOperation. - virtual FileSystemOperation* CreateFileSystemOperation( + virtual std::unique_ptr<FileSystemOperation> CreateFileSystemOperation( const FileSystemURL& url, FileSystemContext* context, base::File::Error* error_code) const = 0; diff --git a/chromium/storage/browser/file_system/file_system_context.cc b/chromium/storage/browser/file_system/file_system_context.cc index a9dff4886dc..f6362869e4f 100644 --- a/chromium/storage/browser/file_system/file_system_context.cc +++ b/chromium/storage/browser/file_system/file_system_context.cc @@ -279,19 +279,19 @@ void FileSystemContext::Initialize() { base::RetainedRef(this), std::move(quota_client_receiver))); } -bool FileSystemContext::DeleteDataForOriginOnFileTaskRunner( - const url::Origin& origin) { +bool FileSystemContext::DeleteDataForStorageKeyOnFileTaskRunner( + const blink::StorageKey& storage_key) { DCHECK(default_file_task_runner()->RunsTasksInCurrentSequence()); - DCHECK(origin.GetURL().is_valid()); + DCHECK(!storage_key.origin().opaque()); bool success = true; for (auto& type_backend_pair : backend_map_) { FileSystemBackend* backend = type_backend_pair.second; if (!backend->GetQuotaUtil()) continue; - if (backend->GetQuotaUtil()->DeleteOriginDataOnFileTaskRunner( - this, quota_manager_proxy(), origin, type_backend_pair.first) != - base::File::FILE_OK) { + if (backend->GetQuotaUtil()->DeleteStorageKeyDataOnFileTaskRunner( + this, quota_manager_proxy(), storage_key, + type_backend_pair.first) != base::File::FILE_OK) { // Continue the loop, but record the failure. success = false; } @@ -302,14 +302,14 @@ bool FileSystemContext::DeleteDataForOriginOnFileTaskRunner( scoped_refptr<QuotaReservation> FileSystemContext::CreateQuotaReservationOnFileTaskRunner( - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type) { DCHECK(default_file_task_runner()->RunsTasksInCurrentSequence()); FileSystemBackend* backend = GetFileSystemBackend(type); if (!backend || !backend->GetQuotaUtil()) return scoped_refptr<QuotaReservation>(); - return backend->GetQuotaUtil()->CreateQuotaReservationOnFileTaskRunner(origin, - type); + return backend->GetQuotaUtil()->CreateQuotaReservationOnFileTaskRunner( + storage_key, type); } void FileSystemContext::Shutdown() { @@ -487,11 +487,11 @@ void FileSystemContext::AttemptAutoMountForURLRequest( std::move(callback).Run(base::File::FILE_ERROR_NOT_FOUND); } -void FileSystemContext::DeleteFileSystem(const url::Origin& origin, +void FileSystemContext::DeleteFileSystem(const blink::StorageKey& storage_key, FileSystemType type, StatusCallback callback) { DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); - DCHECK(origin.GetURL().is_valid()); + DCHECK(!storage_key.origin().opaque()); DCHECK(!callback.is_null()); FileSystemBackend* backend = GetFileSystemBackend(type); @@ -507,10 +507,10 @@ void FileSystemContext::DeleteFileSystem(const url::Origin& origin, base::PostTaskAndReplyWithResult( default_file_task_runner(), FROM_HERE, // It is safe to pass Unretained(quota_util) since context owns it. - base::BindOnce(&FileSystemQuotaUtil::DeleteOriginDataOnFileTaskRunner, - base::Unretained(backend->GetQuotaUtil()), - base::RetainedRef(this), - base::Unretained(quota_manager_proxy()), origin, type), + base::BindOnce( + &FileSystemQuotaUtil::DeleteStorageKeyDataOnFileTaskRunner, + base::Unretained(backend->GetQuotaUtil()), base::RetainedRef(this), + base::Unretained(quota_manager_proxy()), storage_key, type), std::move(callback)); } @@ -624,9 +624,9 @@ FileSystemContext::QuotaManagedStorageTypes() { return quota_storage_types; } -FileSystemOperation* FileSystemContext::CreateFileSystemOperation( - const FileSystemURL& url, - base::File::Error* error_code) { +std::unique_ptr<FileSystemOperation> +FileSystemContext::CreateFileSystemOperation(const FileSystemURL& url, + base::File::Error* error_code) { if (!url.is_valid()) { if (error_code) *error_code = base::File::FILE_ERROR_INVALID_URL; @@ -641,7 +641,7 @@ FileSystemOperation* FileSystemContext::CreateFileSystemOperation( } base::File::Error fs_error = base::File::FILE_OK; - FileSystemOperation* operation = + std::unique_ptr<FileSystemOperation> operation = backend->CreateFileSystemOperation(url, this, &fs_error); if (error_code) diff --git a/chromium/storage/browser/file_system/file_system_context.h b/chromium/storage/browser/file_system/file_system_context.h index 49d34aaf8a4..99699365e0a 100644 --- a/chromium/storage/browser/file_system/file_system_context.h +++ b/chromium/storage/browser/file_system/file_system_context.h @@ -42,11 +42,11 @@ class SingleThreadTaskRunner; namespace blink { class StorageKey; -} +} // namespace blink namespace leveleb { class Env; -} +} // namespace leveleb namespace storage { @@ -83,9 +83,9 @@ struct FileSystemRequestInfo { }; // An auto mount handler will attempt to mount the file system requested in -// |request_info|. If the URL is for this auto mount handler, it returns true -// and calls |callback| when the attempt is complete. If the auto mounter -// does not recognize the URL, it returns false and does not call |callback|. +// `request_info`. If the URL is for this auto mount handler, it returns true +// and calls `callback` when the attempt is complete. If the auto mounter +// does not recognize the URL, it returns false and does not call `callback`. // Called on the IO thread. using URLRequestAutoMountHandler = base::RepeatingCallback<bool( const FileSystemRequestInfo& request_info, @@ -99,7 +99,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemContext public: REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE(); - // Returns file permission policy we should apply for the given |type|. + // Returns file permission policy we should apply for the given `type`. // The return value must be bitwise-or'd of FilePermissionPolicy. // // Note: if a part of a filesystem is returned via 'Isolated' mount point, @@ -115,17 +115,17 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemContext // allows blocking file operations (like SequencedWorkerPool implementation // does). // - // |external_mount_points| contains non-system external mount points available + // `external_mount_points` contains non-system external mount points available // in the context. If not nullptr, it will be used during URL cracking. - // |external_mount_points| may be nullptr only on platforms different from + // `external_mount_points` may be nullptr only on platforms different from // ChromeOS (i.e. platforms that don't use external_mount_point_provider). // - // |additional_backends| are added to the internal backend map + // `additional_backends` are added to the internal backend map // to serve filesystem requests for non-regular types. // If none is given, this context only handles HTML5 Sandbox FileSystem // and Drag-and-drop Isolated FileSystem requests. // - // |auto_mount_handlers| are used to resolve calls to + // `auto_mount_handlers` are used to resolve calls to // AttemptAutoMountForURLRequest. Only external filesystems are auto mounted // when a filesystem: URL request is made. static scoped_refptr<FileSystemContext> Create( @@ -153,14 +153,15 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemContext const FileSystemOptions& options, base::PassKey<FileSystemContext>); - bool DeleteDataForOriginOnFileTaskRunner(const url::Origin& origin); + bool DeleteDataForStorageKeyOnFileTaskRunner( + const blink::StorageKey& storage_key); - // Creates a new QuotaReservation for the given |origin| and |type|. - // Returns nullptr if |type| does not support quota or reservation fails. - // This should be run on |default_file_task_runner_| and the returned value + // Creates a new QuotaReservation for the given `storage_key` and `type`. + // Returns nullptr if `type` does not support quota or reservation fails. + // This should be run on `default_file_task_runner_` and the returned value // should be destroyed on the runner. scoped_refptr<QuotaReservation> CreateQuotaReservationOnFileTaskRunner( - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type); QuotaManagerProxy* quota_manager_proxy() const { @@ -175,22 +176,22 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemContext // it is not a quota-managed storage. FileSystemQuotaUtil* GetQuotaUtil(FileSystemType type) const; - // Returns the appropriate AsyncFileUtil instance for the given |type|. + // Returns the appropriate AsyncFileUtil instance for the given `type`. AsyncFileUtil* GetAsyncFileUtil(FileSystemType type) const; // Returns the appropriate CopyOrMoveFileValidatorFactory for the given - // |type|. If |error_code| is File::FILE_OK and the result is nullptr, + // `type`. If `error_code` is File::FILE_OK and the result is nullptr, // then no validator is required. CopyOrMoveFileValidatorFactory* GetCopyOrMoveFileValidatorFactory( FileSystemType type, base::File::Error* error_code) const; - // Returns the file system backend instance for the given |type|. + // Returns the file system backend instance for the given `type`. // This may return nullptr if it is given an invalid or unsupported filesystem // type. FileSystemBackend* GetFileSystemBackend(FileSystemType type) const; - // Returns the watcher manager for the given |type|. + // Returns the watcher manager for the given `type`. // This may return nullptr if the type does not support watching. WatcherManager* GetWatcherManager(FileSystemType type) const; @@ -244,37 +245,37 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemContext OpenFileSystemMode mode, OpenFileSystemCallback callback); - // Opens the filesystem for the given |url| as read-only, if the filesystem + // Opens the filesystem for the given `url` as read-only, if the filesystem // backend referred by the URL allows opening by resolveURL. Otherwise it // fails with FILE_ERROR_SECURITY. The entry pointed by the URL can be // absent; in that case RESOLVED_ENTRY_NOT_FOUND type is returned to the // callback for indicating the absence. Can be called from any thread with - // a message loop. |callback| is invoked on the caller thread. + // a message loop. `callback` is invoked on the caller thread. void ResolveURL(const FileSystemURL& url, ResolveURLCallback callback); - // Attempts to mount the filesystem needed to satisfy |request_info| made from - // |request_info.storage_domain|. If an appropriate file system is not found, + // Attempts to mount the filesystem needed to satisfy `request_info` made from + // `request_info.storage_domain`. If an appropriate file system is not found, // callback will return an error. void AttemptAutoMountForURLRequest(const FileSystemRequestInfo& request_info, StatusCallback callback); - // Deletes the filesystem for the given |origin_url| and |type|. This should + // Deletes the filesystem for the given `storage_key` and `type`. This should // be called on the IO thread. - void DeleteFileSystem(const url::Origin& origin, + void DeleteFileSystem(const blink::StorageKey& storage_key, FileSystemType type, StatusCallback callback); // Creates new FileStreamReader instance to read a file pointed by the given - // filesystem URL |url| starting from |offset|. |expected_modification_time| + // filesystem URL `url` starting from `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. - // This method internally cracks the |url|, get an appropriate + // This method internally cracks the `url`, get an appropriate // FileSystemBackend for the URL and call the backend's CreateFileReader. // The resolved FileSystemBackend could perform further specialization - // depending on the filesystem type pointed by the |url|. - // At most |max_bytes_to_read| can be fetched from the file stream reader. + // depending on the filesystem type pointed by the `url`. + // At most `max_bytes_to_read` can be fetched from the file stream reader. std::unique_ptr<FileStreamReader> CreateFileStreamReader( const FileSystemURL& url, int64_t offset, @@ -282,7 +283,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemContext const base::Time& expected_modification_time); // Creates new FileStreamWriter instance to write into a file pointed by - // |url| from |offset|. + // `url` from `offset`. std::unique_ptr<FileStreamWriter> CreateFileStreamWriter( const FileSystemURL& url, int64_t offset); @@ -334,6 +335,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemContext // This must be used to open 'plugin private' filesystem. // See "plugin_private_file_system_backend.h" for more details. + // + // TODO(https://crbug.com/1231162): determine whether EME/CDM/plugin private + // file system will be partitioned; if so, replace the url::Origin parameter + // with blink::StorageKey void OpenPluginPrivateFileSystem(const url::Origin& origin, FileSystemType type, const std::string& filesystem_id, @@ -368,18 +373,19 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemContext std::vector<blink::mojom::StorageType> QuotaManagedStorageTypes(); // Creates a new FileSystemOperation instance by getting an appropriate - // FileSystemBackend for |url| and calling the backend's corresponding + // FileSystemBackend for `url` and calling the backend's corresponding // CreateFileSystemOperation method. // The resolved FileSystemBackend could perform further specialization - // depending on the filesystem type pointed by the |url|. + // depending on the filesystem type pointed by the `url`. // // Called by FileSystemOperationRunner. - FileSystemOperation* CreateFileSystemOperation(const FileSystemURL& url, - base::File::Error* error_code); + std::unique_ptr<FileSystemOperation> CreateFileSystemOperation( + const FileSystemURL& url, + base::File::Error* error_code); // For non-cracked isolated and external mount points, returns a FileSystemURL - // created by cracking |url|. The url is cracked using MountPoints registered - // as |url_crackers_|. If the url cannot be cracked, returns invalid + // created by cracking `url`. The url is cracked using MountPoints registered + // as `url_crackers_`. If the url cannot be cracked, returns invalid // FileSystemURL. // // If the original url does not point to an isolated or external filesystem, @@ -406,7 +412,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemContext return plugin_private_backend_.get(); } - // Override the default leveldb Env with |env_override_| if set. + // Override the default leveldb Env with `env_override_` if set. std::unique_ptr<leveldb::Env> env_override_; const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; diff --git a/chromium/storage/browser/file_system/file_system_context_unittest.cc b/chromium/storage/browser/file_system/file_system_context_unittest.cc index 26c4da3e222..036e96dc591 100644 --- a/chromium/storage/browser/file_system/file_system_context_unittest.cc +++ b/chromium/storage/browser/file_system/file_system_context_unittest.cc @@ -210,7 +210,6 @@ TEST_F(FileSystemContextTest, CrackFileSystemURL) { "ext", kFileSystemTypeLocal, FileSystemMountOption(), base::FilePath(DRIVE FPL("/test/local/ext/")))); - const GURL kTestOrigin = GURL("http://chromium.org/"); const base::FilePath kVirtualPathNoRoot = base::FilePath(FPL("root/file")); struct TestCase { @@ -264,7 +263,7 @@ TEST_F(FileSystemContextTest, CrackFileSystemURL) { for (size_t i = 0; i < base::size(kTestCases); ++i) { const base::FilePath virtual_path = - base::FilePath::FromUTF8Unsafe(kTestCases[i].root) + base::FilePath::FromASCII(kTestCases[i].root) .Append(kVirtualPathNoRoot); GURL raw_url = diff --git a/chromium/storage/browser/file_system/file_system_operation.h b/chromium/storage/browser/file_system/file_system_operation.h index 89ee141c3e3..5762713d569 100644 --- a/chromium/storage/browser/file_system/file_system_operation.h +++ b/chromium/storage/browser/file_system/file_system_operation.h @@ -15,6 +15,7 @@ #include "base/files/file.h" #include "base/files/file_path.h" #include "base/process/process.h" +#include "base/types/pass_key.h" #include "components/services/filesystem/public/mojom/types.mojom.h" #include "storage/browser/blob/blob_reader.h" #include "storage/browser/file_system/file_system_operation_context.h" @@ -57,7 +58,7 @@ class FileWriterDelegate; class FileSystemOperation { public: COMPONENT_EXPORT(STORAGE_BROWSER) - static FileSystemOperation* Create( + static std::unique_ptr<FileSystemOperation> Create( const FileSystemURL& url, FileSystemContext* file_system_context, std::unique_ptr<FileSystemOperationContext> operation_context); @@ -251,6 +252,12 @@ class FileSystemOperation { // destination file, this option would be simply ignored (i.e. Copy would // be successfully done without preserving last modified time). OPTION_PRESERVE_LAST_MODIFIED, + + // Preserve permissions of the destination file. If the operation to update + // permissions is not supported on the file system for the destination file, + // this option will simply be ignored (i.e. Copy would be successfully done + // without preserving permissions of the destination file). + OPTION_PRESERVE_DESTINATION_PERMISSIONS, }; // Fields requested for the GetMetadata method. Used as a bitmask. @@ -550,6 +557,11 @@ class FileSystemOperation { }; FileSystemOperation() = default; + + // Allows subclasses to call the FileSystemOperationImpl constructor. + static base::PassKey<FileSystemOperation> CreatePassKey() { + return base::PassKey<FileSystemOperation>(); + } }; } // namespace storage 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 b3837f27a48..2df222e6ba7 100644 --- a/chromium/storage/browser/file_system/file_system_operation_context.h +++ b/chromium/storage/browser/file_system/file_system_operation_context.h @@ -38,6 +38,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemOperationContext FileSystemOperationContext(FileSystemContext* context, base::SequencedTaskRunner* task_runner); + FileSystemOperationContext(const FileSystemOperationContext&) = delete; + FileSystemOperationContext& operator=(const FileSystemOperationContext&) = + delete; + ~FileSystemOperationContext() override; FileSystemContext* file_system_context() const { @@ -90,8 +94,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemOperationContext // Used to check its setters are not called on arbitrary thread. THREAD_CHECKER(setter_thread_checker_); - - DISALLOW_COPY_AND_ASSIGN(FileSystemOperationContext); }; } // namespace storage 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 70ad2fe3526..a3eb8b19e50 100644 --- a/chromium/storage/browser/file_system/file_system_operation_impl.cc +++ b/chromium/storage/browser/file_system/file_system_operation_impl.cc @@ -16,6 +16,7 @@ #include "base/single_thread_task_runner.h" #include "base/threading/sequenced_task_runner_handle.h" #include "base/time/time.h" +#include "base/types/pass_key.h" #include "net/base/escape.h" #include "net/url_request/url_request.h" #include "storage/browser/blob/shareable_file_reference.h" @@ -55,12 +56,13 @@ void DidOpenFile(scoped_refptr<FileSystemContext> context, } // namespace -FileSystemOperation* FileSystemOperation::Create( +std::unique_ptr<FileSystemOperation> FileSystemOperation::Create( const FileSystemURL& url, FileSystemContext* file_system_context, std::unique_ptr<FileSystemOperationContext> operation_context) { - return new FileSystemOperationImpl(url, file_system_context, - std::move(operation_context)); + return std::make_unique<FileSystemOperationImpl>( + url, file_system_context, std::move(operation_context), + base::PassKey<FileSystemOperation>()); } FileSystemOperationImpl::~FileSystemOperationImpl() = default; @@ -388,7 +390,8 @@ base::File::Error FileSystemOperationImpl::SyncGetPlatformPath( FileSystemOperationImpl::FileSystemOperationImpl( const FileSystemURL& url, FileSystemContext* file_system_context, - std::unique_ptr<FileSystemOperationContext> operation_context) + std::unique_ptr<FileSystemOperationContext> operation_context, + base::PassKey<FileSystemOperation>) : file_system_context_(file_system_context), operation_context_(std::move(operation_context)), async_file_util_(nullptr), 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 ee6f52aacbc..64be697f0d9 100644 --- a/chromium/storage/browser/file_system/file_system_operation_impl.h +++ b/chromium/storage/browser/file_system/file_system_operation_impl.h @@ -14,6 +14,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "base/types/pass_key.h" #include "storage/browser/blob/scoped_file.h" #include "storage/browser/file_system/file_system_operation.h" #include "storage/browser/file_system/file_system_operation_context.h" @@ -25,12 +26,24 @@ namespace storage { class AsyncFileUtil; class FileSystemContext; +class FileSystemOperation; class RecursiveOperationDelegate; // The default implementation of FileSystemOperation for file systems. class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemOperationImpl : public FileSystemOperation { public: + // Exposed for use with std::make_unique. Instances should be obtained from + // the factory method FileSystemOperation::Create(). + FileSystemOperationImpl( + const FileSystemURL& url, + FileSystemContext* file_system_context, + std::unique_ptr<FileSystemOperationContext> operation_context, + base::PassKey<FileSystemOperation>); + + FileSystemOperationImpl(const FileSystemOperationImpl&) = delete; + FileSystemOperationImpl& operator=(const FileSystemOperationImpl&) = delete; + ~FileSystemOperationImpl() override; // FileSystemOperation overrides. @@ -107,12 +120,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemOperationImpl return file_system_context_.get(); } - protected: - FileSystemOperationImpl( - const FileSystemURL& url, - FileSystemContext* file_system_context, - std::unique_ptr<FileSystemOperationContext> operation_context); - private: friend class FileSystemOperation; @@ -206,8 +213,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemOperationImpl base::WeakPtr<FileSystemOperationImpl> weak_ptr_; base::WeakPtrFactory<FileSystemOperationImpl> weak_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(FileSystemOperationImpl); }; } // namespace storage 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 65a31f6ad3f..d3c44782632 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 @@ -226,14 +226,14 @@ class FileSystemOperationImplTest : public testing::Test { } int64_t GetDataSizeOnDisk() { - return sandbox_file_system_.ComputeCurrentOriginUsage() - + return sandbox_file_system_.ComputeCurrentStorageKeyUsage() - sandbox_file_system_.ComputeCurrentDirectoryDatabaseUsage(); } void GetUsageAndQuota(int64_t* usage, int64_t* quota) { blink::mojom::QuotaStatusCode status = AsyncFileTestHelper::GetUsageAndQuota( - quota_manager_.get(), sandbox_file_system_.origin(), + quota_manager_.get(), sandbox_file_system_.storage_key().origin(), sandbox_file_system_.type(), usage, quota); task_environment_.RunUntilIdle(); ASSERT_EQ(blink::mojom::QuotaStatusCode::kOk, status); @@ -257,7 +257,7 @@ class FileSystemOperationImplTest : public testing::Test { void GrantQuotaForCurrentUsage() { int64_t usage; GetUsageAndQuota(&usage, nullptr); - quota_manager()->SetQuota(blink::StorageKey(sandbox_file_system_.origin()), + quota_manager()->SetQuota(sandbox_file_system_.storage_key(), sandbox_file_system_.storage_type(), usage); } @@ -270,7 +270,7 @@ class FileSystemOperationImplTest : public testing::Test { void AddQuota(int64_t quota_delta) { int64_t quota; GetUsageAndQuota(nullptr, "a); - quota_manager()->SetQuota(blink::StorageKey(sandbox_file_system_.origin()), + quota_manager()->SetQuota(sandbox_file_system_.storage_key(), sandbox_file_system_.storage_type(), quota + quota_delta); } @@ -1128,8 +1128,7 @@ TEST_F(FileSystemOperationImplTest, TestTouchFile) { const base::Time last_accessed = info.last_accessed; const base::Time new_modified_time = base::Time::UnixEpoch(); - const base::Time new_accessed_time = - new_modified_time + base::TimeDelta::FromHours(77); + const base::Time new_accessed_time = new_modified_time + base::Hours(77); ASSERT_NE(last_modified, new_modified_time); ASSERT_NE(last_accessed, new_accessed_time); 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 ab92adbc1bc..bf2fec28c35 100644 --- a/chromium/storage/browser/file_system/file_system_operation_runner.cc +++ b/chromium/storage/browser/file_system/file_system_operation_runner.cc @@ -49,8 +49,8 @@ OperationID FileSystemOperationRunner::CreateFile(const FileSystemURL& url, bool exclusive, StatusCallback callback) { base::File::Error error = base::File::FILE_OK; - std::unique_ptr<FileSystemOperation> operation = base::WrapUnique( - file_system_context_->CreateFileSystemOperation(url, &error)); + std::unique_ptr<FileSystemOperation> operation = + file_system_context_->CreateFileSystemOperation(url, &error); FileSystemOperation* operation_raw = operation.get(); OperationID id = BeginOperation(std::move(operation)); base::AutoReset<bool> beginning(&is_beginning_operation_, true); @@ -72,8 +72,8 @@ OperationID FileSystemOperationRunner::CreateDirectory( bool recursive, StatusCallback callback) { base::File::Error error = base::File::FILE_OK; - std::unique_ptr<FileSystemOperation> operation = base::WrapUnique( - file_system_context_->CreateFileSystemOperation(url, &error)); + std::unique_ptr<FileSystemOperation> operation = + file_system_context_->CreateFileSystemOperation(url, &error); FileSystemOperation* operation_raw = operation.get(); OperationID id = BeginOperation(std::move(operation)); base::AutoReset<bool> beginning(&is_beginning_operation_, true); @@ -97,8 +97,8 @@ OperationID FileSystemOperationRunner::Copy( 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)); + std::unique_ptr<FileSystemOperation> operation = + file_system_context_->CreateFileSystemOperation(dest_url, &error); FileSystemOperation* operation_raw = operation.get(); OperationID id = BeginOperation(std::move(operation)); base::AutoReset<bool> beginning(&is_beginning_operation_, true); @@ -127,8 +127,8 @@ OperationID FileSystemOperationRunner::Move( 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)); + std::unique_ptr<FileSystemOperation> operation = + file_system_context_->CreateFileSystemOperation(dest_url, &error); FileSystemOperation* operation_raw = operation.get(); OperationID id = BeginOperation(std::move(operation)); base::AutoReset<bool> beginning(&is_beginning_operation_, true); @@ -153,8 +153,8 @@ OperationID FileSystemOperationRunner::DirectoryExists( const FileSystemURL& url, StatusCallback callback) { base::File::Error error = base::File::FILE_OK; - std::unique_ptr<FileSystemOperation> operation = base::WrapUnique( - file_system_context_->CreateFileSystemOperation(url, &error)); + std::unique_ptr<FileSystemOperation> operation = + file_system_context_->CreateFileSystemOperation(url, &error); FileSystemOperation* operation_raw = operation.get(); OperationID id = BeginOperation(std::move(operation)); base::AutoReset<bool> beginning(&is_beginning_operation_, true); @@ -172,8 +172,8 @@ OperationID FileSystemOperationRunner::DirectoryExists( OperationID FileSystemOperationRunner::FileExists(const FileSystemURL& url, StatusCallback callback) { base::File::Error error = base::File::FILE_OK; - std::unique_ptr<FileSystemOperation> operation = base::WrapUnique( - file_system_context_->CreateFileSystemOperation(url, &error)); + std::unique_ptr<FileSystemOperation> operation = + file_system_context_->CreateFileSystemOperation(url, &error); FileSystemOperation* operation_raw = operation.get(); OperationID id = BeginOperation(std::move(operation)); base::AutoReset<bool> beginning(&is_beginning_operation_, true); @@ -193,8 +193,8 @@ OperationID FileSystemOperationRunner::GetMetadata( int fields, GetMetadataCallback callback) { base::File::Error error = base::File::FILE_OK; - std::unique_ptr<FileSystemOperation> operation = base::WrapUnique( - file_system_context_->CreateFileSystemOperation(url, &error)); + std::unique_ptr<FileSystemOperation> operation = + file_system_context_->CreateFileSystemOperation(url, &error); FileSystemOperation* operation_raw = operation.get(); OperationID id = BeginOperation(std::move(operation)); base::AutoReset<bool> beginning(&is_beginning_operation_, true); @@ -214,8 +214,8 @@ OperationID FileSystemOperationRunner::ReadDirectory( const FileSystemURL& url, const ReadDirectoryCallback& callback) { base::File::Error error = base::File::FILE_OK; - std::unique_ptr<FileSystemOperation> operation = base::WrapUnique( - file_system_context_->CreateFileSystemOperation(url, &error)); + std::unique_ptr<FileSystemOperation> operation = + file_system_context_->CreateFileSystemOperation(url, &error); FileSystemOperation* operation_raw = operation.get(); OperationID id = BeginOperation(std::move(operation)); base::AutoReset<bool> beginning(&is_beginning_operation_, true); @@ -235,8 +235,8 @@ OperationID FileSystemOperationRunner::Remove(const FileSystemURL& url, bool recursive, StatusCallback callback) { base::File::Error error = base::File::FILE_OK; - std::unique_ptr<FileSystemOperation> operation = base::WrapUnique( - file_system_context_->CreateFileSystemOperation(url, &error)); + std::unique_ptr<FileSystemOperation> operation = + file_system_context_->CreateFileSystemOperation(url, &error); FileSystemOperation* operation_raw = operation.get(); OperationID id = BeginOperation(std::move(operation)); base::AutoReset<bool> beginning(&is_beginning_operation_, true); @@ -257,8 +257,8 @@ OperationID FileSystemOperationRunner::Write( int64_t offset, const WriteCallback& callback) { base::File::Error error = base::File::FILE_OK; - std::unique_ptr<FileSystemOperation> operation = base::WrapUnique( - file_system_context_->CreateFileSystemOperation(url, &error)); + std::unique_ptr<FileSystemOperation> operation = + file_system_context_->CreateFileSystemOperation(url, &error); FileSystemOperation* operation_raw = operation.get(); OperationID id = BeginOperation(std::move(operation)); base::AutoReset<bool> beginning(&is_beginning_operation_, true); @@ -296,8 +296,8 @@ OperationID FileSystemOperationRunner::WriteStream( int64_t offset, const WriteCallback& callback) { base::File::Error error = base::File::FILE_OK; - std::unique_ptr<FileSystemOperation> operation = base::WrapUnique( - file_system_context_->CreateFileSystemOperation(url, &error)); + std::unique_ptr<FileSystemOperation> operation = + file_system_context_->CreateFileSystemOperation(url, &error); FileSystemOperation* operation_raw = operation.get(); OperationID id = BeginOperation(std::move(operation)); base::AutoReset<bool> beginning(&is_beginning_operation_, true); @@ -328,8 +328,8 @@ OperationID FileSystemOperationRunner::Truncate(const FileSystemURL& url, int64_t length, StatusCallback callback) { base::File::Error error = base::File::FILE_OK; - std::unique_ptr<FileSystemOperation> operation = base::WrapUnique( - file_system_context_->CreateFileSystemOperation(url, &error)); + std::unique_ptr<FileSystemOperation> operation = + file_system_context_->CreateFileSystemOperation(url, &error); FileSystemOperation* operation_raw = operation.get(); OperationID id = BeginOperation(std::move(operation)); base::AutoReset<bool> beginning(&is_beginning_operation_, true); @@ -367,8 +367,8 @@ OperationID FileSystemOperationRunner::TouchFile( const base::Time& last_modified_time, StatusCallback callback) { base::File::Error error = base::File::FILE_OK; - std::unique_ptr<FileSystemOperation> operation = base::WrapUnique( - file_system_context_->CreateFileSystemOperation(url, &error)); + std::unique_ptr<FileSystemOperation> operation = + file_system_context_->CreateFileSystemOperation(url, &error); FileSystemOperation* operation_raw = operation.get(); OperationID id = BeginOperation(std::move(operation)); base::AutoReset<bool> beginning(&is_beginning_operation_, true); @@ -387,8 +387,8 @@ OperationID FileSystemOperationRunner::OpenFile(const FileSystemURL& url, int file_flags, OpenFileCallback callback) { base::File::Error error = base::File::FILE_OK; - std::unique_ptr<FileSystemOperation> operation = base::WrapUnique( - file_system_context_->CreateFileSystemOperation(url, &error)); + std::unique_ptr<FileSystemOperation> operation = + file_system_context_->CreateFileSystemOperation(url, &error); FileSystemOperation* operation_raw = operation.get(); OperationID id = BeginOperation(std::move(operation)); base::AutoReset<bool> beginning(&is_beginning_operation_, true); @@ -417,8 +417,8 @@ OperationID FileSystemOperationRunner::CreateSnapshotFile( const FileSystemURL& url, SnapshotFileCallback callback) { base::File::Error error = base::File::FILE_OK; - std::unique_ptr<FileSystemOperation> operation = base::WrapUnique( - file_system_context_->CreateFileSystemOperation(url, &error)); + std::unique_ptr<FileSystemOperation> operation = + file_system_context_->CreateFileSystemOperation(url, &error); FileSystemOperation* operation_raw = operation.get(); OperationID id = BeginOperation(std::move(operation)); base::AutoReset<bool> beginning(&is_beginning_operation_, true); @@ -439,8 +439,8 @@ OperationID FileSystemOperationRunner::CopyInForeignFile( const FileSystemURL& dest_url, StatusCallback callback) { base::File::Error error = base::File::FILE_OK; - std::unique_ptr<FileSystemOperation> operation = base::WrapUnique( - file_system_context_->CreateFileSystemOperation(dest_url, &error)); + std::unique_ptr<FileSystemOperation> operation = + file_system_context_->CreateFileSystemOperation(dest_url, &error); FileSystemOperation* operation_raw = operation.get(); OperationID id = BeginOperation(std::move(operation)); base::AutoReset<bool> beginning(&is_beginning_operation_, true); @@ -459,8 +459,8 @@ OperationID FileSystemOperationRunner::CopyInForeignFile( OperationID FileSystemOperationRunner::RemoveFile(const FileSystemURL& url, StatusCallback callback) { base::File::Error error = base::File::FILE_OK; - std::unique_ptr<FileSystemOperation> operation = base::WrapUnique( - file_system_context_->CreateFileSystemOperation(url, &error)); + std::unique_ptr<FileSystemOperation> operation = + file_system_context_->CreateFileSystemOperation(url, &error); FileSystemOperation* operation_raw = operation.get(); OperationID id = BeginOperation(std::move(operation)); base::AutoReset<bool> beginning(&is_beginning_operation_, true); @@ -479,8 +479,8 @@ OperationID FileSystemOperationRunner::RemoveDirectory( const FileSystemURL& url, StatusCallback callback) { base::File::Error error = base::File::FILE_OK; - std::unique_ptr<FileSystemOperation> operation = base::WrapUnique( - file_system_context_->CreateFileSystemOperation(url, &error)); + std::unique_ptr<FileSystemOperation> operation = + file_system_context_->CreateFileSystemOperation(url, &error); FileSystemOperation* operation_raw = operation.get(); OperationID id = BeginOperation(std::move(operation)); base::AutoReset<bool> beginning(&is_beginning_operation_, true); @@ -502,8 +502,8 @@ OperationID FileSystemOperationRunner::CopyFileLocal( const CopyFileProgressCallback& progress_callback, StatusCallback callback) { base::File::Error error = base::File::FILE_OK; - std::unique_ptr<FileSystemOperation> operation = base::WrapUnique( - file_system_context_->CreateFileSystemOperation(src_url, &error)); + std::unique_ptr<FileSystemOperation> operation = + file_system_context_->CreateFileSystemOperation(src_url, &error); FileSystemOperation* operation_raw = operation.get(); OperationID id = BeginOperation(std::move(operation)); base::AutoReset<bool> beginning(&is_beginning_operation_, true); @@ -526,8 +526,8 @@ OperationID FileSystemOperationRunner::MoveFileLocal( CopyOrMoveOption option, StatusCallback callback) { base::File::Error error = base::File::FILE_OK; - std::unique_ptr<FileSystemOperation> operation = base::WrapUnique( - file_system_context_->CreateFileSystemOperation(src_url, &error)); + std::unique_ptr<FileSystemOperation> operation = + file_system_context_->CreateFileSystemOperation(src_url, &error); FileSystemOperation* operation_raw = operation.get(); OperationID id = BeginOperation(std::move(operation)); base::AutoReset<bool> beginning(&is_beginning_operation_, true); 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 8dafbc20962..0d186cef3ea 100644 --- a/chromium/storage/browser/file_system/file_system_operation_runner.h +++ b/chromium/storage/browser/file_system/file_system_operation_runner.h @@ -59,6 +59,11 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemOperationRunner { const scoped_refptr<FileSystemContext>& file_system_context); FileSystemOperationRunner(base::PassKey<FileSystemContext>, FileSystemContext* file_system_context); + + FileSystemOperationRunner(const FileSystemOperationRunner&) = delete; + FileSystemOperationRunner& operator=(const FileSystemOperationRunner&) = + delete; + virtual ~FileSystemOperationRunner(); // Cancels all inflight operations. @@ -324,8 +329,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemOperationRunner { base::WeakPtr<FileSystemOperationRunner> weak_ptr_; base::WeakPtrFactory<FileSystemOperationRunner> weak_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(FileSystemOperationRunner); }; } // namespace storage diff --git a/chromium/storage/browser/file_system/file_system_quota_client.cc b/chromium/storage/browser/file_system/file_system_quota_client.cc index 0e6e601ec18..c2683591b2c 100644 --- a/chromium/storage/browser/file_system/file_system_quota_client.cc +++ b/chromium/storage/browser/file_system/file_system_quota_client.cc @@ -4,12 +4,17 @@ #include "storage/browser/file_system/file_system_quota_client.h" +#include <numeric> #include <string> #include <utility> #include <vector> +#include "base/barrier_callback.h" +#include "base/barrier_closure.h" #include "base/bind.h" #include "base/check.h" +#include "base/containers/span.h" +#include "base/feature_list.h" #include "base/files/file.h" #include "base/location.h" #include "base/sequence_checker.h" @@ -18,49 +23,83 @@ #include "storage/browser/file_system/file_system_context.h" #include "storage/common/file_system/file_system_types.h" #include "storage/common/file_system/file_system_util.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/blink/public/mojom/quota/quota_types.mojom.h" -#include "url/origin.h" namespace storage { namespace { -std::vector<blink::StorageKey> ToStorageKeys( - const std::vector<url::Origin>& origins) { - std::vector<blink::StorageKey> storage_keys; - storage_keys.reserve(origins.size()); - for (const url::Origin& origin : origins) - storage_keys.emplace_back(blink::StorageKey(origin)); - return storage_keys; +static const FileSystemType kTemporaryAndPersistent[] = { + kFileSystemTypeTemporary, + kFileSystemTypePersistent, +}; +static const FileSystemType kTemporary[] = {kFileSystemTypeTemporary}; +static const FileSystemType kPersistent[] = {kFileSystemTypePersistent}; +static const FileSystemType kSyncable[] = {kFileSystemTypeSyncable}; + +template <typename T> +std::vector<T> MergeWithoutDuplicates(const std::vector<std::vector<T>>& tss) { + if (tss.size() == 1) { + // We assume that each vector contains no duplicates, already. + return tss[0]; + } + std::vector<T> merged; + merged.reserve(std::accumulate( + tss.begin(), tss.end(), 0U, + [](size_t acc, const std::vector<T>& ts) { return acc + ts.size(); })); + for (const auto& ts : tss) { + merged.insert(merged.end(), ts.begin(), ts.end()); + } + base::ranges::sort(merged); + merged.erase(base::ranges::unique(merged), merged.end()); + return merged; } -std::vector<blink::StorageKey> GetStorageKeysForTypeOnFileTaskRunner( - FileSystemContext* context, +// Converts StorageType to the FileSystemTypes that are used for that quota +// type. +base::span<const FileSystemType> QuotaStorageTypeToFileSystemTypes( blink::mojom::StorageType storage_type) { - FileSystemType type = - FileSystemQuotaClient::QuotaStorageTypeToFileSystemType(storage_type); - DCHECK(type != kFileSystemTypeUnknown); + using StorageType = blink::mojom::StorageType; + if (base::FeatureList::IsEnabled( + blink::features::kPersistentQuotaIsTemporaryQuota)) { + DCHECK_NE(storage_type, StorageType::kPersistent); + if (storage_type == StorageType::kTemporary) + return kTemporaryAndPersistent; + } + switch (storage_type) { + case StorageType::kTemporary: + return kTemporary; + case StorageType::kPersistent: + return kPersistent; + case StorageType::kSyncable: + return kSyncable; + case StorageType::kQuotaNotManaged: + case StorageType::kUnknown: + NOTREACHED(); + return {}; + } +} + +std::vector<blink::StorageKey> GetStorageKeysForTypeOnFileTaskRunner( + FileSystemContext* context, + FileSystemType type) { FileSystemQuotaUtil* quota_util = context->GetQuotaUtil(type); if (!quota_util) return {}; - return ToStorageKeys(quota_util->GetOriginsForTypeOnFileTaskRunner(type)); + return quota_util->GetStorageKeysForTypeOnFileTaskRunner(type); } std::vector<blink::StorageKey> GetStorageKeysForHostOnFileTaskRunner( FileSystemContext* context, - blink::mojom::StorageType storage_type, + FileSystemType type, const std::string& host) { - FileSystemType type = - FileSystemQuotaClient::QuotaStorageTypeToFileSystemType(storage_type); - DCHECK(type != kFileSystemTypeUnknown); - FileSystemQuotaUtil* quota_util = context->GetQuotaUtil(type); if (!quota_util) return {}; - return ToStorageKeys( - quota_util->GetOriginsForHostOnFileTaskRunner(type, host)); + return quota_util->GetStorageKeysForHostOnFileTaskRunner(type, host); } blink::mojom::QuotaStatusCode DeleteStorageKeyOnFileTaskRunner( @@ -71,8 +110,8 @@ blink::mojom::QuotaStatusCode DeleteStorageKeyOnFileTaskRunner( if (!provider || !provider->GetQuotaUtil()) return blink::mojom::QuotaStatusCode::kErrorNotSupported; base::File::Error result = - provider->GetQuotaUtil()->DeleteOriginDataOnFileTaskRunner( - context, context->quota_manager_proxy(), storage_key.origin(), type); + provider->GetQuotaUtil()->DeleteStorageKeyDataOnFileTaskRunner( + context, context->quota_manager_proxy(), storage_key, type); if (result == base::File::FILE_OK) return blink::mojom::QuotaStatusCode::kOk; return blink::mojom::QuotaStatusCode::kErrorInvalidModification; @@ -107,24 +146,31 @@ void FileSystemQuotaClient::GetStorageKeyUsage( DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!callback.is_null()); - FileSystemType type = - FileSystemQuotaClient::QuotaStorageTypeToFileSystemType(storage_type); - DCHECK(type != kFileSystemTypeUnknown); + base::span<const FileSystemType> types = + QuotaStorageTypeToFileSystemTypes(storage_type); - FileSystemQuotaUtil* quota_util = file_system_context_->GetQuotaUtil(type); - if (!quota_util) { - std::move(callback).Run(0); - return; - } + base::RepeatingCallback<void(int64_t)> barrier = + base::BarrierCallback<int64_t>( + types.size(), base::BindOnce([](std::vector<int64_t> usages) { + return std::accumulate(usages.begin(), usages.end(), + 0U); + }).Then(std::move(callback))); - file_task_runner()->PostTaskAndReplyWithResult( - FROM_HERE, - // It is safe to pass Unretained(quota_util) since context owns it. - base::BindOnce(&FileSystemQuotaUtil::GetOriginUsageOnFileTaskRunner, - base::Unretained(quota_util), - base::RetainedRef(file_system_context_), - storage_key.origin(), type), - std::move(callback)); + for (auto type : types) { + FileSystemQuotaUtil* quota_util = file_system_context_->GetQuotaUtil(type); + if (quota_util) { + file_task_runner()->PostTaskAndReplyWithResult( + FROM_HERE, + // It is safe to pass Unretained(quota_util) since context owns it. + base::BindOnce( + &FileSystemQuotaUtil::GetStorageKeyUsageOnFileTaskRunner, + base::Unretained(quota_util), + base::RetainedRef(file_system_context_), storage_key, type), + barrier); + } else { + barrier.Run(0); + } + } } void FileSystemQuotaClient::GetStorageKeysForType( @@ -133,11 +179,22 @@ void FileSystemQuotaClient::GetStorageKeysForType( DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!callback.is_null()); - file_task_runner()->PostTaskAndReplyWithResult( - FROM_HERE, - base::BindOnce(&GetStorageKeysForTypeOnFileTaskRunner, - base::RetainedRef(file_system_context_), storage_type), - std::move(callback)); + base::span<const FileSystemType> types = + QuotaStorageTypeToFileSystemTypes(storage_type); + + base::RepeatingCallback<void(std::vector<blink::StorageKey>)> barrier = + base::BarrierCallback<std::vector<blink::StorageKey>>( + types.size(), + base::BindOnce(&MergeWithoutDuplicates<blink::StorageKey>) + .Then(std::move(callback))); + + for (auto type : types) { + file_task_runner()->PostTaskAndReplyWithResult( + FROM_HERE, + base::BindOnce(&GetStorageKeysForTypeOnFileTaskRunner, + base::RetainedRef(file_system_context_), type), + barrier); + } } void FileSystemQuotaClient::GetStorageKeysForHost( @@ -147,12 +204,22 @@ void FileSystemQuotaClient::GetStorageKeysForHost( DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!callback.is_null()); - file_task_runner()->PostTaskAndReplyWithResult( - FROM_HERE, - base::BindOnce(&GetStorageKeysForHostOnFileTaskRunner, - base::RetainedRef(file_system_context_), storage_type, - host), - std::move(callback)); + base::span<const FileSystemType> types = + QuotaStorageTypeToFileSystemTypes(storage_type); + + base::RepeatingCallback<void(std::vector<blink::StorageKey>)> barrier = + base::BarrierCallback<std::vector<blink::StorageKey>>( + types.size(), + base::BindOnce(&MergeWithoutDuplicates<blink::StorageKey>) + .Then(std::move(callback))); + + for (auto type : types) { + file_task_runner()->PostTaskAndReplyWithResult( + FROM_HERE, + base::BindOnce(&GetStorageKeysForHostOnFileTaskRunner, + base::RetainedRef(file_system_context_), type, host), + barrier); + } } void FileSystemQuotaClient::DeleteStorageKeyData( @@ -162,15 +229,29 @@ void FileSystemQuotaClient::DeleteStorageKeyData( DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!callback.is_null()); - FileSystemType fs_type = QuotaStorageTypeToFileSystemType(type); - DCHECK(fs_type != kFileSystemTypeUnknown); + base::span<const FileSystemType> fs_types = + QuotaStorageTypeToFileSystemTypes(type); + + base::RepeatingCallback<void(blink::mojom::QuotaStatusCode)> barrier = + base::BarrierCallback<blink::mojom::QuotaStatusCode>( + fs_types.size(), + base::BindOnce([](const std::vector<blink::mojom::QuotaStatusCode>& + statuses) { + for (auto status : statuses) { + if (status != blink::mojom::QuotaStatusCode::kOk) + return status; + } + return blink::mojom::QuotaStatusCode::kOk; + }).Then(std::move(callback))); - file_task_runner()->PostTaskAndReplyWithResult( - FROM_HERE, - base::BindOnce(&DeleteStorageKeyOnFileTaskRunner, - base::RetainedRef(file_system_context_), storage_key, - fs_type), - std::move(callback)); + for (const auto fs_type : fs_types) { + file_task_runner()->PostTaskAndReplyWithResult( + FROM_HERE, + base::BindOnce(&DeleteStorageKeyOnFileTaskRunner, + base::RetainedRef(file_system_context_), storage_key, + fs_type), + barrier); + } } void FileSystemQuotaClient::PerformStorageCleanup( @@ -179,30 +260,19 @@ void FileSystemQuotaClient::PerformStorageCleanup( DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!callback.is_null()); - FileSystemType fs_type = QuotaStorageTypeToFileSystemType(type); - DCHECK(fs_type != kFileSystemTypeUnknown); - file_task_runner()->PostTaskAndReply( - FROM_HERE, - base::BindOnce(&PerformStorageCleanupOnFileTaskRunner, - base::RetainedRef(file_system_context_), fs_type), - std::move(callback)); -} + base::span<const FileSystemType> fs_types = + QuotaStorageTypeToFileSystemTypes(type); -// static -FileSystemType FileSystemQuotaClient::QuotaStorageTypeToFileSystemType( - blink::mojom::StorageType storage_type) { - switch (storage_type) { - case blink::mojom::StorageType::kTemporary: - return kFileSystemTypeTemporary; - case blink::mojom::StorageType::kPersistent: - return kFileSystemTypePersistent; - case blink::mojom::StorageType::kSyncable: - return kFileSystemTypeSyncable; - case blink::mojom::StorageType::kQuotaNotManaged: - case blink::mojom::StorageType::kUnknown: - return kFileSystemTypeUnknown; + base::RepeatingClosure barrier = + base::BarrierClosure(fs_types.size(), std::move(callback)); + + for (auto fs_type : fs_types) { + file_task_runner()->PostTaskAndReply( + FROM_HERE, + base::BindOnce(&PerformStorageCleanupOnFileTaskRunner, + base::RetainedRef(file_system_context_), fs_type), + barrier); } - return kFileSystemTypeUnknown; } base::SequencedTaskRunner* FileSystemQuotaClient::file_task_runner() const { 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 fee07e696b2..f686c0ee10e 100644 --- a/chromium/storage/browser/file_system/file_system_quota_client.h +++ b/chromium/storage/browser/file_system/file_system_quota_client.h @@ -55,14 +55,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemQuotaClient void PerformStorageCleanup(blink::mojom::StorageType type, PerformStorageCleanupCallback callback) override; - // Converts FileSystemType `type` to/from the StorageType `storage_type` that - // is used for the unified quota system. - // (Basically this naively maps TEMPORARY storage type to TEMPORARY filesystem - // type, PERSISTENT storage type to PERSISTENT filesystem type and vice - // versa.) - static FileSystemType QuotaStorageTypeToFileSystemType( - blink::mojom::StorageType storage_type); - private: base::SequencedTaskRunner* file_task_runner() const; diff --git a/chromium/storage/browser/file_system/file_system_quota_client_unittest.cc b/chromium/storage/browser/file_system/file_system_quota_client_unittest.cc index cb8bdfd5088..e5c2086ce43 100644 --- a/chromium/storage/browser/file_system/file_system_quota_client_unittest.cc +++ b/chromium/storage/browser/file_system/file_system_quota_client_unittest.cc @@ -13,6 +13,7 @@ #include "base/files/scoped_temp_dir.h" #include "base/macros.h" #include "base/run_loop.h" +#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "components/services/storage/public/mojom/quota_client.mojom.h" #include "storage/browser/file_system/file_system_context.h" @@ -27,6 +28,7 @@ #include "storage/common/file_system/file_system_util.h" #include "testing/gmock/include/gmock/gmock-matchers.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/blink/public/mojom/quota/quota_types.mojom.h" #include "url/gurl.h" @@ -48,17 +50,26 @@ const StorageType kPersistent = StorageType::kPersistent; } // namespace -class FileSystemQuotaClientTest : public testing::Test { +class FileSystemQuotaClientTest : public testing::TestWithParam<bool> { public: FileSystemQuotaClientTest() = default; ~FileSystemQuotaClientTest() override = default; void SetUp() override { + if (persistent_quota_is_temporary_quota()) { + feature_list_.InitAndEnableFeature( + blink::features::kPersistentQuotaIsTemporaryQuota); + } else { + feature_list_.InitAndDisableFeature( + blink::features::kPersistentQuotaIsTemporaryQuota); + } ASSERT_TRUE(data_dir_.CreateUniqueTempDir()); file_system_context_ = CreateFileSystemContextForTesting( /*quota_manager_proxy=*/nullptr, data_dir_.GetPath()); } + bool persistent_quota_is_temporary_quota() const { return GetParam(); } + struct TestFile { bool isDirectory; const char* name; @@ -169,9 +180,8 @@ class FileSystemQuotaClientTest : public testing::Test { // create it later, this will fail due to a quota mismatch. If we // call this before we create the root, it succeeds, but hasn't // actually created the cache. - ASSERT_EQ(0, GetStorageKeyUsage( - quota_client, file.origin_url, - FileSystemTypeToQuotaStorageType(file.type))); + GetStorageKeyUsage(quota_client, file.origin_url, + FileSystemTypeToQuotaStorageType(file.type)); } } else { ASSERT_TRUE( @@ -232,6 +242,7 @@ class FileSystemQuotaClientTest : public testing::Test { deletion_status_ = status; } + base::test::ScopedFeatureList feature_list_; base::ScopedTempDir data_dir_; base::test::TaskEnvironment task_environment_; scoped_refptr<FileSystemContext> file_system_context_; @@ -243,13 +254,13 @@ class FileSystemQuotaClientTest : public testing::Test { base::WeakPtrFactory<FileSystemQuotaClientTest> weak_factory_{this}; }; -TEST_F(FileSystemQuotaClientTest, NoFileSystemTest) { +TEST_P(FileSystemQuotaClientTest, NoFileSystemTest) { FileSystemQuotaClient quota_client(GetFileSystemContext()); EXPECT_EQ(0, GetStorageKeyUsage(quota_client, kDummyURL1, kTemporary)); } -TEST_F(FileSystemQuotaClientTest, NoFileTest) { +TEST_P(FileSystemQuotaClientTest, NoFileTest) { FileSystemQuotaClient quota_client(GetFileSystemContext()); InitializeOriginFiles(quota_client, @@ -260,7 +271,7 @@ TEST_F(FileSystemQuotaClientTest, NoFileTest) { } } -TEST_F(FileSystemQuotaClientTest, OneFileTest) { +TEST_P(FileSystemQuotaClientTest, OneFileTest) { FileSystemQuotaClient quota_client(GetFileSystemContext()); const std::vector<TestFile> kFiles = { {true, "", 0, kDummyURL1, kFileSystemTypeTemporary}, @@ -276,7 +287,7 @@ TEST_F(FileSystemQuotaClientTest, OneFileTest) { } } -TEST_F(FileSystemQuotaClientTest, TwoFilesTest) { +TEST_P(FileSystemQuotaClientTest, TwoFilesTest) { FileSystemQuotaClient quota_client(GetFileSystemContext()); const std::vector<TestFile> kFiles = { {true, "", 0, kDummyURL1, kFileSystemTypeTemporary}, @@ -293,7 +304,7 @@ TEST_F(FileSystemQuotaClientTest, TwoFilesTest) { } } -TEST_F(FileSystemQuotaClientTest, EmptyFilesTest) { +TEST_P(FileSystemQuotaClientTest, EmptyFilesTest) { FileSystemQuotaClient quota_client(GetFileSystemContext()); const std::vector<TestFile> kFiles = { {true, "", 0, kDummyURL1, kFileSystemTypeTemporary}, @@ -311,7 +322,7 @@ TEST_F(FileSystemQuotaClientTest, EmptyFilesTest) { } } -TEST_F(FileSystemQuotaClientTest, SubDirectoryTest) { +TEST_P(FileSystemQuotaClientTest, SubDirectoryTest) { FileSystemQuotaClient quota_client(GetFileSystemContext()); const std::vector<TestFile> kFiles = { {true, "", 0, kDummyURL1, kFileSystemTypeTemporary}, @@ -329,7 +340,7 @@ TEST_F(FileSystemQuotaClientTest, SubDirectoryTest) { } } -TEST_F(FileSystemQuotaClientTest, MultiTypeTest) { +TEST_P(FileSystemQuotaClientTest, MultiTypeTest) { FileSystemQuotaClient quota_client(GetFileSystemContext()); const std::vector<TestFile> kFiles = { {true, "", 0, kDummyURL1, kFileSystemTypeTemporary}, @@ -350,14 +361,20 @@ TEST_F(FileSystemQuotaClientTest, MultiTypeTest) { kFileSystemTypePersistent); for (int i = 0; i < 2; i++) { - EXPECT_EQ(133 + 14 + file_paths_cost_temporary, - GetStorageKeyUsage(quota_client, kDummyURL1, kTemporary)); - EXPECT_EQ(193 + 9 + file_paths_cost_persistent, - GetStorageKeyUsage(quota_client, kDummyURL1, kPersistent)); + if (persistent_quota_is_temporary_quota()) { + EXPECT_EQ(133 + 14 + file_paths_cost_temporary + 193 + 9 + + file_paths_cost_persistent, + GetStorageKeyUsage(quota_client, kDummyURL1, kTemporary)); + } else { + EXPECT_EQ(133 + 14 + file_paths_cost_temporary, + GetStorageKeyUsage(quota_client, kDummyURL1, kTemporary)); + EXPECT_EQ(193 + 9 + file_paths_cost_persistent, + GetStorageKeyUsage(quota_client, kDummyURL1, kPersistent)); + } } } -TEST_F(FileSystemQuotaClientTest, MultiDomainTest) { +TEST_P(FileSystemQuotaClientTest, MultiDomainTest) { FileSystemQuotaClient quota_client(GetFileSystemContext()); const std::vector<TestFile> kFiles = { {true, "", 0, kDummyURL1, kFileSystemTypeTemporary}, @@ -392,18 +409,27 @@ TEST_F(FileSystemQuotaClientTest, MultiDomainTest) { kFileSystemTypePersistent); for (int i = 0; i < 2; i++) { - EXPECT_EQ(1331 + 134 + file_paths_cost_temporary1, - GetStorageKeyUsage(quota_client, kDummyURL1, kTemporary)); - EXPECT_EQ(1903 + 19 + file_paths_cost_persistent1, - GetStorageKeyUsage(quota_client, kDummyURL1, kPersistent)); - EXPECT_EQ(1319 + 113 + file_paths_cost_temporary2, - GetStorageKeyUsage(quota_client, kDummyURL2, kTemporary)); - EXPECT_EQ(2013 + 18 + file_paths_cost_persistent2, - GetStorageKeyUsage(quota_client, kDummyURL2, kPersistent)); + if (persistent_quota_is_temporary_quota()) { + EXPECT_EQ(1331 + 134 + file_paths_cost_temporary1 + 1903 + 19 + + file_paths_cost_persistent1, + GetStorageKeyUsage(quota_client, kDummyURL1, kTemporary)); + EXPECT_EQ(1319 + 113 + file_paths_cost_temporary2 + 2013 + 18 + + file_paths_cost_persistent2, + GetStorageKeyUsage(quota_client, kDummyURL2, kTemporary)); + } else { + EXPECT_EQ(1331 + 134 + file_paths_cost_temporary1, + GetStorageKeyUsage(quota_client, kDummyURL1, kTemporary)); + EXPECT_EQ(1903 + 19 + file_paths_cost_persistent1, + GetStorageKeyUsage(quota_client, kDummyURL1, kPersistent)); + EXPECT_EQ(1319 + 113 + file_paths_cost_temporary2, + GetStorageKeyUsage(quota_client, kDummyURL2, kTemporary)); + EXPECT_EQ(2013 + 18 + file_paths_cost_persistent2, + GetStorageKeyUsage(quota_client, kDummyURL2, kPersistent)); + } } } -TEST_F(FileSystemQuotaClientTest, GetUsage_MultipleTasks) { +TEST_P(FileSystemQuotaClientTest, GetUsage_MultipleTasks) { FileSystemQuotaClient quota_client(GetFileSystemContext()); const std::vector<TestFile> kFiles = { {true, "", 0, kDummyURL1, kFileSystemTypeTemporary}, @@ -433,7 +459,7 @@ TEST_F(FileSystemQuotaClientTest, GetUsage_MultipleTasks) { EXPECT_EQ(2, additional_callback_count()); } -TEST_F(FileSystemQuotaClientTest, GetStorageKeysForType) { +TEST_P(FileSystemQuotaClientTest, GetStorageKeysForType) { FileSystemQuotaClient quota_client(GetFileSystemContext()); InitializeOriginFiles( quota_client, { @@ -442,13 +468,21 @@ TEST_F(FileSystemQuotaClientTest, GetStorageKeysForType) { {true, "", 0, kDummyURL3, kFileSystemTypePersistent}, }); - EXPECT_THAT(GetStorageKeysForType(quota_client, kTemporary), - testing::UnorderedElementsAre( - StorageKey::CreateFromStringForTesting(kDummyURL1), - StorageKey::CreateFromStringForTesting(kDummyURL2))); + if (persistent_quota_is_temporary_quota()) { + EXPECT_THAT(GetStorageKeysForType(quota_client, kTemporary), + testing::UnorderedElementsAre( + StorageKey::CreateFromStringForTesting(kDummyURL1), + StorageKey::CreateFromStringForTesting(kDummyURL2), + StorageKey::CreateFromStringForTesting(kDummyURL3))); + } else { + EXPECT_THAT(GetStorageKeysForType(quota_client, kTemporary), + testing::UnorderedElementsAre( + StorageKey::CreateFromStringForTesting(kDummyURL1), + StorageKey::CreateFromStringForTesting(kDummyURL2))); + } } -TEST_F(FileSystemQuotaClientTest, GetStorageKeysForHost) { +TEST_P(FileSystemQuotaClientTest, GetStorageKeysForHost) { FileSystemQuotaClient quota_client(GetFileSystemContext()); const char* kURL1 = "http://foo.com/"; const char* kURL2 = "https://foo.com/"; @@ -464,14 +498,23 @@ TEST_F(FileSystemQuotaClientTest, GetStorageKeysForHost) { {true, "", 0, kURL5, kFileSystemTypePersistent}, }); - EXPECT_THAT(GetStorageKeysForHost(quota_client, kTemporary, "foo.com"), - testing::UnorderedElementsAre( - StorageKey::CreateFromStringForTesting(kURL1), - StorageKey::CreateFromStringForTesting(kURL2), - StorageKey::CreateFromStringForTesting(kURL3))); + if (persistent_quota_is_temporary_quota()) { + EXPECT_THAT(GetStorageKeysForHost(quota_client, kTemporary, "foo.com"), + testing::UnorderedElementsAre( + StorageKey::CreateFromStringForTesting(kURL1), + StorageKey::CreateFromStringForTesting(kURL2), + StorageKey::CreateFromStringForTesting(kURL3), + StorageKey::CreateFromStringForTesting(kURL5))); + } else { + EXPECT_THAT(GetStorageKeysForHost(quota_client, kTemporary, "foo.com"), + testing::UnorderedElementsAre( + StorageKey::CreateFromStringForTesting(kURL1), + StorageKey::CreateFromStringForTesting(kURL2), + StorageKey::CreateFromStringForTesting(kURL3))); + } } -TEST_F(FileSystemQuotaClientTest, DeleteOriginTest) { +TEST_P(FileSystemQuotaClientTest, DeleteOriginTest) { FileSystemQuotaClient quota_client(GetFileSystemContext()); const std::vector<TestFile> kFiles = { {true, "", 0, "http://foo.com/", kFileSystemTypeTemporary}, @@ -499,6 +542,9 @@ TEST_F(FileSystemQuotaClientTest, DeleteOriginTest) { const int64_t file_paths_cost_temporary_bar = ComputeFilePathsCostForOriginAndType(kFiles, "http://bar.com/", kFileSystemTypeTemporary); + const int64_t file_paths_cost_persistent_bar = + ComputeFilePathsCostForOriginAndType(kFiles, "http://bar.com/", + kFileSystemTypePersistent); const int64_t file_paths_cost_temporary_bar_https = ComputeFilePathsCostForOriginAndType(kFiles, "https://bar.com/", kFileSystemTypeTemporary); @@ -510,29 +556,44 @@ TEST_F(FileSystemQuotaClientTest, DeleteOriginTest) { base::RunLoop().RunUntilIdle(); EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk, status()); - DeleteStorageKeyData("a_client, "http://bar.com/", kPersistent); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk, status()); + if (!persistent_quota_is_temporary_quota()) { + DeleteStorageKeyData("a_client, "http://bar.com/", kPersistent); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk, status()); + } DeleteStorageKeyData("a_client, "http://buz.com/", kTemporary); base::RunLoop().RunUntilIdle(); EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk, status()); EXPECT_EQ(0, GetStorageKeyUsage(quota_client, "http://foo.com/", kTemporary)); - EXPECT_EQ(0, - GetStorageKeyUsage(quota_client, "http://bar.com/", kPersistent)); EXPECT_EQ(0, GetStorageKeyUsage(quota_client, "http://buz.com/", kTemporary)); - EXPECT_EQ(2 + file_paths_cost_temporary_foo_https, GetStorageKeyUsage(quota_client, "https://foo.com/", kTemporary)); - EXPECT_EQ(4 + file_paths_cost_persistent_foo, - GetStorageKeyUsage(quota_client, "http://foo.com/", kPersistent)); - EXPECT_EQ(8 + file_paths_cost_temporary_bar, + EXPECT_EQ(8 + file_paths_cost_temporary_bar + + (persistent_quota_is_temporary_quota() + ? 16 + file_paths_cost_persistent_bar + : 0), GetStorageKeyUsage(quota_client, "http://bar.com/", kTemporary)); - EXPECT_EQ(32 + file_paths_cost_persistent_bar_https, - GetStorageKeyUsage(quota_client, "https://bar.com/", kPersistent)); - EXPECT_EQ(64 + file_paths_cost_temporary_bar_https, + EXPECT_EQ(64 + file_paths_cost_temporary_bar_https + + (persistent_quota_is_temporary_quota() + ? 32 + file_paths_cost_persistent_bar_https + : 0), GetStorageKeyUsage(quota_client, "https://bar.com/", kTemporary)); + + if (!persistent_quota_is_temporary_quota()) { + EXPECT_EQ(0, + GetStorageKeyUsage(quota_client, "http://bar.com/", kPersistent)); + EXPECT_EQ(4 + file_paths_cost_persistent_foo, + GetStorageKeyUsage(quota_client, "http://foo.com/", kPersistent)); + EXPECT_EQ( + 32 + file_paths_cost_persistent_bar_https, + GetStorageKeyUsage(quota_client, "https://bar.com/", kPersistent)); + } } +INSTANTIATE_TEST_SUITE_P(FileSystemQuotaClientTests, + FileSystemQuotaClientTest, + testing::Bool()); + } // namespace storage diff --git a/chromium/storage/browser/file_system/file_system_quota_util.h b/chromium/storage/browser/file_system/file_system_quota_util.h index bc97e79cda3..d329f63de74 100644 --- a/chromium/storage/browser/file_system/file_system_quota_util.h +++ b/chromium/storage/browser/file_system/file_system_quota_util.h @@ -15,9 +15,9 @@ #include "base/memory/scoped_refptr.h" #include "storage/common/file_system/file_system_types.h" -namespace url { -class Origin; -} +namespace blink { +class StorageKey; +} // namespace blink namespace storage { @@ -35,32 +35,32 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemQuotaUtil { // Deletes the data on the origin and reports the amount of deleted data // to the quota manager via |proxy|. - virtual base::File::Error DeleteOriginDataOnFileTaskRunner( + virtual base::File::Error DeleteStorageKeyDataOnFileTaskRunner( FileSystemContext* context, QuotaManagerProxy* proxy, - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type) = 0; virtual void PerformStorageCleanupOnFileTaskRunner(FileSystemContext* context, QuotaManagerProxy* proxy, FileSystemType type) = 0; - virtual std::vector<url::Origin> GetOriginsForTypeOnFileTaskRunner( + virtual std::vector<blink::StorageKey> GetStorageKeysForTypeOnFileTaskRunner( FileSystemType type) = 0; - virtual std::vector<url::Origin> GetOriginsForHostOnFileTaskRunner( + virtual std::vector<blink::StorageKey> GetStorageKeysForHostOnFileTaskRunner( FileSystemType type, const std::string& host) = 0; - // Returns the amount of data used for the origin for usage tracking. - virtual int64_t GetOriginUsageOnFileTaskRunner( + // Returns the amount of data used for the `storage_key` for usage tracking. + virtual int64_t GetStorageKeyUsageOnFileTaskRunner( FileSystemContext* file_system_context, - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type) = 0; - // Creates new reservation object for the origin and the type. + // Creates new reservation object for the `storage_key` and the `type`. virtual scoped_refptr<QuotaReservation> - CreateQuotaReservationOnFileTaskRunner(const url::Origin& origin, + CreateQuotaReservationOnFileTaskRunner(const blink::StorageKey& storage_key, FileSystemType type) = 0; }; diff --git a/chromium/storage/browser/file_system/file_system_url.cc b/chromium/storage/browser/file_system/file_system_url.cc index a7eb2331c5c..57bfad03653 100644 --- a/chromium/storage/browser/file_system/file_system_url.cc +++ b/chromium/storage/browser/file_system/file_system_url.cc @@ -9,6 +9,7 @@ #include "base/check.h" #include "base/strings/string_util.h" #include "net/base/escape.h" +#include "storage/common/file_system/file_system_types.h" #include "storage/common/file_system/file_system_util.h" #include "third_party/blink/public/common/storage_key/storage_key.h" #include "url/origin.h" @@ -134,7 +135,20 @@ std::string FileSystemURL::DebugString() const { if (!is_valid_) return "invalid filesystem: URL"; std::ostringstream ss; - ss << GetFileSystemRootURI(storage_key_.origin().GetURL(), mount_type_); + switch (mount_type_) { + // Include GURL if GURL serialization is possible. + case kFileSystemTypeTemporary: + case kFileSystemTypePersistent: + case kFileSystemTypeExternal: + case kFileSystemTypeIsolated: + case kFileSystemTypeTest: + ss << "{ uri: "; + ss << GetFileSystemRootURI(storage_key_.origin().GetURL(), mount_type_); + break; + // Otherwise list the origin and path separately. + default: + ss << "{ path: "; + } // filesystem_id_ will be non empty for (and only for) cracked URLs. if (!filesystem_id_.empty()) { @@ -146,6 +160,8 @@ std::string FileSystemURL::DebugString() const { } else { ss << path_.value(); } + ss << ", storage key: " << storage_key_.GetDebugString(); + ss << " }"; return ss.str(); } diff --git a/chromium/storage/browser/file_system/file_system_url_unittest.cc b/chromium/storage/browser/file_system/file_system_url_unittest.cc index 71f21789163..722f8b16437 100644 --- a/chromium/storage/browser/file_system/file_system_url_unittest.cc +++ b/chromium/storage/browser/file_system/file_system_url_unittest.cc @@ -188,9 +188,16 @@ TEST(FileSystemURLTest, DebugString) { const FileSystemURL kURL1 = FileSystemURL::CreateForTest( blink::StorageKey::CreateFromStringForTesting("http://example.com"), kFileSystemTypeTemporary, kPath); - EXPECT_EQ( - "filesystem:http://example.com/temporary/" + NormalizedUTF8Path(kPath), - kURL1.DebugString()); + EXPECT_EQ("{ uri: filesystem:http://example.com/temporary/" + + NormalizedUTF8Path(kPath) + + ", storage key: " + kURL1.storage_key().GetDebugString() + " }", + kURL1.DebugString()); + const FileSystemURL kURL2 = FileSystemURL::CreateForTest( + blink::StorageKey::CreateFromStringForTesting("http://example.com"), + kFileSystemTypeLocal, kPath); + EXPECT_EQ("{ path: " + NormalizedUTF8Path(kPath) + + ", storage key: " + kURL1.storage_key().GetDebugString() + " }", + kURL2.DebugString()); } TEST(FileSystemURLTest, IsInSameFileSystem) { 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 61e411493e9..5b165353f01 100644 --- a/chromium/storage/browser/file_system/file_system_usage_cache.cc +++ b/chromium/storage/browser/file_system/file_system_usage_cache.cc @@ -20,7 +20,7 @@ namespace storage { namespace { -constexpr base::TimeDelta kCloseDelay = base::TimeDelta::FromSeconds(5); +constexpr base::TimeDelta kCloseDelay = base::Seconds(5); const size_t kMaxHandleCacheSize = 2; } // namespace 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 a0ef4c1b7ad..d19a4142e4f 100644 --- a/chromium/storage/browser/file_system/file_system_usage_cache.h +++ b/chromium/storage/browser/file_system/file_system_usage_cache.h @@ -22,6 +22,10 @@ namespace storage { class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemUsageCache { public: FileSystemUsageCache(bool is_incognito); + + FileSystemUsageCache(const FileSystemUsageCache&) = delete; + FileSystemUsageCache& operator=(const FileSystemUsageCache&) = delete; + ~FileSystemUsageCache(); // Gets the size described in the .usage file even if dirty > 0 or @@ -99,8 +103,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemUsageCache { std::map<base::FilePath, std::vector<uint8_t>> incognito_usages_; std::map<base::FilePath, std::unique_ptr<base::File>> cache_files_; - - DISALLOW_COPY_AND_ASSIGN(FileSystemUsageCache); }; } // namespace storage diff --git a/chromium/storage/browser/file_system/file_system_util.cc b/chromium/storage/browser/file_system/file_system_util.cc index 95b190f68b3..a32a53f2676 100644 --- a/chromium/storage/browser/file_system/file_system_util.cc +++ b/chromium/storage/browser/file_system/file_system_util.cc @@ -4,13 +4,20 @@ #include "storage/browser/file_system/file_system_util.h" +#include "base/feature_list.h" #include "storage/common/file_system/file_system_types.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/mojom/quota/quota_types.mojom.h" namespace storage { blink::mojom::StorageType FileSystemTypeToQuotaStorageType( FileSystemType type) { + if (base::FeatureList::IsEnabled( + blink::features::kPersistentQuotaIsTemporaryQuota) && + (type == kFileSystemTypeTemporary || type == kFileSystemTypePersistent)) { + return blink::mojom::StorageType::kTemporary; + } switch (type) { case kFileSystemTypeTemporary: return blink::mojom::StorageType::kTemporary; diff --git a/chromium/storage/browser/file_system/file_writer_delegate.h b/chromium/storage/browser/file_system/file_writer_delegate.h index 70626b3f55e..d8fa5514e32 100644 --- a/chromium/storage/browser/file_system/file_writer_delegate.h +++ b/chromium/storage/browser/file_system/file_writer_delegate.h @@ -41,6 +41,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileWriterDelegate { FileWriterDelegate(std::unique_ptr<FileStreamWriter> file_writer, FlushPolicy flush_policy); + + FileWriterDelegate(const FileWriterDelegate&) = delete; + FileWriterDelegate& operator=(const FileWriterDelegate&) = delete; + virtual ~FileWriterDelegate(); void Start(std::unique_ptr<BlobReader> blob_reader, @@ -102,8 +106,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileWriterDelegate { mojo::SimpleWatcher data_pipe_watcher_; base::WeakPtrFactory<FileWriterDelegate> weak_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(FileWriterDelegate); }; } // namespace storage diff --git a/chromium/storage/browser/file_system/file_writer_delegate_unittest.cc b/chromium/storage/browser/file_system/file_writer_delegate_unittest.cc index 116317b8a10..7dbd161cd7b 100644 --- a/chromium/storage/browser/file_system/file_writer_delegate_unittest.cc +++ b/chromium/storage/browser/file_system/file_writer_delegate_unittest.cc @@ -100,9 +100,10 @@ class FileWriterDelegateTest : public PlatformTest { int64_t usage() { return file_system_context_->GetQuotaUtil(kFileSystemType) - ->GetOriginUsageOnFileTaskRunner(file_system_context_.get(), - url::Origin::Create(GURL(kOrigin)), - kFileSystemType); + ->GetStorageKeyUsageOnFileTaskRunner( + file_system_context_.get(), + blink::StorageKey::CreateFromStringForTesting(kOrigin), + kFileSystemType); } int64_t GetFileSizeOnDisk(const char* test_file_path) { diff --git a/chromium/storage/browser/file_system/isolated_context.cc b/chromium/storage/browser/file_system/isolated_context.cc index c6ba0a167b4..2871e1c6247 100644 --- a/chromium/storage/browser/file_system/isolated_context.cc +++ b/chromium/storage/browser/file_system/isolated_context.cc @@ -19,6 +19,8 @@ #include "storage/browser/file_system/file_system_url.h" #include "third_party/blink/public/common/storage_key/storage_key.h" +class GURL; + namespace storage { namespace { @@ -162,6 +164,9 @@ class IsolatedContext::Instance { // could be registered by IsolatedContext::RegisterDraggedFileSystem(). Instance(FileSystemType type, const std::set<MountPointInfo>& files); + Instance(const Instance&) = delete; + Instance& operator=(const Instance&) = delete; + ~Instance(); FileSystemType type() const { return type_; } @@ -192,8 +197,6 @@ class IsolatedContext::Instance { // Reference counts. Note that an isolated filesystem is created with ref==0 // and will get deleted when the ref count reaches <=0. int ref_counts_; - - DISALLOW_COPY_AND_ASSIGN(Instance); }; IsolatedContext::Instance::Instance(FileSystemType type, @@ -389,24 +392,22 @@ bool IsolatedContext::CrackVirtualPath( return true; } -// TODO(https://crbug.com/1221308): creating StorageKey from url is -// temporary; StorageKey will be added in future CL -FileSystemURL IsolatedContext::CrackURL(const GURL& url) const { - FileSystemURL filesystem_url = - FileSystemURL(url, blink::StorageKey(url::Origin::Create(url))); +FileSystemURL IsolatedContext::CrackURL( + const GURL& url, + const blink::StorageKey& storage_key) const { + FileSystemURL filesystem_url = FileSystemURL(url, storage_key); if (!filesystem_url.is_valid()) return FileSystemURL(); return CrackFileSystemURL(filesystem_url); } FileSystemURL IsolatedContext::CreateCrackedFileSystemURL( - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type, const base::FilePath& virtual_path) const { // TODO(https://crbug.com/1221308): function will have StorageKey param in // future CL; conversion from url::Origin is temporary - return CrackFileSystemURL( - FileSystemURL(blink::StorageKey(origin), type, virtual_path)); + return CrackFileSystemURL(FileSystemURL(storage_key, type, virtual_path)); } void IsolatedContext::RevokeFileSystemByPath(const base::FilePath& path_in) { diff --git a/chromium/storage/browser/file_system/isolated_context.h b/chromium/storage/browser/file_system/isolated_context.h index c70f51d37f8..1271f4a947d 100644 --- a/chromium/storage/browser/file_system/isolated_context.h +++ b/chromium/storage/browser/file_system/isolated_context.h @@ -19,12 +19,16 @@ #include "storage/browser/file_system/mount_points.h" #include "storage/common/file_system/file_system_types.h" -namespace storage { -class FileSystemURL; -} +class GURL; + +namespace blink { +class StorageKey; +} // namespace blink namespace storage { +class FileSystemURL; + // Manages isolated filesystem mount points which have no well-known names // and are identified by a string 'filesystem ID', which usually just looks // like random value. @@ -173,9 +177,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) IsolatedContext : public MountPoints { std::string* cracked_id, base::FilePath* path, FileSystemMountOption* mount_option) const override; - FileSystemURL CrackURL(const GURL& url) const override; + FileSystemURL CrackURL(const GURL& url, + const blink::StorageKey& storage_key) const override; FileSystemURL CreateCrackedFileSystemURL( - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type, const base::FilePath& virtual_path) const override; diff --git a/chromium/storage/browser/file_system/isolated_context_unittest.cc b/chromium/storage/browser/file_system/isolated_context_unittest.cc index 8c514f11d97..a68becfb97d 100644 --- a/chromium/storage/browser/file_system/isolated_context_unittest.cc +++ b/chromium/storage/browser/file_system/isolated_context_unittest.cc @@ -11,6 +11,7 @@ #include "storage/browser/file_system/file_system_url.h" #include "storage/browser/file_system/isolated_context.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/storage_key/storage_key.h" #define FPL(x) FILE_PATH_LITERAL(x) @@ -254,7 +255,7 @@ TEST_F(IsolatedContextTest, CrackURLWithRelativePaths) { .Append(relatives[j].path); FileSystemURL cracked = isolated_context()->CreateCrackedFileSystemURL( - url::Origin::Create(GURL("http://chromium.org")), + blink::StorageKey::CreateFromStringForTesting("http://chromium.org"), kFileSystemTypeIsolated, virtual_path); ASSERT_EQ(relatives[j].valid, cracked.is_valid()); diff --git a/chromium/storage/browser/file_system/isolated_file_system_backend.cc b/chromium/storage/browser/file_system/isolated_file_system_backend.cc index 49e2e3dca7a..ad82ddbb82d 100644 --- a/chromium/storage/browser/file_system/isolated_file_system_backend.cc +++ b/chromium/storage/browser/file_system/isolated_file_system_backend.cc @@ -102,7 +102,8 @@ IsolatedFileSystemBackend::GetCopyOrMoveFileValidatorFactory( return nullptr; } -FileSystemOperation* IsolatedFileSystemBackend::CreateFileSystemOperation( +std::unique_ptr<FileSystemOperation> +IsolatedFileSystemBackend::CreateFileSystemOperation( const FileSystemURL& url, FileSystemContext* context, base::File::Error* error_code) const { diff --git a/chromium/storage/browser/file_system/isolated_file_system_backend.h b/chromium/storage/browser/file_system/isolated_file_system_backend.h index 9befd377e9f..a5061e347b6 100644 --- a/chromium/storage/browser/file_system/isolated_file_system_backend.h +++ b/chromium/storage/browser/file_system/isolated_file_system_backend.h @@ -33,7 +33,7 @@ class IsolatedFileSystemBackend : public FileSystemBackend { CopyOrMoveFileValidatorFactory* GetCopyOrMoveFileValidatorFactory( FileSystemType type, base::File::Error* error_code) override; - FileSystemOperation* CreateFileSystemOperation( + std::unique_ptr<FileSystemOperation> CreateFileSystemOperation( const FileSystemURL& url, FileSystemContext* context, base::File::Error* error_code) const override; diff --git a/chromium/storage/browser/file_system/local_file_stream_writer.h b/chromium/storage/browser/file_system/local_file_stream_writer.h index ed51d9c4fb7..dc47e710ea3 100644 --- a/chromium/storage/browser/file_system/local_file_stream_writer.h +++ b/chromium/storage/browser/file_system/local_file_stream_writer.h @@ -29,6 +29,9 @@ namespace storage { class COMPONENT_EXPORT(STORAGE_BROWSER) LocalFileStreamWriter : public FileStreamWriter { public: + LocalFileStreamWriter(const LocalFileStreamWriter&) = delete; + LocalFileStreamWriter& operator=(const LocalFileStreamWriter&) = delete; + ~LocalFileStreamWriter() override; // FileStreamWriter overrides. @@ -85,7 +88,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) LocalFileStreamWriter net::CompletionOnceCallback cancel_callback_; base::WeakPtrFactory<LocalFileStreamWriter> weak_factory_{this}; - DISALLOW_COPY_AND_ASSIGN(LocalFileStreamWriter); }; } // namespace storage diff --git a/chromium/storage/browser/file_system/local_file_util.h b/chromium/storage/browser/file_system/local_file_util.h index 4250d25040d..14506422802 100644 --- a/chromium/storage/browser/file_system/local_file_util.h +++ b/chromium/storage/browser/file_system/local_file_util.h @@ -29,6 +29,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) LocalFileUtil : public FileSystemFileUtil { public: LocalFileUtil(); + + LocalFileUtil(const LocalFileUtil&) = delete; + LocalFileUtil& operator=(const LocalFileUtil&) = delete; + ~LocalFileUtil() override; base::File CreateOrOpen(FileSystemOperationContext* context, @@ -89,8 +93,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) LocalFileUtil private: class LocalFileEnumerator; - - DISALLOW_COPY_AND_ASSIGN(LocalFileUtil); }; } // namespace storage diff --git a/chromium/storage/browser/file_system/local_file_util_unittest.cc b/chromium/storage/browser/file_system/local_file_util_unittest.cc index 669f4b6e135..76a8cda48c1 100644 --- a/chromium/storage/browser/file_system/local_file_util_unittest.cc +++ b/chromium/storage/browser/file_system/local_file_util_unittest.cc @@ -184,10 +184,8 @@ TEST_F(LocalFileUtilTest, TouchFile) { base::File::Info info; ASSERT_TRUE(base::GetFileInfo(LocalPath(file_name), &info)); - const base::Time new_accessed = - info.last_accessed + base::TimeDelta::FromHours(10); - const base::Time new_modified = - info.last_modified + base::TimeDelta::FromHours(5); + const base::Time new_accessed = info.last_accessed + base::Hours(10); + const base::Time new_modified = info.last_modified + base::Hours(5); EXPECT_EQ(base::File::FILE_OK, file_util()->Touch(context.get(), CreateURL(file_name), @@ -208,10 +206,8 @@ TEST_F(LocalFileUtilTest, TouchDirectory) { base::File::Info info; ASSERT_TRUE(base::GetFileInfo(LocalPath(dir_name), &info)); - const base::Time new_accessed = - info.last_accessed + base::TimeDelta::FromHours(10); - const base::Time new_modified = - info.last_modified + base::TimeDelta::FromHours(5); + const base::Time new_accessed = info.last_accessed + base::Hours(10); + const base::Time new_modified = info.last_modified + base::Hours(5); EXPECT_EQ(base::File::FILE_OK, file_util()->Touch(context.get(), CreateURL(dir_name), new_accessed, 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 342fc8e81c5..77eb3192efe 100644 --- a/chromium/storage/browser/file_system/memory_file_stream_reader.h +++ b/chromium/storage/browser/file_system/memory_file_stream_reader.h @@ -35,6 +35,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) MemoryFileStreamReader const base::FilePath& file_path, int64_t initial_offset, const base::Time& expected_modification_time); + + MemoryFileStreamReader(const MemoryFileStreamReader&) = delete; + MemoryFileStreamReader& operator=(const MemoryFileStreamReader&) = delete; + ~MemoryFileStreamReader() override; // FileStreamReader overrides. @@ -56,8 +60,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) MemoryFileStreamReader int64_t offset_; base::WeakPtrFactory<MemoryFileStreamReader> weak_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(MemoryFileStreamReader); }; } // namespace storage 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 83f3c8c3965..b7f2437ab42 100644 --- a/chromium/storage/browser/file_system/memory_file_stream_writer.h +++ b/chromium/storage/browser/file_system/memory_file_stream_writer.h @@ -23,6 +23,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) MemoryFileStreamWriter base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util, const base::FilePath& file_path, int64_t initial_offset); + + MemoryFileStreamWriter(const MemoryFileStreamWriter&) = delete; + MemoryFileStreamWriter& operator=(const MemoryFileStreamWriter&) = delete; + ~MemoryFileStreamWriter() override; // FileStreamWriter overrides. @@ -49,7 +53,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) MemoryFileStreamWriter net::CompletionOnceCallback cancel_callback_; base::WeakPtrFactory<MemoryFileStreamWriter> weak_factory_{this}; - DISALLOW_COPY_AND_ASSIGN(MemoryFileStreamWriter); }; } // namespace storage diff --git a/chromium/storage/browser/file_system/mount_points.h b/chromium/storage/browser/file_system/mount_points.h index f8bca3aa17b..c1e75f6defa 100644 --- a/chromium/storage/browser/file_system/mount_points.h +++ b/chromium/storage/browser/file_system/mount_points.h @@ -13,9 +13,10 @@ #include "storage/common/file_system/file_system_util.h" class GURL; -namespace url { -class Origin; -} + +namespace blink { +class StorageKey; +} // namespace blink namespace storage { class FileSystemMountOption; @@ -56,16 +57,23 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) MountPoints { // the given mount type. virtual bool HandlesFileSystemMountType(FileSystemType type) const = 0; - // Same as CreateCrackedFileSystemURL, but cracks FileSystemURL created - // from |url|. - virtual FileSystemURL CrackURL(const GURL& url) const = 0; - - // Creates a FileSystemURL with the given origin, type and virtual path and - // tries to crack it as a part of one of the registered mount points. If the - // the URL is not valid or does not belong to any of the mount points - // registered in this context, returns empty, invalid FileSystemURL. + // TODO(https://crbug.com/1240603): Determine if MountPoints::CrackURL() + // and its overrides in child classes should be removed and replaced with + // FileSystemContext::CrackURL(). + // + // Same as CreateCrackedFileSystemURL, but cracks a FileSystemURL created + // from `url` and `storage_key`. + virtual FileSystemURL CrackURL( + const GURL& url, + const blink::StorageKey& storage_key) const = 0; + + // Creates a FileSystemURL with the given `storage_key`, `type`, and + // `virtual_path` and tries to crack it as a part of one of the registered + // mount points. If the the URL is not valid or does not belong to any of the + // mount points registered in this context, returns empty, invalid + // FileSystemURL. virtual FileSystemURL CreateCrackedFileSystemURL( - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type, const base::FilePath& virtual_path) const = 0; diff --git a/chromium/storage/browser/file_system/native_file_util.cc b/chromium/storage/browser/file_system/native_file_util.cc index 42b1496c162..2fb54be84f2 100644 --- a/chromium/storage/browser/file_system/native_file_util.cc +++ b/chromium/storage/browser/file_system/native_file_util.cc @@ -16,6 +16,10 @@ #include "storage/browser/file_system/file_system_url.h" #include "storage/common/file_system/file_system_mount_option.h" +#if defined(OS_WIN) +#include "windows.h" +#endif // defined(OS_WIN) + namespace storage { namespace { @@ -282,6 +286,23 @@ base::File::Error NativeFileUtil::CopyOrMoveFile( return base::File::FILE_ERROR_NOT_FOUND; } + // Cache permissions of dest file before copy/move overwrites the file. + bool should_retain_file_permissions = false; +#if defined(OS_POSIX) + int dest_mode; + if (option == FileSystemOperation::OPTION_PRESERVE_DESTINATION_PERMISSIONS) { + // Will be false if the destination file doesn't exist. + should_retain_file_permissions = + base::GetPosixFilePermissions(dest_path, &dest_mode); + } +#elif defined(OS_WIN) + DWORD dest_attributes; + if (option == FileSystemOperation::OPTION_PRESERVE_DESTINATION_PERMISSIONS) { + dest_attributes = ::GetFileAttributes(dest_path.value().c_str()); + should_retain_file_permissions = dest_attributes != INVALID_FILE_ATTRIBUTES; + } +#endif // defined(OS_POSIX) + switch (mode) { case COPY_NOSYNC: if (!base::CopyFile(src_path, dest_path)) @@ -299,8 +320,17 @@ base::File::Error NativeFileUtil::CopyOrMoveFile( // Preserve the last modified time. Do not return error here even if // the setting is failed, because the copy itself is successfully done. - if (option == FileSystemOperation::OPTION_PRESERVE_LAST_MODIFIED) + if (option == FileSystemOperation::OPTION_PRESERVE_LAST_MODIFIED) { base::TouchFile(dest_path, last_modified, last_modified); + } + + if (should_retain_file_permissions) { +#if defined(OS_POSIX) + base::SetPosixFilePermissions(dest_path, dest_mode); +#elif defined(OS_WIN) + ::SetFileAttributes(dest_path.value().c_str(), dest_attributes); +#endif // defined(OS_POSIX) + } return base::File::FILE_OK; } diff --git a/chromium/storage/browser/file_system/native_file_util_unittest.cc b/chromium/storage/browser/file_system/native_file_util_unittest.cc index fd00f8cf564..9191ab56c37 100644 --- a/chromium/storage/browser/file_system/native_file_util_unittest.cc +++ b/chromium/storage/browser/file_system/native_file_util_unittest.cc @@ -16,6 +16,10 @@ #include "storage/browser/file_system/native_file_util.h" #include "testing/gtest/include/gtest/gtest.h" +#if defined(OS_WIN) +#include "windows.h" +#endif // defined(OS_WIN) + namespace storage { class NativeFileUtilTest : public testing::Test { @@ -41,6 +45,30 @@ class NativeFileUtilTest : public testing::Test { return info.size; } +#if defined(OS_POSIX) + void ExpectFileHasPermissionsPosix(base::FilePath file, int expected_mode) { + base::File::Info file_info; + int mode; + ASSERT_TRUE(FileExists(file)); + + EXPECT_TRUE(base::GetPosixFilePermissions(file, &mode)); + EXPECT_EQ(mode, expected_mode); + } +#endif // defined(OS_POSIX) + +#if defined(OS_WIN) + void ExpectFileHasPermissionsWin(base::FilePath file, + DWORD expected_attributes) { + base::File::Info file_info; + DWORD attributes; + ASSERT_TRUE(FileExists(file)); + + attributes = ::GetFileAttributes(file.value().c_str()); + EXPECT_NE(attributes, INVALID_FILE_ATTRIBUTES); + EXPECT_EQ(attributes, expected_attributes); + } +#endif // defined(OS_WIN) + private: base::ScopedTempDir data_dir_; @@ -125,10 +153,8 @@ TEST_F(NativeFileUtilTest, TouchFileAndGetFileInfo) { ASSERT_EQ(info.last_accessed, native_info.last_accessed); ASSERT_EQ(info.creation_time, native_info.creation_time); - const base::Time new_accessed = - info.last_accessed + base::TimeDelta::FromHours(10); - const base::Time new_modified = - info.last_modified + base::TimeDelta::FromHours(5); + const base::Time new_accessed = info.last_accessed + base::Hours(10); + const base::Time new_modified = info.last_modified + base::Hours(5); EXPECT_EQ(base::File::FILE_OK, NativeFileUtil::Touch(file_name, new_accessed, new_modified)); @@ -464,4 +490,78 @@ TEST_F(NativeFileUtilTest, PreserveLastModified) { EXPECT_EQ(file_info1.last_modified, file_info2.last_modified); } +#if defined(OS_POSIX) || defined(OS_WIN) +TEST_F(NativeFileUtilTest, PreserveDestinationPermissions) { + // Ensure both the src and dest files exist. + base::FilePath to_file = Path("to-file"); + base::FilePath from_file = Path("from-file1"); + bool created = false; + ASSERT_EQ(base::File::FILE_OK, + NativeFileUtil::EnsureFileExists(to_file, &created)); + ASSERT_TRUE(created); + EXPECT_TRUE(FileExists(to_file)); + + ASSERT_EQ(base::File::FILE_OK, + NativeFileUtil::EnsureFileExists(from_file, &created)); + ASSERT_TRUE(created); + EXPECT_TRUE(FileExists(from_file)); + +#if defined(OS_POSIX) + int dest_initial_mode; + ASSERT_TRUE(base::GetPosixFilePermissions(to_file, &dest_initial_mode)); +#elif defined(OS_WIN) + DWORD dest_initial_attributes = ::GetFileAttributes(to_file.value().c_str()); + ASSERT_NE(dest_initial_attributes, INVALID_FILE_ATTRIBUTES); +#endif // defined(OS_POSIX) + + // Give dest file some distinct permissions it didn't have before. +#if defined(OS_POSIX) + int old_dest_mode = dest_initial_mode | S_IRGRP | S_IXOTH; + EXPECT_NE(old_dest_mode, dest_initial_mode); + EXPECT_TRUE(base::SetPosixFilePermissions(to_file, old_dest_mode)); +#elif defined(OS_WIN) + DWORD old_dest_attributes = FILE_ATTRIBUTE_NORMAL; + EXPECT_NE(old_dest_attributes, dest_initial_attributes); + EXPECT_TRUE( + ::SetFileAttributes(to_file.value().c_str(), old_dest_attributes)); +#endif // defined(OS_POSIX) + + // Test for copy (nosync). + ASSERT_EQ(base::File::FILE_OK, + NativeFileUtil::CopyOrMoveFile( + from_file, to_file, + FileSystemOperation::OPTION_PRESERVE_DESTINATION_PERMISSIONS, + NativeFileUtil::COPY_NOSYNC)); +#if defined(OS_POSIX) + ExpectFileHasPermissionsPosix(to_file, old_dest_mode); +#elif defined(OS_WIN) + ExpectFileHasPermissionsWin(to_file, old_dest_attributes); +#endif // defined(OS_POSIX) + + // Test for copy (sync). + ASSERT_EQ(base::File::FILE_OK, + NativeFileUtil::CopyOrMoveFile( + from_file, to_file, + FileSystemOperation::OPTION_PRESERVE_DESTINATION_PERMISSIONS, + NativeFileUtil::COPY_SYNC)); +#if defined(OS_POSIX) + ExpectFileHasPermissionsPosix(to_file, old_dest_mode); +#elif defined(OS_WIN) + ExpectFileHasPermissionsWin(to_file, old_dest_attributes); +#endif // defined(OS_POSIX) + + // Test for move. + ASSERT_EQ(base::File::FILE_OK, + NativeFileUtil::CopyOrMoveFile( + from_file, to_file, + FileSystemOperation::OPTION_PRESERVE_DESTINATION_PERMISSIONS, + NativeFileUtil::MOVE)); +#if defined(OS_POSIX) + ExpectFileHasPermissionsPosix(to_file, old_dest_mode); +#elif defined(OS_WIN) + ExpectFileHasPermissionsWin(to_file, old_dest_attributes); +#endif // defined(OS_POSIX) +} +#endif // defined(OS_POSIX) || defined(OS_WIN) + } // namespace storage diff --git a/chromium/storage/browser/file_system/obfuscated_file_util.cc b/chromium/storage/browser/file_system/obfuscated_file_util.cc index 05726e8a451..bdf8475d28b 100644 --- a/chromium/storage/browser/file_system/obfuscated_file_util.cc +++ b/chromium/storage/browser/file_system/obfuscated_file_util.cc @@ -33,6 +33,7 @@ #include "storage/browser/quota/quota_manager.h" #include "storage/common/database/database_identifier.h" #include "storage/common/file_system/file_system_util.h" +#include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/leveldatabase/leveldb_chrome.h" #include "url/gurl.h" @@ -108,6 +109,15 @@ enum IsolatedOriginStatus { } // namespace +// TODO(https://crbug.com/1248104): This class will eventually interface with +// Storage Buckets instead of directly interfacing with LevelDB. Thus, the below +// functions were converted from url::Origin to blink::StorageKey to prepare for +// Storage Partitioning of the FileSystem APIs. However, it is important to note +// that, until the refactor to use Storage Buckets, the LevelDB structure above +// is still used, and the entries are still keyed per-origin (achieved by +// storage_key.origin()) and per-type. Going forward, OriginRecords will be +// retrieved from the database and converted into StorageKey values until +// Storage Buckets are implemented instead. class ObfuscatedFileEnumerator final : public FileSystemFileUtil::AbstractFileEnumerator { public: @@ -205,36 +215,37 @@ class ObfuscatedFileEnumerator final base::File::Info current_platform_file_info_; }; -class ObfuscatedOriginEnumerator - : public ObfuscatedFileUtil::AbstractOriginEnumerator { +class ObfuscatedStorageKeyEnumerator + : public ObfuscatedFileUtil::AbstractStorageKeyEnumerator { public: using OriginRecord = SandboxOriginDatabase::OriginRecord; - ObfuscatedOriginEnumerator( + ObfuscatedStorageKeyEnumerator( SandboxOriginDatabaseInterface* origin_database, base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util, const base::FilePath& base_file_path) : base_file_path_(base_file_path), memory_file_util_(std::move(memory_file_util)) { if (origin_database) - origin_database->ListAllOrigins(&origins_); + origin_database->ListAllOrigins(&origin_records_); } - ~ObfuscatedOriginEnumerator() override = default; + ~ObfuscatedStorageKeyEnumerator() override = default; - // Returns the next origin. Returns empty if there are no more origins. - absl::optional<url::Origin> Next() override { + // Returns the next StorageKey. Returns empty if there are no more + // StorageKeys. + absl::optional<blink::StorageKey> Next() override { OriginRecord record; - if (origins_.empty()) { + if (origin_records_.empty()) { current_ = record; return absl::nullopt; } - record = origins_.back(); - origins_.pop_back(); + record = origin_records_.back(); + origin_records_.pop_back(); current_ = record; - return GetOriginFromIdentifier(record.origin); + return blink::StorageKey(GetOriginFromIdentifier(record.origin)); } - // Returns the current origin's information. + // Returns the current StorageKey.origin()'s information. bool HasTypeDirectory(const std::string& type_string) const override { if (current_.path.empty()) return false; @@ -251,7 +262,7 @@ class ObfuscatedOriginEnumerator } private: - std::vector<OriginRecord> origins_; + std::vector<OriginRecord> origin_records_; OriginRecord current_; base::FilePath base_file_path_; base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util_; @@ -298,7 +309,8 @@ base::File ObfuscatedFileUtil::CreateOrOpen(FileSystemOperationContext* context, if (file.IsValid() && file_flags & base::File::FLAG_WRITE && context->quota_limit_type() == QuotaLimitType::kUnlimited && sandbox_delegate_) { - sandbox_delegate_->StickyInvalidateUsageCache(url.origin(), url.type()); + sandbox_delegate_->StickyInvalidateUsageCache(url.storage_key(), + url.type()); } return file; } @@ -539,9 +551,9 @@ base::File::Error ObfuscatedFileUtil::CopyOrMoveFile( base::File::Info dest_platform_file_info; // overwrite case only base::FilePath dest_local_path; // overwrite case only if (overwrite) { - base::File::Error error = GetFileInfoInternal( - db, context, dest_url, dest_file_id, &dest_file_info, - &dest_platform_file_info, &dest_local_path); + error = GetFileInfoInternal(db, context, dest_url, dest_file_id, + &dest_file_info, &dest_platform_file_info, + &dest_local_path); if (error == base::File::FILE_ERROR_NOT_FOUND) overwrite = false; // fallback to non-overwrite case else if (error != base::File::FILE_OK) @@ -772,6 +784,10 @@ base::File::Error ObfuscatedFileUtil::DeleteDirectory( FileId file_id; if (!db->GetFileWithPath(url.path(), &file_id)) return base::File::FILE_ERROR_NOT_FOUND; + if (!file_id) { + // Cannot remove the root directory. + return base::File::FILE_ERROR_FAILED; + } FileInfo file_info; if (!db->GetFileInfo(file_id, &file_info)) { NOTREACHED(); @@ -845,13 +861,14 @@ bool ObfuscatedFileUtil::IsDirectoryEmpty(FileSystemOperationContext* context, return children.empty(); } -base::FilePath ObfuscatedFileUtil::GetDirectoryForOriginAndType( - const url::Origin& origin, +base::FilePath ObfuscatedFileUtil::GetDirectoryForStorageKeyAndType( + const blink::StorageKey& storage_key, const std::string& type_string, bool create, base::File::Error* error_code) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - base::FilePath origin_dir = GetDirectoryForOrigin(origin, create, error_code); + base::FilePath origin_dir = + GetDirectoryForStorageKey(storage_key, create, error_code); if (origin_dir.empty()) return base::FilePath(); if (type_string.empty()) @@ -871,22 +888,22 @@ base::FilePath ObfuscatedFileUtil::GetDirectoryForOriginAndType( return path; } -bool ObfuscatedFileUtil::DeleteDirectoryForOriginAndType( - const url::Origin& origin, +bool ObfuscatedFileUtil::DeleteDirectoryForStorageKeyAndType( + const blink::StorageKey& storage_key, const std::string& type_string) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DestroyDirectoryDatabase(origin, type_string); + DestroyDirectoryDatabase(storage_key, type_string); const base::FilePath origin_path = - GetDirectoryForOrigin(origin, false, nullptr); + GetDirectoryForStorageKey(storage_key, false, nullptr); if (origin_path.empty()) return true; if (!type_string.empty()) { // Delete the filesystem type directory. base::File::Error error = base::File::FILE_OK; - const base::FilePath origin_type_path = - GetDirectoryForOriginAndType(origin, type_string, false, &error); + const base::FilePath origin_type_path = GetDirectoryForStorageKeyAndType( + storage_key, type_string, false, &error); if (error == base::File::FILE_ERROR_FAILED) return false; if (error == base::File::FILE_OK && !origin_type_path.empty() && @@ -909,19 +926,21 @@ bool ObfuscatedFileUtil::DeleteDirectoryForOriginAndType( } // No other directories seem exist. Try deleting the entire origin directory. - InitOriginDatabase(origin, false); + InitOriginDatabase(storage_key.origin(), false); if (origin_database_) { - origin_database_->RemovePathForOrigin(GetIdentifierFromOrigin(origin)); + origin_database_->RemovePathForOrigin( + GetIdentifierFromOrigin(storage_key.origin())); } return delegate_->DeleteFileOrDirectory(origin_path, true /* recursive */); } -void ObfuscatedFileUtil::CloseFileSystemForOriginAndType( - const url::Origin& origin, +void ObfuscatedFileUtil::CloseFileSystemForStorageKeyAndType( + const blink::StorageKey& storage_key, const std::string& type_string) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - const std::string key_prefix = GetDirectoryDatabaseKey(origin, type_string); + const std::string key_prefix = + GetDirectoryDatabaseKey(storage_key, type_string); for (auto iter = directories_.lower_bound(key_prefix); iter != directories_.end();) { if (!base::StartsWith(iter->first, key_prefix, @@ -932,12 +951,10 @@ void ObfuscatedFileUtil::CloseFileSystemForOriginAndType( } } -std::unique_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> -ObfuscatedFileUtil::CreateOriginEnumerator() { +std::unique_ptr<ObfuscatedFileUtil::AbstractStorageKeyEnumerator> +ObfuscatedFileUtil::CreateStorageKeyEnumerator() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - std::vector<SandboxOriginDatabase::OriginRecord> origins; - InitOriginDatabase(url::Origin(), false); base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> file_util_delegate; if (is_incognito()) { @@ -945,17 +962,18 @@ ObfuscatedFileUtil::CreateOriginEnumerator() { static_cast<ObfuscatedFileUtilMemoryDelegate*>(delegate()) ->GetWeakPtr(); } - return std::make_unique<ObfuscatedOriginEnumerator>( + return std::make_unique<ObfuscatedStorageKeyEnumerator>( origin_database_.get(), file_util_delegate, file_system_directory_); } void ObfuscatedFileUtil::DestroyDirectoryDatabase( - const url::Origin& origin, + const blink::StorageKey& storage_key, const std::string& type_string) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // If |type_string| is empty, delete all filesystem types under |origin|. - const std::string key_prefix = GetDirectoryDatabaseKey(origin, type_string); + // If `type_string` is empty, delete all filesystem types under `storage_key`. + const std::string key_prefix = + GetDirectoryDatabaseKey(storage_key, type_string); for (auto iter = directories_.lower_bound(key_prefix); iter != directories_.end();) { if (!base::StartsWith(iter->first, key_prefix, @@ -982,8 +1000,8 @@ base::FilePath ObfuscatedFileUtil::GetDirectoryForURL( bool create, base::File::Error* error_code) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return GetDirectoryForOriginAndType( - url.origin(), CallGetTypeStringForURL(url), create, error_code); + return GetDirectoryForStorageKeyAndType( + url.storage_key(), CallGetTypeStringForURL(url), create, error_code); } std::string ObfuscatedFileUtil::CallGetTypeStringForURL( @@ -1033,7 +1051,7 @@ base::File::Error ObfuscatedFileUtil::GetFileInfoInternal( *platform_file_path = local_path; } else if (error == base::File::FILE_ERROR_NOT_FOUND) { LOG(WARNING) << "Lost a backing file."; - InvalidateUsageCache(context, url.origin(), url.type()); + InvalidateUsageCache(context, url.storage_key(), url.type()); if (!db->RemoveFileInfo(file_id)) return base::File::FILE_ERROR_FAILED; } @@ -1059,7 +1077,7 @@ base::File ObfuscatedFileUtil::CreateAndOpenFile( false /* recursive */)) return base::File(base::File::FILE_ERROR_FAILED); LOG(WARNING) << "A stray file detected"; - InvalidateUsageCache(context, dest_url.origin(), dest_url.type()); + InvalidateUsageCache(context, dest_url.storage_key(), dest_url.type()); } base::File file = delegate_->CreateOrOpen(dest_local_path, file_flags); @@ -1104,7 +1122,7 @@ base::File::Error ObfuscatedFileUtil::CreateFile( false /* recursive */)) return base::File::FILE_ERROR_FAILED; LOG(WARNING) << "A stray file detected"; - InvalidateUsageCache(context, dest_url.origin(), dest_url.type()); + InvalidateUsageCache(context, dest_url.storage_key(), dest_url.type()); } error = delegate_->EnsureFileExists(dest_local_path, &created); @@ -1161,11 +1179,11 @@ base::FilePath ObfuscatedFileUtil::DataPathToLocalPath( } std::string ObfuscatedFileUtil::GetDirectoryDatabaseKey( - const url::Origin& origin, + const blink::StorageKey& storage_key, const std::string& type_string) { // For isolated origin we just use a type string as a key. - return GetIdentifierFromOrigin(origin) + kDirectoryDatabaseKeySeparator + - type_string; + return GetIdentifierFromOrigin(storage_key.origin()) + + kDirectoryDatabaseKeySeparator + type_string; } // TODO(ericu): How to do the whole validation-without-creation thing? @@ -1178,7 +1196,7 @@ SandboxDirectoryDatabase* ObfuscatedFileUtil::GetDirectoryDatabase( DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); std::string key = - GetDirectoryDatabaseKey(url.origin(), CallGetTypeStringForURL(url)); + GetDirectoryDatabaseKey(url.storage_key(), CallGetTypeStringForURL(url)); if (key.empty()) return nullptr; @@ -1201,12 +1219,12 @@ SandboxDirectoryDatabase* ObfuscatedFileUtil::GetDirectoryDatabase( return directories_[key].get(); } -base::FilePath ObfuscatedFileUtil::GetDirectoryForOrigin( - const url::Origin& origin, +base::FilePath ObfuscatedFileUtil::GetDirectoryForStorageKey( + const blink::StorageKey& storage_key, bool create, base::File::Error* error_code) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!InitOriginDatabase(origin, create)) { + if (!InitOriginDatabase(storage_key.origin(), create)) { if (error_code) { *error_code = create ? base::File::FILE_ERROR_FAILED : base::File::FILE_ERROR_NOT_FOUND; @@ -1214,7 +1232,7 @@ base::FilePath ObfuscatedFileUtil::GetDirectoryForOrigin( return base::FilePath(); } base::FilePath directory_name; - std::string id = GetIdentifierFromOrigin(origin); + std::string id = GetIdentifierFromOrigin(storage_key.origin()); bool exists_in_db = origin_database_->HasOriginPath(id); if (!exists_in_db && !create) { @@ -1258,17 +1276,17 @@ base::FilePath ObfuscatedFileUtil::GetDirectoryForOrigin( void ObfuscatedFileUtil::InvalidateUsageCache( FileSystemOperationContext* context, - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type) { if (sandbox_delegate_) - sandbox_delegate_->InvalidateUsageCache(origin, type); + sandbox_delegate_->InvalidateUsageCache(storage_key, type); } void ObfuscatedFileUtil::MarkUsed() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(db_flush_delay_seconds_), - this, &ObfuscatedFileUtil::DropDatabases); + timer_.Start(FROM_HERE, base::Seconds(db_flush_delay_seconds_), this, + &ObfuscatedFileUtil::DropDatabases); } void ObfuscatedFileUtil::DropDatabases() { @@ -1407,7 +1425,7 @@ base::File ObfuscatedFileUtil::CreateOrOpenInternal( if (error == base::File::FILE_ERROR_NOT_FOUND) { // TODO(tzik): Also invalidate on-memory usage cache in UsageTracker. // TODO(tzik): Delete database entry after ensuring the file lost. - InvalidateUsageCache(context, url.origin(), url.type()); + InvalidateUsageCache(context, url.storage_key(), url.type()); LOG(WARNING) << "Lost a backing file."; return base::File(base::File::FILE_ERROR_FAILED); } @@ -1422,9 +1440,11 @@ base::File ObfuscatedFileUtil::CreateOrOpenInternal( return file; } -bool ObfuscatedFileUtil::HasIsolatedStorage(const url::Origin& origin) { +bool ObfuscatedFileUtil::HasIsolatedStorage( + const blink::StorageKey& storage_key) { return special_storage_policy_.get() && - special_storage_policy_->HasIsolatedStorage(origin.GetURL()); + special_storage_policy_->HasIsolatedStorage( + storage_key.origin().GetURL()); } } // namespace storage diff --git a/chromium/storage/browser/file_system/obfuscated_file_util.h b/chromium/storage/browser/file_system/obfuscated_file_util.h index 98d8db7c525..89aed25b846 100644 --- a/chromium/storage/browser/file_system/obfuscated_file_util.h +++ b/chromium/storage/browser/file_system/obfuscated_file_util.h @@ -29,9 +29,13 @@ #include "storage/browser/file_system/sandbox_file_system_backend_delegate.h" #include "storage/common/file_system/file_system_types.h" +namespace blink { +class StorageKey; +} // namespace blink + namespace url { class Origin; -} +} // namespace url namespace storage { @@ -64,38 +68,47 @@ class SpecialStoragePolicy; // // This class must be deleted on the FILE thread, because that's where // DropDatabases needs to be called. +// +// TODO(https://crbug.com/1248104): This class will eventually use Storage +// Buckets instead of LevelDB. Thus, the below functions were converted from +// url::Origin to blink::StorageKey to prepare for Storage Partitioning of the +// FileSystem APIs. However, it is important to note that, until the refactor to +// use Storage Buckets, the LevelDB structure above is still used, and the +// entries are still keyed per-origin (achieved by storage_key.origin()) and +// per-type. Going forward, comments will refer to the DB as "origin database" +// or the directory as "origin directory", but the origin will come from a +// larger StorageKey object. class COMPONENT_EXPORT(STORAGE_BROWSER) ObfuscatedFileUtil : public FileSystemFileUtil { public: - // Origin enumerator interface. + // StorageKey enumerator interface. // An instance of this interface is assumed to be called on the file thread. - class AbstractOriginEnumerator { + class AbstractStorageKeyEnumerator { public: - virtual ~AbstractOriginEnumerator() = default; + virtual ~AbstractStorageKeyEnumerator() = default; - // Returns the next origin. Returns absl::nullopt if there are no more - // origins. - virtual absl::optional<url::Origin> Next() = 0; + // Returns the next StorageKey. Returns absl::nullopt if there are no more + // StorageKeys. + virtual absl::optional<blink::StorageKey> Next() = 0; // Returns the current origin's information. - // |type_string| must be ascii string. + // `type_string` must be ascii string. virtual bool HasTypeDirectory(const std::string& type_string) const = 0; }; using GetTypeStringForURLCallback = base::RepeatingCallback<std::string(const FileSystemURL&)>; - // |get_type_string_for_url| is user-defined callback that should return + // `get_type_string_for_url` is user-defined callback that should return // a type string for the given FileSystemURL. The type string is used // to provide per-type isolation in the sandboxed filesystem directory. // - // |known_type_strings| are known type string names that this file system + // `known_type_strings` are known type string names that this file system // should care about. // This info is used to determine whether we could delete the entire - // origin directory or not in DeleteDirectoryForOriginAndType. If no directory - // for any known type exists the origin directory may get deleted when - // one origin/type pair is deleted. - // + // origin directory or not in DeleteDirectoryForStorageKeyAndType. If no + // directory for any known type exists the origin directory may get + // deleted when one StorageKey/type pair is deleted. ObfuscatedFileUtil(scoped_refptr<SpecialStoragePolicy> special_storage_policy, const base::FilePath& file_system_directory, leveldb::Env* env_override, @@ -103,6 +116,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) ObfuscatedFileUtil const std::set<std::string>& known_type_strings, SandboxFileSystemBackendDelegate* sandbox_delegate, bool is_incognito); + + ObfuscatedFileUtil(const ObfuscatedFileUtil&) = delete; + ObfuscatedFileUtil& operator=(const ObfuscatedFileUtil&) = delete; + ~ObfuscatedFileUtil() override; // FileSystemFileUtil overrides. @@ -152,42 +169,43 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) ObfuscatedFileUtil base::File::Info* file_info, base::FilePath* platform_path) override; - // Returns true if the directory |url| is empty. + // Returns true if the directory `url` is empty. bool IsDirectoryEmpty(FileSystemOperationContext* context, const FileSystemURL& url); - // Gets the topmost directory specific to this origin and type. This will + // Gets the topmost directory specific to this StorageKey and type. This will // contain both the directory database's files and all the backing file // subdirectories. - // Returns the topmost origin directory if |type_string| is empty. + // Returns the topmost origin directory if `type_string` is empty. // Returns an empty path if the directory is undefined. // If the directory is defined, it will be returned, even if // there is a file system error (e.g. the directory doesn't exist on disk and - // |create| is false). Callers should always check |error_code| to make sure + // `create` is false). Callers should always check `error_code` to make sure // the returned path is usable. - base::FilePath GetDirectoryForOriginAndType(const url::Origin& origin, - const std::string& type_string, - bool create, - base::File::Error* error_code); - - // Deletes the topmost directory specific to this origin and type. This will - // delete its directory database. - // Deletes the topmost origin directory if |type_string| is empty. - bool DeleteDirectoryForOriginAndType(const url::Origin& origin, - const std::string& type_string); - - // Frees resources used by an origin's filesystem. - void CloseFileSystemForOriginAndType(const url::Origin& origin, - const std::string& type_string); + base::FilePath GetDirectoryForStorageKeyAndType( + const blink::StorageKey& storage_key, + const std::string& type_string, + bool create, + base::File::Error* error_code); + + // Deletes the topmost directory specific to this StorageKey and type. This + // will delete its directory database. Deletes the topmost origin + // directory if `type_string` is empty. + bool DeleteDirectoryForStorageKeyAndType(const blink::StorageKey& storage_key, + const std::string& type_string); + + // Frees resources used by a StorageKey's filesystem. + void CloseFileSystemForStorageKeyAndType(const blink::StorageKey& storage_key, + const std::string& type_string); // This method and all methods of its returned class must be called only on // the FILE thread. The caller is responsible for deleting the returned // object. - std::unique_ptr<AbstractOriginEnumerator> CreateOriginEnumerator(); + std::unique_ptr<AbstractStorageKeyEnumerator> CreateStorageKeyEnumerator(); // Deletes a directory database from the database list in the ObfuscatedFSFU // and destroys the database on the disk. - void DestroyDirectoryDatabase(const url::Origin& origin, + void DestroyDirectoryDatabase(const blink::StorageKey& storage_key, const std::string& type_string); // Computes a cost for storing a given file in the obfuscated FSFU. @@ -237,7 +255,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) ObfuscatedFileUtil base::FilePath* platform_file_path); // Creates a new file, both the underlying backing file and the entry in the - // database. |dest_file_info| is an in-out parameter. Supply the name and + // database. `dest_file_info` is an in-out parameter. Supply the name and // parent_id; data_path is ignored. On success, data_path will // always be set to the relative path [from the root of the type-specific // filesystem directory] of a NEW backing file. Returns the new file. @@ -247,8 +265,8 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) ObfuscatedFileUtil int file_flags); // The same as CreateAndOpenFile except that a file is not returned and if a - // path is provided in |source_path|, it will be used as a source from which - // to COPY data. If |foreign_source| is true, the source file is considered + // path is provided in `source_path`, it will be used as a source from which + // to COPY data. If `foreign_source` is true, the source file is considered // from another (on disk) file system and its path is considered not // obfuscated. base::File::Error CreateFile(FileSystemOperationContext* context, @@ -257,7 +275,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) ObfuscatedFileUtil const FileSystemURL& dest_url, FileInfo* dest_file_info); - // Updates |db| and |dest_file_info| at the end of creating a new file. + // Updates `db` and `dest_file_info` at the end of creating a new file. base::File::Error CommitCreateFile(const base::FilePath& root, const base::FilePath& local_path, SandboxDirectoryDatabase* db, @@ -269,30 +287,30 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) ObfuscatedFileUtil base::FilePath DataPathToLocalPath(const FileSystemURL& url, const base::FilePath& data_file_path); - std::string GetDirectoryDatabaseKey(const url::Origin& origin, + std::string GetDirectoryDatabaseKey(const blink::StorageKey& storage_key, const std::string& type_string); - // This returns nullptr if |create| flag is false and a filesystem does not - // exist for the given |url|. - // For read operations |create| should be false. + // This returns nullptr if `create` flag is false and a filesystem does not + // exist for the given `url`. + // For read operations `create` should be false. SandboxDirectoryDatabase* GetDirectoryDatabase(const FileSystemURL& url, bool create); - // Gets the topmost directory specific to this origin. This will + // Gets the topmost directory specific to this StorageKey. This will // contain both the filesystem type subdirectories. - base::FilePath GetDirectoryForOrigin(const url::Origin& origin, - bool create, - base::File::Error* error_code); + base::FilePath GetDirectoryForStorageKey(const blink::StorageKey& storage_key, + bool create, + base::File::Error* error_code); void InvalidateUsageCache(FileSystemOperationContext* context, - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type); void MarkUsed(); void DropDatabases(); - // Initializes the origin database. |origin_hint| may be used as a hint - // for initializing database if it's not empty. + // Initializes the origin/type database. `origin_hint` may be used as a + // hint for initializing database if it's not empty. bool InitOriginDatabase(const url::Origin& origin_hint, bool create); base::File::Error GenerateNewLocalPath(SandboxDirectoryDatabase* db, @@ -305,7 +323,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) ObfuscatedFileUtil const FileSystemURL& url, int file_flags); - bool HasIsolatedStorage(const url::Origin& origin); + bool HasIsolatedStorage(const blink::StorageKey& storage_key); SEQUENCE_CHECKER(sequence_checker_); @@ -328,8 +346,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) ObfuscatedFileUtil SandboxFileSystemBackendDelegate* sandbox_delegate_; std::unique_ptr<ObfuscatedFileUtilDelegate> delegate_; - - DISALLOW_COPY_AND_ASSIGN(ObfuscatedFileUtil); }; } // namespace storage diff --git a/chromium/storage/browser/file_system/obfuscated_file_util_delegate.h b/chromium/storage/browser/file_system/obfuscated_file_util_delegate.h index 17d31f6c9d1..dfb81c8a1b3 100644 --- a/chromium/storage/browser/file_system/obfuscated_file_util_delegate.h +++ b/chromium/storage/browser/file_system/obfuscated_file_util_delegate.h @@ -17,6 +17,11 @@ namespace storage { class COMPONENT_EXPORT(STORAGE_BROWSER) ObfuscatedFileUtilDelegate { public: ObfuscatedFileUtilDelegate() = default; + + ObfuscatedFileUtilDelegate(const ObfuscatedFileUtilDelegate&) = delete; + ObfuscatedFileUtilDelegate& operator=(const ObfuscatedFileUtilDelegate&) = + delete; + virtual ~ObfuscatedFileUtilDelegate() = default; virtual bool DirectoryExists(const base::FilePath& path) = 0; @@ -54,9 +59,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) ObfuscatedFileUtilDelegate { FileSystemOperation::CopyOrMoveOption option, NativeFileUtil::CopyOrMoveMode mode) = 0; virtual base::File::Error DeleteFile(const base::FilePath& path) = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(ObfuscatedFileUtilDelegate); }; } // namespace storage 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 acc22212832..2948fa56d6f 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 @@ -409,8 +409,12 @@ base::File::Error ObfuscatedFileUtilMemoryDelegate::CopyOrMoveFile( break; } - if (option == FileSystemOperation::OPTION_PRESERVE_LAST_MODIFIED) + if (option == FileSystemOperation::OPTION_PRESERVE_LAST_MODIFIED) { Touch(dest_path, last_modified, last_modified); + } + + // Don't bother with the OPTION_PRESERVE_DESTINATION_PERMISSIONS option, since + // this is not relevant to in-memory files. return base::File::FILE_OK; } 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 9242697bb7d..733d3bcec4c 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 @@ -42,6 +42,12 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) ObfuscatedFileUtilMemoryDelegate : public ObfuscatedFileUtilDelegate { public: ObfuscatedFileUtilMemoryDelegate(const base::FilePath& file_system_directory); + + ObfuscatedFileUtilMemoryDelegate(const ObfuscatedFileUtilMemoryDelegate&) = + delete; + ObfuscatedFileUtilMemoryDelegate& operator=( + const ObfuscatedFileUtilMemoryDelegate&) = delete; + ~ObfuscatedFileUtilMemoryDelegate() override; bool DirectoryExists(const base::FilePath& path) override; @@ -135,8 +141,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) ObfuscatedFileUtilMemoryDelegate std::vector<base::FilePath::StringType> root_path_components_; base::WeakPtrFactory<ObfuscatedFileUtilMemoryDelegate> weak_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(ObfuscatedFileUtilMemoryDelegate); }; } // namespace storage diff --git a/chromium/storage/browser/file_system/obfuscated_file_util_memory_delegate_unittest.cc b/chromium/storage/browser/file_system/obfuscated_file_util_memory_delegate_unittest.cc index 6428d9f28b2..711c83b051c 100644 --- a/chromium/storage/browser/file_system/obfuscated_file_util_memory_delegate_unittest.cc +++ b/chromium/storage/browser/file_system/obfuscated_file_util_memory_delegate_unittest.cc @@ -228,10 +228,8 @@ TEST_F(ObfuscatedFileUtilMemoryDelegateTest, TouchFileAndGetFileInfo) { ASSERT_EQ(false, info.is_directory); ASSERT_EQ(false, info.is_symbolic_link); - const base::Time new_accessed = - info.last_accessed + base::TimeDelta::FromHours(10); - const base::Time new_modified = - info.last_modified + base::TimeDelta::FromHours(5); + const base::Time new_accessed = info.last_accessed + base::Hours(10); + const base::Time new_modified = info.last_modified + base::Hours(5); EXPECT_EQ(base::File::FILE_OK, file_util()->Touch(file_name, new_accessed, new_modified)); @@ -616,9 +614,9 @@ TEST_F(ObfuscatedFileUtilMemoryDelegateTest, PreserveLastModified_NoSync) { file_util()->CopyOrMoveFile( from_file, to_file, FileSystemOperation::OPTION_PRESERVE_LAST_MODIFIED, nosync)); + ASSERT_TRUE(FileExists(to_file)); base::File::Info file_info2; - ASSERT_TRUE(FileExists(to_file)); ASSERT_EQ(base::File::FILE_OK, file_util()->GetFileInfo(to_file, &file_info2)); EXPECT_EQ(file_info1.last_modified, file_info2.last_modified); 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 8049ff3377a..0bedcb3baea 100644 --- a/chromium/storage/browser/file_system/obfuscated_file_util_unittest.cc +++ b/chromium/storage/browser/file_system/obfuscated_file_util_unittest.cc @@ -52,7 +52,6 @@ #include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/leveldatabase/leveldb_chrome.h" #include "url/gurl.h" -#include "url/origin.h" using url::Origin; @@ -140,8 +139,9 @@ std::string GetTypeString(FileSystemType type) { return SandboxFileSystemBackendDelegate::GetTypeString(type); } -bool HasFileSystemType(ObfuscatedFileUtil::AbstractOriginEnumerator* enumerator, - FileSystemType type) { +bool HasFileSystemType( + ObfuscatedFileUtil::AbstractStorageKeyEnumerator* enumerator, + FileSystemType type) { return enumerator->HasTypeDirectory(GetTypeString(type)); } @@ -156,9 +156,10 @@ class ObfuscatedFileUtilTest : public testing::Test, public: ObfuscatedFileUtilTest() : task_environment_(base::test::TaskEnvironment::MainThreadType::IO), - origin_(Origin::Create(GURL("http://www.example.com"))), + storage_key_(blink::StorageKey::CreateFromStringForTesting( + "http://www.example.com")), type_(kFileSystemTypeTemporary), - sandbox_file_system_(origin_, type_), + sandbox_file_system_(storage_key_, type_), quota_status_(blink::mojom::QuotaStatusCode::kUnknown), usage_(-1) {} @@ -254,8 +255,10 @@ class ObfuscatedFileUtilTest : public testing::Test, std::unique_ptr<SandboxFileSystemTestHelper> NewFileSystem( const Origin& origin, FileSystemType type) { - auto file_system = - std::make_unique<SandboxFileSystemTestHelper>(origin, type); + // TODO(https://crbug.com/1245710): Refactor ObfuscatedFileSystem to use + // StorageKey instead of origin and replace in-line conversion below. + auto file_system = std::make_unique<SandboxFileSystemTestHelper>( + blink::StorageKey(origin), type); file_system->SetUp(file_system_context_); return file_system; @@ -275,14 +278,16 @@ class ObfuscatedFileUtilTest : public testing::Test, const base::FilePath& test_directory() const { return data_dir_.GetPath(); } - const Origin& origin() const { return origin_; } + const blink::StorageKey& storage_key() const { return storage_key_; } + + const Origin& origin() const { return storage_key_.origin(); } FileSystemType type() const { return type_; } std::string type_string() const { return GetTypeString(type_); } int64_t ComputeTotalFileSize() { - return sandbox_file_system_.ComputeCurrentOriginUsage() - + return sandbox_file_system_.ComputeCurrentStorageKeyUsage() - sandbox_file_system_.ComputeCurrentDirectoryDatabaseUsage(); } @@ -300,7 +305,7 @@ class ObfuscatedFileUtilTest : public testing::Test, } int64_t SizeByQuotaUtil() { - return sandbox_file_system_.GetCachedOriginUsage(); + return sandbox_file_system_.GetCachedStorageKeyUsage(); } int64_t SizeInUsageFile() { @@ -453,7 +458,8 @@ class ObfuscatedFileUtilTest : public testing::Test, private: void Check() { - ASSERT_EQ(expected_usage_, sandbox_file_system_->GetCachedOriginUsage()); + ASSERT_EQ(expected_usage_, + sandbox_file_system_->GetCachedStorageKeyUsage()); } std::unique_ptr<FileSystemOperationContext> context_; @@ -464,7 +470,7 @@ class ObfuscatedFileUtilTest : public testing::Test, std::unique_ptr<UsageVerifyHelper> AllowUsageIncrease( int64_t requested_growth) { - int64_t usage = sandbox_file_system_.GetCachedOriginUsage(); + int64_t usage = sandbox_file_system_.GetCachedStorageKeyUsage(); return std::make_unique<UsageVerifyHelper>(LimitedContext(requested_growth), &sandbox_file_system_, usage + requested_growth, this); @@ -472,7 +478,7 @@ class ObfuscatedFileUtilTest : public testing::Test, std::unique_ptr<UsageVerifyHelper> DisallowUsageIncrease( int64_t requested_growth) { - int64_t usage = sandbox_file_system_.GetCachedOriginUsage(); + int64_t usage = sandbox_file_system_.GetCachedStorageKeyUsage(); return std::make_unique<UsageVerifyHelper>( LimitedContext(requested_growth - 1), &sandbox_file_system_, usage, this); @@ -565,8 +571,8 @@ class ObfuscatedFileUtilTest : public testing::Test, EXPECT_EQ(file_info.last_modified.ToTimeT(), last_modified_time.ToTimeT()); context = NewContext(nullptr); - last_modified_time += base::TimeDelta::FromHours(1); - last_access_time += base::TimeDelta::FromHours(14); + last_modified_time += base::Hours(1); + last_access_time += base::Hours(14); EXPECT_EQ( base::File::FILE_OK, ofu()->Touch(context.get(), url, last_access_time, last_modified_time)); @@ -705,7 +711,7 @@ class ObfuscatedFileUtilTest : public testing::Test, void MaybeDropDatabasesAliveCaseTestBody() { std::unique_ptr<ObfuscatedFileUtil> file_util = CreateObfuscatedFileUtil(/*storage_policy=*/nullptr); - file_util->InitOriginDatabase(Origin(), true /*create*/); + file_util->InitOriginDatabase(url::Origin(), true /*create*/); ASSERT_TRUE(file_util->origin_database_ != nullptr); // Callback to Drop DB is called while ObfuscatedFileUtilTest is @@ -723,7 +729,7 @@ class ObfuscatedFileUtilTest : public testing::Test, { std::unique_ptr<ObfuscatedFileUtil> file_util = CreateObfuscatedFileUtil(/*storage_policy=*/nullptr); - file_util->InitOriginDatabase(Origin(), true /*create*/); + file_util->InitOriginDatabase(url::Origin(), true /*create*/); file_util->db_flush_delay_seconds_ = 0; file_util->MarkUsed(); } @@ -733,31 +739,29 @@ class ObfuscatedFileUtilTest : public testing::Test, } void DestroyDirectoryDatabase_IsolatedTestBody() { - storage_policy_->AddIsolated(origin_.GetURL()); + storage_policy_->AddIsolated(storage_key_.origin().GetURL()); std::unique_ptr<ObfuscatedFileUtil> file_util = CreateObfuscatedFileUtil(/*storage_policy=*/storage_policy_); const FileSystemURL url = FileSystemURL::CreateForTest( - blink::StorageKey(url::Origin(origin_)), kFileSystemTypePersistent, - base::FilePath()); + storage_key_, kFileSystemTypePersistent, base::FilePath()); // Create DirectoryDatabase for isolated origin. SandboxDirectoryDatabase* db = file_util->GetDirectoryDatabase(url, true /* create */); ASSERT_TRUE(db != nullptr); - // Destory it. - file_util->DestroyDirectoryDatabase(url.origin(), + // Destroy it. + file_util->DestroyDirectoryDatabase(url.storage_key(), GetTypeString(url.type())); ASSERT_TRUE(file_util->directories_.empty()); } void GetDirectoryDatabase_IsolatedTestBody() { - storage_policy_->AddIsolated(origin_.GetURL()); + storage_policy_->AddIsolated(storage_key_.origin().GetURL()); std::unique_ptr<ObfuscatedFileUtil> file_util = CreateObfuscatedFileUtil(storage_policy_); const FileSystemURL url = FileSystemURL::CreateForTest( - blink::StorageKey(url::Origin(origin_)), kFileSystemTypePersistent, - base::FilePath()); + storage_key_, kFileSystemTypePersistent, base::FilePath()); // Create DirectoryDatabase for isolated origin. SandboxDirectoryDatabase* db = @@ -775,7 +779,7 @@ class ObfuscatedFileUtilTest : public testing::Test, } int64_t ComputeCurrentUsage() { - return sandbox_file_system_.ComputeCurrentOriginUsage() - + return sandbox_file_system_.ComputeCurrentStorageKeyUsage() - sandbox_file_system_.ComputeCurrentDirectoryDatabaseUsage(); } @@ -800,7 +804,7 @@ class ObfuscatedFileUtilTest : public testing::Test, scoped_refptr<MockSpecialStoragePolicy> storage_policy_; scoped_refptr<QuotaManager> quota_manager_; scoped_refptr<FileSystemContext> file_system_context_; - Origin origin_; + blink::StorageKey storage_key_; FileSystemType type_; SandboxFileSystemTestHelper sandbox_file_system_; blink::mojom::QuotaStatusCode quota_status_; @@ -1561,12 +1565,12 @@ TEST_P(ObfuscatedFileUtilTest, TestEnumerator) { EXPECT_FALSE(DirectoryExists(dest_url)); } -TEST_P(ObfuscatedFileUtilTest, TestOriginEnumerator) { - std::unique_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enumerator = - ofu()->CreateOriginEnumerator(); +TEST_P(ObfuscatedFileUtilTest, TestStorageKeyEnumerator) { + std::unique_ptr<ObfuscatedFileUtil::AbstractStorageKeyEnumerator> enumerator = + ofu()->CreateStorageKeyEnumerator(); // The test helper starts out with a single filesystem. EXPECT_TRUE(enumerator.get()); - EXPECT_EQ(origin(), enumerator->Next()); + EXPECT_EQ(storage_key(), enumerator->Next()); ASSERT_TRUE(type() == kFileSystemTypeTemporary); EXPECT_TRUE(HasFileSystemType(enumerator.get(), kFileSystemTypeTemporary)); EXPECT_FALSE(HasFileSystemType(enumerator.get(), kFileSystemTypePersistent)); @@ -1574,19 +1578,20 @@ TEST_P(ObfuscatedFileUtilTest, TestOriginEnumerator) { EXPECT_FALSE(HasFileSystemType(enumerator.get(), kFileSystemTypeTemporary)); EXPECT_FALSE(HasFileSystemType(enumerator.get(), kFileSystemTypePersistent)); - std::set<Origin> origins_expected; - origins_expected.insert(origin()); + std::set<blink::StorageKey> storage_keys_expected; + storage_keys_expected.insert(storage_key()); for (size_t i = 0; i < base::size(kOriginEnumerationTestRecords); ++i) { SCOPED_TRACE(testing::Message() << "Validating kOriginEnumerationTestRecords " << i); const OriginEnumerationTestRecord& record = kOriginEnumerationTestRecords[i]; - Origin origin = Origin::Create(GURL(record.origin_url)); - origins_expected.insert(origin); + blink::StorageKey storage_key = + blink::StorageKey::CreateFromStringForTesting(record.origin_url); + storage_keys_expected.insert(storage_key); if (record.has_temporary) { std::unique_ptr<SandboxFileSystemTestHelper> file_system = - NewFileSystem(origin, kFileSystemTypeTemporary); + NewFileSystem(storage_key.origin(), kFileSystemTypeTemporary); std::unique_ptr<FileSystemOperationContext> context( NewContext(file_system.get())); bool created = false; @@ -1598,7 +1603,7 @@ TEST_P(ObfuscatedFileUtilTest, TestOriginEnumerator) { } if (record.has_persistent) { std::unique_ptr<SandboxFileSystemTestHelper> file_system = - NewFileSystem(origin, kFileSystemTypePersistent); + NewFileSystem(storage_key.origin(), kFileSystemTypePersistent); std::unique_ptr<FileSystemOperationContext> context( NewContext(file_system.get())); bool created = false; @@ -1609,17 +1614,18 @@ TEST_P(ObfuscatedFileUtilTest, TestOriginEnumerator) { EXPECT_TRUE(created); } } - enumerator = ofu()->CreateOriginEnumerator(); + enumerator = ofu()->CreateStorageKeyEnumerator(); EXPECT_TRUE(enumerator.get()); - std::set<Origin> origins_found; - absl::optional<url::Origin> enumerator_origin; - while ((enumerator_origin = enumerator->Next()).has_value()) { - origins_found.insert(enumerator_origin.value()); + std::set<blink::StorageKey> storage_keys_found; + absl::optional<blink::StorageKey> enumerator_storage_key; + while ((enumerator_storage_key = enumerator->Next()).has_value()) { + storage_keys_found.insert(enumerator_storage_key.value()); SCOPED_TRACE(testing::Message() - << "Handling " << enumerator_origin->Serialize()); + << "Handling " + << enumerator_storage_key->origin().Serialize()); bool found = false; for (const auto& record : kOriginEnumerationTestRecords) { - if (enumerator_origin->GetURL() != record.origin_url) + if (enumerator_storage_key->origin().GetURL() != record.origin_url) continue; found = true; EXPECT_EQ(record.has_temporary, @@ -1628,7 +1634,7 @@ TEST_P(ObfuscatedFileUtilTest, TestOriginEnumerator) { HasFileSystemType(enumerator.get(), kFileSystemTypePersistent)); } // Deal with the default filesystem created by the test helper. - if (!found && enumerator_origin == origin()) { + if (!found && enumerator_storage_key == storage_key()) { ASSERT_TRUE(type() == kFileSystemTypeTemporary); EXPECT_TRUE( HasFileSystemType(enumerator.get(), kFileSystemTypeTemporary)); @@ -1639,10 +1645,11 @@ TEST_P(ObfuscatedFileUtilTest, TestOriginEnumerator) { EXPECT_TRUE(found); } - std::set<Origin> diff; + std::set<blink::StorageKey> diff; std::set_symmetric_difference( - origins_expected.begin(), origins_expected.end(), origins_found.begin(), - origins_found.end(), inserter(diff, diff.begin())); + storage_keys_expected.begin(), storage_keys_expected.end(), + storage_keys_found.begin(), storage_keys_found.end(), + inserter(diff, diff.begin())); EXPECT_TRUE(diff.empty()); } @@ -1713,7 +1720,7 @@ TEST_P(ObfuscatedFileUtilTest, TestInconsistency) { EXPECT_EQ(10, file_info.size); // Destroy database to make inconsistency between database and filesystem. - ofu()->DestroyDirectoryDatabase(origin(), type_string()); + ofu()->DestroyDirectoryDatabase(storage_key(), type_string()); // Try to get file info of broken file. EXPECT_FALSE(PathExists(kPath1)); @@ -1726,16 +1733,16 @@ TEST_P(ObfuscatedFileUtilTest, TestInconsistency) { ofu()->GetFileInfo(context.get(), kPath1, &file_info, &data_path)); EXPECT_EQ(0, file_info.size); - // Make another broken file to |kPath2|. + // Make another broken file to `kPath2`. context = NewContext(nullptr); EXPECT_EQ(base::File::FILE_OK, ofu()->EnsureFileExists(context.get(), kPath2, &created)); EXPECT_TRUE(created); // Destroy again. - ofu()->DestroyDirectoryDatabase(origin(), type_string()); + ofu()->DestroyDirectoryDatabase(storage_key(), type_string()); - // Repair broken |kPath1|. + // Repair broken `kPath1`. context = NewContext(nullptr); EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, ofu()->Touch(context.get(), kPath1, base::Time::Now(), @@ -1744,14 +1751,14 @@ TEST_P(ObfuscatedFileUtilTest, TestInconsistency) { ofu()->EnsureFileExists(context.get(), kPath1, &created)); EXPECT_TRUE(created); - // Copy from sound |kPath1| to broken |kPath2|. + // Copy from sound `kPath1` to broken `kPath2`. context = NewContext(nullptr); EXPECT_EQ( base::File::FILE_OK, ofu()->CopyOrMoveFile(context.get(), kPath1, kPath2, FileSystemOperation::OPTION_NONE, true /* copy */)); - ofu()->DestroyDirectoryDatabase(origin(), type_string()); + ofu()->DestroyDirectoryDatabase(storage_key(), type_string()); context = NewContext(nullptr); created = false; EXPECT_EQ(base::File::FILE_OK, @@ -2001,8 +2008,7 @@ TEST_P(ObfuscatedFileUtilTest, TestFileEnumeratorTimestamp) { context = NewContext(nullptr); EXPECT_EQ(base::File::FILE_OK, ofu()->Touch(context.get(), url1, - base::Time::Now() + base::TimeDelta::FromHours(1), - base::Time())); + base::Time::Now() + base::Hours(1), base::Time())); context = NewContext(nullptr); std::unique_ptr<FileSystemFileUtil::AbstractFileEnumerator> file_enum = @@ -2013,7 +2019,6 @@ TEST_P(ObfuscatedFileUtilTest, TestFileEnumeratorTimestamp) { while (!(file_path_each = file_enum->Next()).empty()) { context = NewContext(nullptr); base::File::Info file_info; - base::FilePath file_path; EXPECT_EQ(base::File::FILE_OK, ofu()->GetFileInfo( context.get(), @@ -2391,138 +2396,148 @@ TEST_P(ObfuscatedFileUtilTest, CreateDirectory_NotADirectoryInRecursive) { } TEST_P(ObfuscatedFileUtilTest, DeleteDirectoryForOriginAndType) { - const Origin origin1 = Origin::Create(GURL("http://www.example.com:12")); - const Origin origin2 = Origin::Create(GURL("http://www.example.com:1234")); - const Origin origin3 = Origin::Create(GURL("http://nope.example.com")); + const blink::StorageKey storage_key1 = + blink::StorageKey::CreateFromStringForTesting( + "http://www.example.com:12"); + const blink::StorageKey storage_key2 = + blink::StorageKey::CreateFromStringForTesting( + "http://www.example.com:1234"); + const blink::StorageKey storage_key3 = + blink::StorageKey::CreateFromStringForTesting("http://nope.example.com"); // Create origin directories. std::unique_ptr<SandboxFileSystemTestHelper> fs1 = - NewFileSystem(origin1, kFileSystemTypeTemporary); + NewFileSystem(storage_key1.origin(), kFileSystemTypeTemporary); std::unique_ptr<SandboxFileSystemTestHelper> fs2 = - NewFileSystem(origin1, kFileSystemTypePersistent); + NewFileSystem(storage_key1.origin(), kFileSystemTypePersistent); std::unique_ptr<SandboxFileSystemTestHelper> fs3 = - NewFileSystem(origin2, kFileSystemTypeTemporary); + NewFileSystem(storage_key2.origin(), kFileSystemTypeTemporary); std::unique_ptr<SandboxFileSystemTestHelper> fs4 = - NewFileSystem(origin2, kFileSystemTypePersistent); + NewFileSystem(storage_key2.origin(), kFileSystemTypePersistent); - // Make sure directories for origin1 exist. + // Make sure directories for storage_key1 exist. base::File::Error error = base::File::FILE_ERROR_FAILED; - ofu()->GetDirectoryForOriginAndType( - origin1, GetTypeString(kFileSystemTypeTemporary), false, &error); + ofu()->GetDirectoryForStorageKeyAndType( + storage_key1, GetTypeString(kFileSystemTypeTemporary), false, &error); ASSERT_EQ(base::File::FILE_OK, error); error = base::File::FILE_ERROR_FAILED; - ofu()->GetDirectoryForOriginAndType( - origin1, GetTypeString(kFileSystemTypePersistent), false, &error); + ofu()->GetDirectoryForStorageKeyAndType( + storage_key1, GetTypeString(kFileSystemTypePersistent), false, &error); ASSERT_EQ(base::File::FILE_OK, error); - // Make sure directories for origin2 exist. + // Make sure directories for storage_key2 exist. error = base::File::FILE_ERROR_FAILED; - ofu()->GetDirectoryForOriginAndType( - origin2, GetTypeString(kFileSystemTypeTemporary), false, &error); + ofu()->GetDirectoryForStorageKeyAndType( + storage_key2, GetTypeString(kFileSystemTypeTemporary), false, &error); ASSERT_EQ(base::File::FILE_OK, error); error = base::File::FILE_ERROR_FAILED; - ofu()->GetDirectoryForOriginAndType( - origin2, GetTypeString(kFileSystemTypePersistent), false, &error); + ofu()->GetDirectoryForStorageKeyAndType( + storage_key2, GetTypeString(kFileSystemTypePersistent), false, &error); ASSERT_EQ(base::File::FILE_OK, error); - // Delete a directory for origin1's persistent filesystem. - ASSERT_TRUE(ofu()->DeleteDirectoryForOriginAndType( - origin1, GetTypeString(kFileSystemTypePersistent))); + // Delete a directory for storage_key1's persistent filesystem. + ASSERT_TRUE(ofu()->DeleteDirectoryForStorageKeyAndType( + storage_key1, GetTypeString(kFileSystemTypePersistent))); - // The directory for origin1's temporary filesystem should not be removed. + // The directory for storage_key1's temporary filesystem should not be + // removed. error = base::File::FILE_ERROR_FAILED; - ofu()->GetDirectoryForOriginAndType( - origin1, GetTypeString(kFileSystemTypeTemporary), false, &error); + ofu()->GetDirectoryForStorageKeyAndType( + storage_key1, GetTypeString(kFileSystemTypeTemporary), false, &error); ASSERT_EQ(base::File::FILE_OK, error); - // The directory for origin1's persistent filesystem should be removed. + // The directory for storage_key1's persistent filesystem should be removed. error = base::File::FILE_ERROR_FAILED; - ofu()->GetDirectoryForOriginAndType( - origin1, GetTypeString(kFileSystemTypePersistent), false, &error); + ofu()->GetDirectoryForStorageKeyAndType( + storage_key1, GetTypeString(kFileSystemTypePersistent), false, &error); ASSERT_EQ(base::File::FILE_ERROR_NOT_FOUND, error); - // The directories for origin2 should not be removed. + // The directories for storage_key2 should not be removed. error = base::File::FILE_ERROR_FAILED; - ofu()->GetDirectoryForOriginAndType( - origin2, GetTypeString(kFileSystemTypeTemporary), false, &error); + ofu()->GetDirectoryForStorageKeyAndType( + storage_key2, GetTypeString(kFileSystemTypeTemporary), false, &error); ASSERT_EQ(base::File::FILE_OK, error); error = base::File::FILE_ERROR_FAILED; - ofu()->GetDirectoryForOriginAndType( - origin2, GetTypeString(kFileSystemTypePersistent), false, &error); + ofu()->GetDirectoryForStorageKeyAndType( + storage_key2, GetTypeString(kFileSystemTypePersistent), false, &error); ASSERT_EQ(base::File::FILE_OK, error); - // Make sure origin3's directories don't exist. + // Make sure storage_key3's directories don't exist. error = base::File::FILE_ERROR_FAILED; - ofu()->GetDirectoryForOriginAndType( - origin3, GetTypeString(kFileSystemTypeTemporary), false, &error); + ofu()->GetDirectoryForStorageKeyAndType( + storage_key3, GetTypeString(kFileSystemTypeTemporary), false, &error); ASSERT_EQ(base::File::FILE_ERROR_NOT_FOUND, error); error = base::File::FILE_ERROR_FAILED; - ofu()->GetDirectoryForOriginAndType( - origin3, GetTypeString(kFileSystemTypePersistent), false, &error); + ofu()->GetDirectoryForStorageKeyAndType( + storage_key3, GetTypeString(kFileSystemTypePersistent), false, &error); ASSERT_EQ(base::File::FILE_ERROR_NOT_FOUND, error); // Deleting directories which don't exist is not an error. - ASSERT_TRUE(ofu()->DeleteDirectoryForOriginAndType( - origin3, GetTypeString(kFileSystemTypeTemporary))); - ASSERT_TRUE(ofu()->DeleteDirectoryForOriginAndType( - origin3, GetTypeString(kFileSystemTypePersistent))); + ASSERT_TRUE(ofu()->DeleteDirectoryForStorageKeyAndType( + storage_key3, GetTypeString(kFileSystemTypeTemporary))); + ASSERT_TRUE(ofu()->DeleteDirectoryForStorageKeyAndType( + storage_key3, GetTypeString(kFileSystemTypePersistent))); } TEST_P(ObfuscatedFileUtilTest, DeleteDirectoryForOriginAndType_DeleteAll) { - const Origin origin1 = Origin::Create(GURL("http://www.example.com:12")); - const Origin origin2 = Origin::Create(GURL("http://www.example.com:1234")); + const blink::StorageKey storage_key1 = + blink::StorageKey::CreateFromStringForTesting( + "http://www.example.com:12"); + const blink::StorageKey storage_key2 = + blink::StorageKey::CreateFromStringForTesting( + "http://www.example.com:1234"); // Create origin directories. std::unique_ptr<SandboxFileSystemTestHelper> fs1 = - NewFileSystem(origin1, kFileSystemTypeTemporary); + NewFileSystem(storage_key1.origin(), kFileSystemTypeTemporary); std::unique_ptr<SandboxFileSystemTestHelper> fs2 = - NewFileSystem(origin1, kFileSystemTypePersistent); + NewFileSystem(storage_key1.origin(), kFileSystemTypePersistent); std::unique_ptr<SandboxFileSystemTestHelper> fs3 = - NewFileSystem(origin2, kFileSystemTypeTemporary); + NewFileSystem(storage_key2.origin(), kFileSystemTypeTemporary); std::unique_ptr<SandboxFileSystemTestHelper> fs4 = - NewFileSystem(origin2, kFileSystemTypePersistent); + NewFileSystem(storage_key2.origin(), kFileSystemTypePersistent); - // Make sure directories for origin1 exist. + // Make sure directories for storage_key1 exist. base::File::Error error = base::File::FILE_ERROR_FAILED; - ofu()->GetDirectoryForOriginAndType( - origin1, GetTypeString(kFileSystemTypeTemporary), false, &error); + ofu()->GetDirectoryForStorageKeyAndType( + storage_key1, GetTypeString(kFileSystemTypeTemporary), false, &error); ASSERT_EQ(base::File::FILE_OK, error); error = base::File::FILE_ERROR_FAILED; - ofu()->GetDirectoryForOriginAndType( - origin1, GetTypeString(kFileSystemTypePersistent), false, &error); + ofu()->GetDirectoryForStorageKeyAndType( + storage_key1, GetTypeString(kFileSystemTypePersistent), false, &error); ASSERT_EQ(base::File::FILE_OK, error); - // Make sure directories for origin2 exist. + // Make sure directories for storage_key2 exist. error = base::File::FILE_ERROR_FAILED; - ofu()->GetDirectoryForOriginAndType( - origin2, GetTypeString(kFileSystemTypeTemporary), false, &error); + ofu()->GetDirectoryForStorageKeyAndType( + storage_key2, GetTypeString(kFileSystemTypeTemporary), false, &error); ASSERT_EQ(base::File::FILE_OK, error); error = base::File::FILE_ERROR_FAILED; - ofu()->GetDirectoryForOriginAndType( - origin2, GetTypeString(kFileSystemTypePersistent), false, &error); + ofu()->GetDirectoryForStorageKeyAndType( + storage_key2, GetTypeString(kFileSystemTypePersistent), false, &error); ASSERT_EQ(base::File::FILE_OK, error); - // Delete all directories for origin1. - ofu()->DeleteDirectoryForOriginAndType(origin1, std::string()); + // Delete all directories for storage_key1. + ofu()->DeleteDirectoryForStorageKeyAndType(storage_key1, std::string()); - // The directories for origin1 should be removed. + // The directories for storage_key1 should be removed. error = base::File::FILE_ERROR_FAILED; - ofu()->GetDirectoryForOriginAndType( - origin1, GetTypeString(kFileSystemTypeTemporary), false, &error); + ofu()->GetDirectoryForStorageKeyAndType( + storage_key1, GetTypeString(kFileSystemTypeTemporary), false, &error); ASSERT_EQ(base::File::FILE_ERROR_NOT_FOUND, error); error = base::File::FILE_ERROR_FAILED; - ofu()->GetDirectoryForOriginAndType( - origin1, GetTypeString(kFileSystemTypePersistent), false, &error); + ofu()->GetDirectoryForStorageKeyAndType( + storage_key1, GetTypeString(kFileSystemTypePersistent), false, &error); ASSERT_EQ(base::File::FILE_ERROR_NOT_FOUND, error); - // The directories for origin2 should not be removed. + // The directories for storage_key2 should not be removed. error = base::File::FILE_ERROR_FAILED; - ofu()->GetDirectoryForOriginAndType( - origin2, GetTypeString(kFileSystemTypeTemporary), false, &error); + ofu()->GetDirectoryForStorageKeyAndType( + storage_key2, GetTypeString(kFileSystemTypeTemporary), false, &error); ASSERT_EQ(base::File::FILE_OK, error); error = base::File::FILE_ERROR_FAILED; - ofu()->GetDirectoryForOriginAndType( - origin2, GetTypeString(kFileSystemTypePersistent), false, &error); + ofu()->GetDirectoryForStorageKeyAndType( + storage_key2, GetTypeString(kFileSystemTypePersistent), false, &error); ASSERT_EQ(base::File::FILE_OK, error); } 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 ebad1e2a749..280ec770154 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 @@ -87,7 +87,11 @@ base::File::Error OpenFileSystemOnFileTaskRunner( OpenFileSystemMode mode) { base::File::Error error = base::File::FILE_ERROR_FAILED; const bool create = (mode == OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT); - file_util->GetDirectoryForOriginAndType(origin, plugin_id, create, &error); + // TODO(https://crbug.com/1231162): determine whether EME/CDM/plugin private + // file system will be partitioned; if so, replace the in-line conversion with + // the correct third-party StorageKey. + file_util->GetDirectoryForStorageKeyAndType(blink::StorageKey(origin), + plugin_id, create, &error); if (error == base::File::FILE_OK) plugin_map->RegisterFileSystem(filesystem_id, plugin_id); return error; @@ -180,12 +184,13 @@ PluginPrivateFileSystemBackend::GetCopyOrMoveFileValidatorFactory( return nullptr; } -FileSystemOperation* PluginPrivateFileSystemBackend::CreateFileSystemOperation( +std::unique_ptr<FileSystemOperation> +PluginPrivateFileSystemBackend::CreateFileSystemOperation( const FileSystemURL& url, FileSystemContext* context, base::File::Error* error_code) const { - std::unique_ptr<FileSystemOperationContext> operation_context( - std::make_unique<FileSystemOperationContext>(context)); + auto operation_context = + std::make_unique<FileSystemOperationContext>(context); return FileSystemOperation::Create(url, context, std::move(operation_context)); } @@ -232,15 +237,15 @@ FileSystemQuotaUtil* PluginPrivateFileSystemBackend::GetQuotaUtil() { } base::File::Error -PluginPrivateFileSystemBackend::DeleteOriginDataOnFileTaskRunner( +PluginPrivateFileSystemBackend::DeleteStorageKeyDataOnFileTaskRunner( FileSystemContext* context, QuotaManagerProxy* proxy, - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type) { if (!CanHandleType(type)) return base::File::FILE_ERROR_SECURITY; - bool result = obfuscated_file_util()->DeleteDirectoryForOriginAndType( - origin, std::string()); + bool result = obfuscated_file_util()->DeleteDirectoryForStorageKeyAndType( + storage_key, std::string()); if (result) return base::File::FILE_OK; return base::File::FILE_ERROR_FAILED; @@ -255,40 +260,40 @@ void PluginPrivateFileSystemBackend::PerformStorageCleanupOnFileTaskRunner( obfuscated_file_util()->RewriteDatabases(); } -std::vector<url::Origin> -PluginPrivateFileSystemBackend::GetOriginsForTypeOnFileTaskRunner( +std::vector<blink::StorageKey> +PluginPrivateFileSystemBackend::GetStorageKeysForTypeOnFileTaskRunner( FileSystemType type) { if (!CanHandleType(type)) - return std::vector<url::Origin>(); - std::unique_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enumerator( - obfuscated_file_util()->CreateOriginEnumerator()); - std::vector<url::Origin> origins; - absl::optional<url::Origin> origin; - while ((origin = enumerator->Next()).has_value()) - origins.push_back(std::move(origin).value()); - return origins; + return std::vector<blink::StorageKey>(); + std::unique_ptr<ObfuscatedFileUtil::AbstractStorageKeyEnumerator> enumerator( + obfuscated_file_util()->CreateStorageKeyEnumerator()); + std::vector<blink::StorageKey> storage_keys; + absl::optional<blink::StorageKey> storage_key; + while ((storage_key = enumerator->Next()).has_value()) + storage_keys.push_back(std::move(storage_key).value()); + return storage_keys; } -std::vector<url::Origin> -PluginPrivateFileSystemBackend::GetOriginsForHostOnFileTaskRunner( +std::vector<blink::StorageKey> +PluginPrivateFileSystemBackend::GetStorageKeysForHostOnFileTaskRunner( FileSystemType type, const std::string& host) { if (!CanHandleType(type)) - return std::vector<url::Origin>(); - std::unique_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enumerator( - obfuscated_file_util()->CreateOriginEnumerator()); - std::vector<url::Origin> origins; - absl::optional<url::Origin> origin; - while ((origin = enumerator->Next()).has_value()) { - if (host == origin->host()) - origins.push_back(std::move(origin).value()); + return std::vector<blink::StorageKey>(); + std::unique_ptr<ObfuscatedFileUtil::AbstractStorageKeyEnumerator> enumerator( + obfuscated_file_util()->CreateStorageKeyEnumerator()); + std::vector<blink::StorageKey> storage_keys; + absl::optional<blink::StorageKey> storage_key; + while ((storage_key = enumerator->Next()).has_value()) { + if (host == storage_key->origin().host()) + storage_keys.push_back(std::move(storage_key).value()); } - return origins; + return storage_keys; } -int64_t PluginPrivateFileSystemBackend::GetOriginUsageOnFileTaskRunner( +int64_t PluginPrivateFileSystemBackend::GetStorageKeyUsageOnFileTaskRunner( FileSystemContext* context, - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type) { DCHECK(file_task_runner_->RunsTasksInCurrentSequence()); @@ -297,7 +302,7 @@ int64_t PluginPrivateFileSystemBackend::GetOriginUsageOnFileTaskRunner( int64_t total_size; base::Time last_modified_time; - GetOriginDetailsOnFileTaskRunner(context, origin, &total_size, + GetOriginDetailsOnFileTaskRunner(context, storage_key.origin(), &total_size, &last_modified_time); return total_size; } @@ -329,8 +334,12 @@ void PluginPrivateFileSystemBackend::GetOriginDetailsOnFileTaskRunner( // application_x-ppapi-widevine-cdm). Enumerate through the set of // directories so that data from any CDM used by this origin is counted. base::File::Error error; - base::FilePath path = obfuscated_file_util()->GetDirectoryForOriginAndType( - origin, "", false, &error); + // TODO(https://crbug.com/1231162): determine whether EME/CDM/plugin private + // file system will be partitioned; if so, replace the in-line conversion with + // the correct third-party StorageKey. + base::FilePath path = + obfuscated_file_util()->GetDirectoryForStorageKeyAndType( + blink::StorageKey(origin), "", false, &error); if (error != base::File::FILE_OK) { DLOG(ERROR) << "Unable to read directory for " << origin; return; @@ -366,7 +375,7 @@ void PluginPrivateFileSystemBackend::GetOriginDetailsOnFileTaskRunner( scoped_refptr<QuotaReservation> PluginPrivateFileSystemBackend::CreateQuotaReservationOnFileTaskRunner( - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type) { // We don't track usage on this filesystem. NOTREACHED(); diff --git a/chromium/storage/browser/file_system/plugin_private_file_system_backend.h b/chromium/storage/browser/file_system/plugin_private_file_system_backend.h index 0394ffbae24..5d02bc4b8f6 100644 --- a/chromium/storage/browser/file_system/plugin_private_file_system_backend.h +++ b/chromium/storage/browser/file_system/plugin_private_file_system_backend.h @@ -22,15 +22,19 @@ namespace base { class SequencedTaskRunner; -} +} // namespace base + +namespace blink { +class StorageKey; +} // namespace blink namespace leveldb { class Env; -} +} // namespace leveldb namespace url { class Origin; -} +} // namespace url namespace storage { @@ -52,6 +56,12 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) PluginPrivateFileSystemBackend scoped_refptr<SpecialStoragePolicy> special_storage_policy, const FileSystemOptions& file_system_options, leveldb::Env* env_override); + + PluginPrivateFileSystemBackend(const PluginPrivateFileSystemBackend&) = + delete; + PluginPrivateFileSystemBackend& operator=( + const PluginPrivateFileSystemBackend&) = delete; + ~PluginPrivateFileSystemBackend() override; // This must be used to open 'private' filesystem instead of regular @@ -78,7 +88,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) PluginPrivateFileSystemBackend CopyOrMoveFileValidatorFactory* GetCopyOrMoveFileValidatorFactory( FileSystemType type, base::File::Error* error_code) override; - FileSystemOperation* CreateFileSystemOperation( + std::unique_ptr<FileSystemOperation> CreateFileSystemOperation( const FileSystemURL& url, FileSystemContext* context, base::File::Error* error_code) const override; @@ -103,24 +113,25 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) PluginPrivateFileSystemBackend FileSystemType type) const override; // FileSystemQuotaUtil overrides. - base::File::Error DeleteOriginDataOnFileTaskRunner( + base::File::Error DeleteStorageKeyDataOnFileTaskRunner( FileSystemContext* context, QuotaManagerProxy* proxy, - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type) override; void PerformStorageCleanupOnFileTaskRunner(FileSystemContext* context, QuotaManagerProxy* proxy, FileSystemType type) override; - std::vector<url::Origin> GetOriginsForTypeOnFileTaskRunner( + std::vector<blink::StorageKey> GetStorageKeysForTypeOnFileTaskRunner( FileSystemType type) override; - std::vector<url::Origin> GetOriginsForHostOnFileTaskRunner( + std::vector<blink::StorageKey> GetStorageKeysForHostOnFileTaskRunner( FileSystemType type, const std::string& host) override; - int64_t GetOriginUsageOnFileTaskRunner(FileSystemContext* context, - const url::Origin& origin, - FileSystemType type) override; + int64_t GetStorageKeyUsageOnFileTaskRunner( + FileSystemContext* context, + const blink::StorageKey& storage_key, + FileSystemType type) override; scoped_refptr<QuotaReservation> CreateQuotaReservationOnFileTaskRunner( - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type) override; // Get details on the files saved for the specified |origin_url|. Returns @@ -146,8 +157,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) PluginPrivateFileSystemBackend std::unique_ptr<AsyncFileUtil> file_util_; FileSystemIDToPluginMap* plugin_map_; // Owned by file_util_. base::WeakPtrFactory<PluginPrivateFileSystemBackend> weak_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(PluginPrivateFileSystemBackend); }; } // namespace storage diff --git a/chromium/storage/browser/file_system/plugin_private_file_system_backend_unittest.cc b/chromium/storage/browser/file_system/plugin_private_file_system_backend_unittest.cc index 56495593a65..f162888f09a 100644 --- a/chromium/storage/browser/file_system/plugin_private_file_system_backend_unittest.cc +++ b/chromium/storage/browser/file_system/plugin_private_file_system_backend_unittest.cc @@ -186,13 +186,16 @@ TEST_F(PluginPrivateFileSystemBackendTest, OriginIsolation) { } TEST_F(PluginPrivateFileSystemBackendTest, DeleteOriginDirectory) { - const Origin kOrigin1 = Origin::Create(GURL("http://www.example.com")); - const Origin kOrigin2 = Origin::Create(GURL("https://www.example.com")); + const blink::StorageKey kStorageKey1 = + blink::StorageKey::CreateFromStringForTesting("http://www.example.com"); + const blink::StorageKey kStorageKey2 = + blink::StorageKey::CreateFromStringForTesting("https://www.example.com"); - // Open filesystem for kOrigin1 and kOrigin2. + // Open filesystem for kStorageKey1.origin() and kStorageKey2.origin(). const std::string filesystem_id1 = RegisterFileSystem(); base::File::Error error = base::File::FILE_ERROR_FAILED; - backend()->OpenPrivateFileSystem(kOrigin1, kType, filesystem_id1, kPlugin1, + backend()->OpenPrivateFileSystem(kStorageKey1.origin(), kType, filesystem_id1, + kPlugin1, OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT, base::BindOnce(&DidOpenFileSystem, &error)); base::RunLoop().RunUntilIdle(); @@ -200,62 +203,64 @@ TEST_F(PluginPrivateFileSystemBackendTest, DeleteOriginDirectory) { const std::string filesystem_id2 = RegisterFileSystem(); error = base::File::FILE_ERROR_FAILED; - backend()->OpenPrivateFileSystem(kOrigin2, kType, filesystem_id2, kPlugin1, + backend()->OpenPrivateFileSystem(kStorageKey2.origin(), kType, filesystem_id2, + kPlugin1, OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT, base::BindOnce(&DidOpenFileSystem, &error)); base::RunLoop().RunUntilIdle(); ASSERT_EQ(base::File::FILE_OK, error); - // Create 'foo' in kOrigin1. + // Create 'foo' in kStorageKey1.origin(). const GURL root_url1(GetIsolatedFileSystemRootURIString( - kOrigin1.GetURL(), filesystem_id1, kRootName)); + kStorageKey1.origin().GetURL(), filesystem_id1, kRootName)); FileSystemURL file1 = CreateURL(root_url1, "foo"); EXPECT_EQ(base::File::FILE_OK, AsyncFileTestHelper::CreateFile(context_.get(), file1)); EXPECT_TRUE(AsyncFileTestHelper::FileExists( context_.get(), file1, AsyncFileTestHelper::kDontCheckSize)); - // Create 'foo' in kOrigin2. + // Create 'foo' in kStorageKey2.origin(). const GURL root_url2(GetIsolatedFileSystemRootURIString( - kOrigin2.GetURL(), filesystem_id2, kRootName)); + kStorageKey2.origin().GetURL(), filesystem_id2, kRootName)); FileSystemURL file2 = CreateURL(root_url2, "foo"); EXPECT_EQ(base::File::FILE_OK, AsyncFileTestHelper::CreateFile(context_.get(), file2)); EXPECT_TRUE(AsyncFileTestHelper::FileExists( context_.get(), file2, AsyncFileTestHelper::kDontCheckSize)); - // Delete data for kOrigin1. - error = backend()->DeleteOriginDataOnFileTaskRunner(context_.get(), nullptr, - kOrigin1, kType); + // Delete data for kStorageKey1.origin(). + error = backend()->DeleteStorageKeyDataOnFileTaskRunner( + context_.get(), nullptr, kStorageKey1, kType); EXPECT_EQ(base::File::FILE_OK, error); - // Confirm 'foo' in kOrigin1 is deleted. + // Confirm 'foo' in kStorageKey1.origin() is deleted. EXPECT_FALSE(AsyncFileTestHelper::FileExists( context_.get(), file1, AsyncFileTestHelper::kDontCheckSize)); - // Confirm 'foo' in kOrigin2 is NOT deleted. + // Confirm 'foo' in kStorageKey2.origin() is NOT deleted. EXPECT_TRUE(AsyncFileTestHelper::FileExists( context_.get(), file2, AsyncFileTestHelper::kDontCheckSize)); - // Re-open filesystem for kOrigin1. + // Re-open filesystem for kStorageKey1.origin(). const std::string filesystem_id3 = RegisterFileSystem(); error = base::File::FILE_ERROR_FAILED; - backend()->OpenPrivateFileSystem(kOrigin1, kType, filesystem_id3, kPlugin1, + backend()->OpenPrivateFileSystem(kStorageKey1.origin(), kType, filesystem_id3, + kPlugin1, OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT, base::BindOnce(&DidOpenFileSystem, &error)); base::RunLoop().RunUntilIdle(); ASSERT_EQ(base::File::FILE_OK, error); - // Re-create 'foo' in kOrigin1. + // Re-create 'foo' in kStorageKey1.origin(). const GURL root_url3(GetIsolatedFileSystemRootURIString( - kOrigin1.GetURL(), filesystem_id3, kRootName)); + kStorageKey1.origin().GetURL(), filesystem_id3, kRootName)); FileSystemURL file3 = CreateURL(root_url3, "foo"); EXPECT_EQ(base::File::FILE_OK, AsyncFileTestHelper::CreateFile(context_.get(), file3)); EXPECT_TRUE(AsyncFileTestHelper::FileExists( context_.get(), file3, AsyncFileTestHelper::kDontCheckSize)); - // Confirm 'foo' in kOrigin1 is re-created. + // Confirm 'foo' in kStorageKey1.origin() is re-created. EXPECT_TRUE(AsyncFileTestHelper::FileExists( context_.get(), file3, AsyncFileTestHelper::kDontCheckSize)); } diff --git a/chromium/storage/browser/file_system/quota/open_file_handle.h b/chromium/storage/browser/file_system/quota/open_file_handle.h index cfbeea32c2e..7a3aa621829 100644 --- a/chromium/storage/browser/file_system/quota/open_file_handle.h +++ b/chromium/storage/browser/file_system/quota/open_file_handle.h @@ -27,6 +27,9 @@ class QuotaReservationBuffer; // deleted when the plugin closes the file. class COMPONENT_EXPORT(STORAGE_BROWSER) OpenFileHandle { public: + OpenFileHandle(const OpenFileHandle&) = delete; + OpenFileHandle& operator=(const OpenFileHandle&) = delete; + ~OpenFileHandle(); // Updates cached file size and consumes quota for that. @@ -62,8 +65,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) OpenFileHandle { scoped_refptr<OpenFileHandleContext> context_; base::SequenceChecker sequence_checker_; - - DISALLOW_COPY_AND_ASSIGN(OpenFileHandle); }; } // namespace storage diff --git a/chromium/storage/browser/file_system/quota/quota_backend_impl.cc b/chromium/storage/browser/file_system/quota/quota_backend_impl.cc index d079fd2d12f..a48eeb45947 100644 --- a/chromium/storage/browser/file_system/quota/quota_backend_impl.cc +++ b/chromium/storage/browser/file_system/quota/quota_backend_impl.cc @@ -157,8 +157,8 @@ base::File::Error QuotaBackendImpl::GetUsageCachePath( DCHECK(usage_file_path); base::File::Error error = base::File::FILE_OK; *usage_file_path = - SandboxFileSystemBackendDelegate::GetUsageCachePathForOriginAndType( - obfuscated_file_util_, origin, type, &error); + SandboxFileSystemBackendDelegate::GetUsageCachePathForStorageKeyAndType( + obfuscated_file_util_, blink::StorageKey(origin), type, &error); return error; } diff --git a/chromium/storage/browser/file_system/quota/quota_backend_impl.h b/chromium/storage/browser/file_system/quota/quota_backend_impl.h index 151b4d6e7da..c5a66224a5b 100644 --- a/chromium/storage/browser/file_system/quota/quota_backend_impl.h +++ b/chromium/storage/browser/file_system/quota/quota_backend_impl.h @@ -36,6 +36,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaBackendImpl ObfuscatedFileUtil* obfuscated_file_util, FileSystemUsageCache* file_system_usage_cache, scoped_refptr<QuotaManagerProxy> quota_manager_proxy); + + QuotaBackendImpl(const QuotaBackendImpl&) = delete; + QuotaBackendImpl& operator=(const QuotaBackendImpl&) = delete; + ~QuotaBackendImpl() override; // QuotaReservationManager::QuotaBackend overrides. @@ -88,8 +92,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaBackendImpl const scoped_refptr<QuotaManagerProxy> quota_manager_proxy_; base::WeakPtrFactory<QuotaBackendImpl> weak_ptr_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(QuotaBackendImpl); }; } // namespace storage diff --git a/chromium/storage/browser/file_system/quota/quota_backend_impl_unittest.cc b/chromium/storage/browser/file_system/quota/quota_backend_impl_unittest.cc index b48a4d0e74c..cf8eddfd823 100644 --- a/chromium/storage/browser/file_system/quota/quota_backend_impl_unittest.cc +++ b/chromium/storage/browser/file_system/quota/quota_backend_impl_unittest.cc @@ -23,6 +23,7 @@ #include "storage/browser/file_system/obfuscated_file_util.h" #include "storage/browser/quota/quota_manager_proxy.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/leveldatabase/leveldb_chrome.h" namespace storage { @@ -134,8 +135,8 @@ class QuotaBackendImplTest : public testing::Test, std::string type_string = SandboxFileSystemBackendDelegate::GetTypeString(type); base::File::Error error = base::File::FILE_ERROR_FAILED; - base::FilePath path = file_util_->GetDirectoryForOriginAndType( - origin, type_string, true /* create */, &error); + base::FilePath path = file_util_->GetDirectoryForStorageKeyAndType( + blink::StorageKey(origin), type_string, true /* create */, &error); ASSERT_EQ(base::File::FILE_OK, error); ASSERT_TRUE(file_system_usage_cache_.UpdateUsage( diff --git a/chromium/storage/browser/file_system/quota/quota_reservation_manager.h b/chromium/storage/browser/file_system/quota/quota_reservation_manager.h index 74077e504ab..2c1463d85fb 100644 --- a/chromium/storage/browser/file_system/quota/quota_reservation_manager.h +++ b/chromium/storage/browser/file_system/quota/quota_reservation_manager.h @@ -39,6 +39,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaReservationManager { class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaBackend { public: QuotaBackend() = default; + + QuotaBackend(const QuotaBackend&) = delete; + QuotaBackend& operator=(const QuotaBackend&) = delete; + virtual ~QuotaBackend() = default; // Reserves or reclaims |delta| of quota for |origin| and |type| pair. @@ -67,12 +71,13 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaReservationManager { FileSystemType type) = 0; virtual void DecrementDirtyCount(const url::Origin& origin, FileSystemType type) = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(QuotaBackend); }; explicit QuotaReservationManager(std::unique_ptr<QuotaBackend> backend); + + QuotaReservationManager(const QuotaReservationManager&) = delete; + QuotaReservationManager& operator=(const QuotaReservationManager&) = delete; + ~QuotaReservationManager(); // The entry point of the quota reservation. Creates new reservation object @@ -117,8 +122,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaReservationManager { base::SequenceChecker sequence_checker_; base::WeakPtrFactory<QuotaReservationManager> weak_ptr_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(QuotaReservationManager); }; } // namespace storage diff --git a/chromium/storage/browser/file_system/quota/quota_reservation_manager_unittest.cc b/chromium/storage/browser/file_system/quota/quota_reservation_manager_unittest.cc index f588e185d30..42b4605a69a 100644 --- a/chromium/storage/browser/file_system/quota/quota_reservation_manager_unittest.cc +++ b/chromium/storage/browser/file_system/quota/quota_reservation_manager_unittest.cc @@ -49,6 +49,10 @@ void SetFileSize(const base::FilePath& path, int64_t size) { class FakeBackend : public QuotaReservationManager::QuotaBackend { public: FakeBackend() = default; + + FakeBackend(const FakeBackend&) = delete; + FakeBackend& operator=(const FakeBackend&) = delete; + ~FakeBackend() override = default; void ReserveQuota(const url::Origin& origin, @@ -94,8 +98,6 @@ class FakeBackend : public QuotaReservationManager::QuotaBackend { const url::Origin origin_ = url::Origin::Create(GURL("http://example.com")); int64_t on_memory_usage_ = kInitialFileSize; int64_t on_disk_usage_ = kInitialFileSize; - - DISALLOW_COPY_AND_ASSIGN(FakeBackend); }; class FakeWriter { @@ -181,6 +183,11 @@ void RefreshReservation(QuotaReservation* reservation, int64_t size) { class QuotaReservationManagerTest : public testing::Test { public: QuotaReservationManagerTest() = default; + + QuotaReservationManagerTest(const QuotaReservationManagerTest&) = delete; + QuotaReservationManagerTest& operator=(const QuotaReservationManagerTest&) = + delete; + ~QuotaReservationManagerTest() override = default; void SetUp() override { @@ -215,8 +222,6 @@ class QuotaReservationManagerTest : public testing::Test { base::ScopedTempDir work_dir_; base::FilePath file_path_; std::unique_ptr<QuotaReservationManager> reservation_manager_; - - DISALLOW_COPY_AND_ASSIGN(QuotaReservationManagerTest); }; TEST_F(QuotaReservationManagerTest, BasicTest) { diff --git a/chromium/storage/browser/file_system/recursive_operation_delegate.h b/chromium/storage/browser/file_system/recursive_operation_delegate.h index f9c90589143..bec65aacab3 100644 --- a/chromium/storage/browser/file_system/recursive_operation_delegate.h +++ b/chromium/storage/browser/file_system/recursive_operation_delegate.h @@ -31,6 +31,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) RecursiveOperationDelegate using FileEntryList = FileSystemOperation::FileEntryList; using ErrorBehavior = FileSystemOperation::ErrorBehavior; + RecursiveOperationDelegate(const RecursiveOperationDelegate&) = delete; + RecursiveOperationDelegate& operator=(const RecursiveOperationDelegate&) = + delete; + virtual ~RecursiveOperationDelegate(); // This is called when the consumer of this instance starts a non-recursive @@ -149,8 +153,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) RecursiveOperationDelegate bool canceled_; ErrorBehavior error_behavior_; bool failed_some_operations_; - - DISALLOW_COPY_AND_ASSIGN(RecursiveOperationDelegate); }; } // namespace storage diff --git a/chromium/storage/browser/file_system/recursive_operation_delegate_unittest.cc b/chromium/storage/browser/file_system/recursive_operation_delegate_unittest.cc index cd4c1f2e310..55f079e587d 100644 --- a/chromium/storage/browser/file_system/recursive_operation_delegate_unittest.cc +++ b/chromium/storage/browser/file_system/recursive_operation_delegate_unittest.cc @@ -43,6 +43,11 @@ class LoggingRecursiveOperation : public RecursiveOperationDelegate { : RecursiveOperationDelegate(file_system_context), root_(root), callback_(std::move(callback)) {} + + LoggingRecursiveOperation(const LoggingRecursiveOperation&) = delete; + LoggingRecursiveOperation& operator=(const LoggingRecursiveOperation&) = + delete; + ~LoggingRecursiveOperation() override = default; const std::vector<LogEntry>& log_entries() const { return log_entries_; } @@ -115,7 +120,6 @@ class LoggingRecursiveOperation : public RecursiveOperationDelegate { FileSystemURL error_url_; base::WeakPtrFactory<LoggingRecursiveOperation> weak_factory_{this}; - DISALLOW_COPY_AND_ASSIGN(LoggingRecursiveOperation); }; void ReportStatus(base::File::Error* out_error, base::File::Error error) { diff --git a/chromium/storage/browser/file_system/remove_operation_delegate.h b/chromium/storage/browser/file_system/remove_operation_delegate.h index c96eb69b71f..f1a2bbfc037 100644 --- a/chromium/storage/browser/file_system/remove_operation_delegate.h +++ b/chromium/storage/browser/file_system/remove_operation_delegate.h @@ -15,6 +15,10 @@ class RemoveOperationDelegate : public RecursiveOperationDelegate { RemoveOperationDelegate(FileSystemContext* file_system_context, const FileSystemURL& url, StatusCallback callback); + + RemoveOperationDelegate(const RemoveOperationDelegate&) = delete; + RemoveOperationDelegate& operator=(const RemoveOperationDelegate&) = delete; + ~RemoveOperationDelegate() override; // RecursiveOperationDelegate overrides: @@ -38,7 +42,6 @@ class RemoveOperationDelegate : public RecursiveOperationDelegate { FileSystemURL url_; StatusCallback callback_; base::WeakPtrFactory<RemoveOperationDelegate> weak_factory_{this}; - DISALLOW_COPY_AND_ASSIGN(RemoveOperationDelegate); }; } // namespace storage diff --git a/chromium/storage/browser/file_system/sandbox_directory_database.cc b/chromium/storage/browser/file_system/sandbox_directory_database.cc index c4976a5ec09..2539ab30527 100644 --- a/chromium/storage/browser/file_system/sandbox_directory_database.cc +++ b/chromium/storage/browser/file_system/sandbox_directory_database.cc @@ -357,7 +357,6 @@ bool DatabaseCheckHelper::ScanHierarchy() { return false; // Check if the child knows the parent as its parent. - FileInfo file_info; if (!dir_db_->GetFileInfo(id, &file_info)) return false; if (file_info.parent_id != dir_id) @@ -799,7 +798,7 @@ bool SandboxDirectoryDatabase::IsFileSystemConsistent() { void SandboxDirectoryDatabase::ReportInitStatus(const leveldb::Status& status) { base::Time now = base::Time::Now(); const base::TimeDelta minimum_interval = - base::TimeDelta::FromHours(kSandboxDirectoryMinimumReportIntervalHours); + base::Hours(kSandboxDirectoryMinimumReportIntervalHours); if (last_reported_time_ + minimum_interval >= now) return; last_reported_time_ = now; diff --git a/chromium/storage/browser/file_system/sandbox_directory_database.h b/chromium/storage/browser/file_system/sandbox_directory_database.h index c8b9de72f32..5a2d0bacfcc 100644 --- a/chromium/storage/browser/file_system/sandbox_directory_database.h +++ b/chromium/storage/browser/file_system/sandbox_directory_database.h @@ -60,6 +60,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SandboxDirectoryDatabase { SandboxDirectoryDatabase(const base::FilePath& filesystem_data_directory, leveldb::Env* env_override); + + SandboxDirectoryDatabase(const SandboxDirectoryDatabase&) = delete; + SandboxDirectoryDatabase& operator=(const SandboxDirectoryDatabase&) = delete; + ~SandboxDirectoryDatabase(); bool GetChildWithName(FileId parent_id, @@ -125,7 +129,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SandboxDirectoryDatabase { leveldb::Env* env_override_; std::unique_ptr<leveldb::DB> db_; base::Time last_reported_time_; - DISALLOW_COPY_AND_ASSIGN(SandboxDirectoryDatabase); }; } // namespace storage diff --git a/chromium/storage/browser/file_system/sandbox_file_stream_reader.h b/chromium/storage/browser/file_system/sandbox_file_stream_reader.h index 07fe4597d08..7e9722b5bf0 100644 --- a/chromium/storage/browser/file_system/sandbox_file_stream_reader.h +++ b/chromium/storage/browser/file_system/sandbox_file_stream_reader.h @@ -43,6 +43,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SandboxFileStreamReader const FileSystemURL& url, int64_t initial_offset, const base::Time& expected_modification_time); + + SandboxFileStreamReader(const SandboxFileStreamReader&) = delete; + SandboxFileStreamReader& operator=(const SandboxFileStreamReader&) = delete; + ~SandboxFileStreamReader() override; // FileStreamReader overrides. @@ -74,8 +78,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SandboxFileStreamReader scoped_refptr<ShareableFileReference> snapshot_ref_; bool has_pending_create_snapshot_; base::WeakPtrFactory<SandboxFileStreamReader> weak_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(SandboxFileStreamReader); }; } // namespace storage diff --git a/chromium/storage/browser/file_system/sandbox_file_stream_writer.h b/chromium/storage/browser/file_system/sandbox_file_stream_writer.h index ed4414b78a1..00a1c88b508 100644 --- a/chromium/storage/browser/file_system/sandbox_file_stream_writer.h +++ b/chromium/storage/browser/file_system/sandbox_file_stream_writer.h @@ -33,6 +33,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SandboxFileStreamWriter const FileSystemURL& url, int64_t initial_offset, const UpdateObserverList& observers); + + SandboxFileStreamWriter(const SandboxFileStreamWriter&) = delete; + SandboxFileStreamWriter& operator=(const SandboxFileStreamWriter&) = delete; + ~SandboxFileStreamWriter() override; // FileStreamWriter overrides. @@ -91,8 +95,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SandboxFileStreamWriter int64_t default_quota_; base::WeakPtrFactory<SandboxFileStreamWriter> weak_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(SandboxFileStreamWriter); }; } // namespace storage diff --git a/chromium/storage/browser/file_system/sandbox_file_system_backend.cc b/chromium/storage/browser/file_system/sandbox_file_system_backend.cc index 89597058355..8b640d8b472 100644 --- a/chromium/storage/browser/file_system/sandbox_file_system_backend.cc +++ b/chromium/storage/browser/file_system/sandbox_file_system_backend.cc @@ -73,7 +73,7 @@ void SandboxFileSystemBackend::ResolveURL(const FileSystemURL& url, } delegate_->OpenFileSystem( - url.origin(), url.type(), mode, std::move(callback), + url.storage_key(), url.type(), mode, std::move(callback), GetFileSystemRootURI(url.origin().GetURL(), url.type())); } @@ -96,7 +96,8 @@ SandboxFileSystemBackend::GetCopyOrMoveFileValidatorFactory( return nullptr; } -FileSystemOperation* SandboxFileSystemBackend::CreateFileSystemOperation( +std::unique_ptr<FileSystemOperation> +SandboxFileSystemBackend::CreateFileSystemOperation( const FileSystemURL& url, FileSystemContext* context, base::File::Error* error_code) const { @@ -173,10 +174,10 @@ const AccessObserverList* SandboxFileSystemBackend::GetAccessObservers( return delegate_->GetAccessObservers(type); } -SandboxFileSystemBackendDelegate::OriginEnumerator* -SandboxFileSystemBackend::CreateOriginEnumerator() { +SandboxFileSystemBackendDelegate::StorageKeyEnumerator* +SandboxFileSystemBackend::CreateStorageKeyEnumerator() { DCHECK(delegate_); - return delegate_->CreateOriginEnumerator(); + return delegate_->CreateStorageKeyEnumerator(); } } // namespace storage 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 9fdacef3b20..9518e3eb81d 100644 --- a/chromium/storage/browser/file_system/sandbox_file_system_backend.h +++ b/chromium/storage/browser/file_system/sandbox_file_system_backend.h @@ -31,6 +31,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SandboxFileSystemBackend : public FileSystemBackend { public: explicit SandboxFileSystemBackend(SandboxFileSystemBackendDelegate* delegate); + + SandboxFileSystemBackend(const SandboxFileSystemBackend&) = delete; + SandboxFileSystemBackend& operator=(const SandboxFileSystemBackend&) = delete; + ~SandboxFileSystemBackend() override; // FileSystemBackend overrides. @@ -44,7 +48,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SandboxFileSystemBackend CopyOrMoveFileValidatorFactory* GetCopyOrMoveFileValidatorFactory( FileSystemType type, base::File::Error* error_code) override; - FileSystemOperation* CreateFileSystemOperation( + std::unique_ptr<FileSystemOperation> CreateFileSystemOperation( const FileSystemURL& url, FileSystemContext* context, base::File::Error* error_code) const override; @@ -68,14 +72,13 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SandboxFileSystemBackend const AccessObserverList* GetAccessObservers( FileSystemType type) const override; - // Returns an origin enumerator of this backend. + // Returns a StorageKey enumerator of this backend. // This method can only be called on the file thread. - SandboxFileSystemBackendDelegate::OriginEnumerator* CreateOriginEnumerator(); + SandboxFileSystemBackendDelegate::StorageKeyEnumerator* + CreateStorageKeyEnumerator(); private: SandboxFileSystemBackendDelegate* delegate_; // Not owned. - - DISALLOW_COPY_AND_ASSIGN(SandboxFileSystemBackend); }; } // namespace storage 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 7db7a96717d..cd90326262a 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 @@ -38,7 +38,6 @@ #include "storage/common/file_system/file_system_util.h" #include "third_party/blink/public/common/storage_key/storage_key.h" #include "url/gurl.h" -#include "url/origin.h" namespace storage { @@ -95,15 +94,16 @@ std::set<std::string> GetKnownTypeStrings() { return known_type_strings; } -class SandboxObfuscatedOriginEnumerator - : public SandboxFileSystemBackendDelegate::OriginEnumerator { +class SandboxObfuscatedStorageKeyEnumerator + : public SandboxFileSystemBackendDelegate::StorageKeyEnumerator { public: - explicit SandboxObfuscatedOriginEnumerator(ObfuscatedFileUtil* file_util) { - enum_ = file_util->CreateOriginEnumerator(); + explicit SandboxObfuscatedStorageKeyEnumerator( + ObfuscatedFileUtil* file_util) { + enum_ = file_util->CreateStorageKeyEnumerator(); } - ~SandboxObfuscatedOriginEnumerator() override = default; + ~SandboxObfuscatedStorageKeyEnumerator() override = default; - absl::optional<url::Origin> Next() override { return enum_->Next(); } + absl::optional<blink::StorageKey> Next() override { return enum_->Next(); } bool HasFileSystemType(FileSystemType type) const override { return enum_->HasTypeDirectory( @@ -111,7 +111,7 @@ class SandboxObfuscatedOriginEnumerator } private: - std::unique_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enum_; + std::unique_ptr<ObfuscatedFileUtil::AbstractStorageKeyEnumerator> enum_; }; base::File::Error OpenSandboxFileSystemOnFileTaskRunner( @@ -121,8 +121,8 @@ base::File::Error OpenSandboxFileSystemOnFileTaskRunner( OpenFileSystemMode mode) { const bool create = (mode == OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT); base::File::Error error; - file_util->GetDirectoryForOriginAndType( - url::Origin::Create(origin_url), + file_util->GetDirectoryForStorageKeyAndType( + blink::StorageKey(url::Origin::Create(origin_url)), SandboxFileSystemBackendDelegate::GetTypeString(type), create, &error); if (error != base::File::FILE_OK) { UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemLabel, kCreateDirectoryError, @@ -224,43 +224,44 @@ SandboxFileSystemBackendDelegate::~SandboxFileSystemBackendDelegate() { } } -SandboxFileSystemBackendDelegate::OriginEnumerator* -SandboxFileSystemBackendDelegate::CreateOriginEnumerator() { - return new SandboxObfuscatedOriginEnumerator(obfuscated_file_util()); +SandboxFileSystemBackendDelegate::StorageKeyEnumerator* +SandboxFileSystemBackendDelegate::CreateStorageKeyEnumerator() { + return new SandboxObfuscatedStorageKeyEnumerator(obfuscated_file_util()); } base::FilePath -SandboxFileSystemBackendDelegate::GetBaseDirectoryForOriginAndType( - const url::Origin& origin, +SandboxFileSystemBackendDelegate::GetBaseDirectoryForStorageKeyAndType( + const blink::StorageKey& storage_key, FileSystemType type, bool create) { base::File::Error error = base::File::FILE_OK; - base::FilePath path = obfuscated_file_util()->GetDirectoryForOriginAndType( - origin, GetTypeString(type), create, &error); + base::FilePath path = + obfuscated_file_util()->GetDirectoryForStorageKeyAndType( + storage_key, GetTypeString(type), create, &error); if (error != base::File::FILE_OK) return base::FilePath(); return path; } void SandboxFileSystemBackendDelegate::OpenFileSystem( - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type, OpenFileSystemMode mode, OpenFileSystemCallback callback, const GURL& root_url) { - if (!IsAllowedScheme(origin.GetURL())) { + if (!IsAllowedScheme(storage_key.origin().GetURL())) { std::move(callback).Run(GURL(), std::string(), base::File::FILE_ERROR_SECURITY); return; } - std::string name = GetFileSystemName(origin.GetURL(), type); + std::string name = GetFileSystemName(storage_key.origin().GetURL(), type); // |quota_manager_proxy_| may be null in unit tests. base::OnceClosure quota_callback = (quota_manager_proxy_.get()) ? base::BindOnce(&QuotaManagerProxy::NotifyStorageAccessed, - quota_manager_proxy_, blink::StorageKey(origin), + quota_manager_proxy_, storage_key, FileSystemTypeToQuotaStorageType(type), base::Time::Now()) : base::DoNothing(); @@ -268,7 +269,8 @@ void SandboxFileSystemBackendDelegate::OpenFileSystem( file_task_runner_->PostTaskAndReplyWithResult( FROM_HERE, base::BindOnce(&OpenSandboxFileSystemOnFileTaskRunner, - obfuscated_file_util(), origin.GetURL(), type, mode), + obfuscated_file_util(), storage_key.origin().GetURL(), + type, mode), base::BindOnce(&DidOpenFileSystem, weak_factory_.GetWeakPtr(), std::move(quota_callback), base::BindOnce(std::move(callback), root_url, name))); @@ -327,21 +329,21 @@ SandboxFileSystemBackendDelegate::CreateFileStreamWriter( } base::File::Error -SandboxFileSystemBackendDelegate::DeleteOriginDataOnFileTaskRunner( +SandboxFileSystemBackendDelegate::DeleteStorageKeyDataOnFileTaskRunner( FileSystemContext* file_system_context, QuotaManagerProxy* proxy, - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type) { DCHECK(file_task_runner_->RunsTasksInCurrentSequence()); - int64_t usage = - GetOriginUsageOnFileTaskRunner(file_system_context, origin, type); + int64_t usage = GetStorageKeyUsageOnFileTaskRunner(file_system_context, + storage_key, type); usage_cache()->CloseCacheFiles(); - bool result = obfuscated_file_util()->DeleteDirectoryForOriginAndType( - origin, GetTypeString(type)); + bool result = obfuscated_file_util()->DeleteDirectoryForStorageKeyAndType( + storage_key, GetTypeString(type)); if (result && proxy && usage) { - proxy->NotifyStorageModified( - QuotaClientType::kFileSystem, blink::StorageKey(origin), - FileSystemTypeToQuotaStorageType(type), -usage, base::Time::Now()); + proxy->NotifyStorageModified(QuotaClientType::kFileSystem, storage_key, + FileSystemTypeToQuotaStorageType(type), -usage, + base::Time::Now()); } if (result) @@ -357,58 +359,63 @@ void SandboxFileSystemBackendDelegate::PerformStorageCleanupOnFileTaskRunner( obfuscated_file_util()->RewriteDatabases(); } -std::vector<url::Origin> -SandboxFileSystemBackendDelegate::GetOriginsForTypeOnFileTaskRunner( +std::vector<blink::StorageKey> +SandboxFileSystemBackendDelegate::GetStorageKeysForTypeOnFileTaskRunner( FileSystemType type) { DCHECK(file_task_runner_->RunsTasksInCurrentSequence()); - std::unique_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator()); - std::vector<url::Origin> origins; - absl::optional<url::Origin> origin; - while ((origin = enumerator->Next()).has_value()) { + std::unique_ptr<StorageKeyEnumerator> enumerator( + CreateStorageKeyEnumerator()); + std::vector<blink::StorageKey> storage_keys; + absl::optional<blink::StorageKey> storage_key; + while ((storage_key = enumerator->Next()).has_value()) { if (enumerator->HasFileSystemType(type)) - origins.push_back(std::move(origin).value()); + storage_keys.push_back(std::move(storage_key).value()); } switch (type) { case kFileSystemTypeTemporary: - UMA_HISTOGRAM_COUNTS_1M(kTemporaryOriginsCountLabel, origins.size()); + UMA_HISTOGRAM_COUNTS_1M(kTemporaryOriginsCountLabel, storage_keys.size()); break; case kFileSystemTypePersistent: - UMA_HISTOGRAM_COUNTS_1M(kPersistentOriginsCountLabel, origins.size()); + UMA_HISTOGRAM_COUNTS_1M(kPersistentOriginsCountLabel, + storage_keys.size()); break; default: break; } - return origins; + return storage_keys; } -std::vector<url::Origin> -SandboxFileSystemBackendDelegate::GetOriginsForHostOnFileTaskRunner( +std::vector<blink::StorageKey> +SandboxFileSystemBackendDelegate::GetStorageKeysForHostOnFileTaskRunner( FileSystemType type, const std::string& host) { DCHECK(file_task_runner_->RunsTasksInCurrentSequence()); - std::vector<url::Origin> origins; - std::unique_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator()); - 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()); + std::vector<blink::StorageKey> storage_keys; + std::unique_ptr<StorageKeyEnumerator> enumerator( + CreateStorageKeyEnumerator()); + absl::optional<blink::StorageKey> storage_key; + while ((storage_key = enumerator->Next()).has_value()) { + if (host == storage_key->origin().host() && + enumerator->HasFileSystemType(type)) + storage_keys.push_back(std::move(storage_key).value()); } - return origins; + return storage_keys; } -int64_t SandboxFileSystemBackendDelegate::GetOriginUsageOnFileTaskRunner( +int64_t SandboxFileSystemBackendDelegate::GetStorageKeyUsageOnFileTaskRunner( FileSystemContext* file_system_context, - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type) { DCHECK(file_task_runner_->RunsTasksInCurrentSequence()); // Don't use usage cache and return recalculated usage for sticky invalidated // origins. - if (base::Contains(sticky_dirty_origins_, std::make_pair(origin, type))) - return RecalculateUsage(file_system_context, origin, type); + if (base::Contains(sticky_dirty_origins_, + std::make_pair(storage_key.origin(), type))) + return RecalculateUsage(file_system_context, storage_key, type); base::FilePath base_path = - GetBaseDirectoryForOriginAndType(origin, type, false); + GetBaseDirectoryForStorageKeyAndType(storage_key, type, false); if (base_path.empty() || !obfuscated_file_util()->delegate()->DirectoryExists(base_path)) { return 0; @@ -420,7 +427,7 @@ int64_t SandboxFileSystemBackendDelegate::GetOriginUsageOnFileTaskRunner( uint32_t dirty_status = 0; bool dirty_status_available = usage_cache()->GetDirty(usage_file_path, &dirty_status); - bool visited = !visited_origins_.insert(origin).second; + bool visited = !visited_origins_.insert(storage_key.origin()).second; if (is_valid && (dirty_status == 0 || (dirty_status_available && visited))) { // The usage cache is clean (dirty == 0) or the origin is already // initialized and running. Read the cache file to get the usage. @@ -431,7 +438,7 @@ int64_t SandboxFileSystemBackendDelegate::GetOriginUsageOnFileTaskRunner( // Get the directory size now and update the cache. usage_cache()->Delete(usage_file_path); - int64_t usage = RecalculateUsage(file_system_context, origin, type); + int64_t usage = RecalculateUsage(file_system_context, storage_key, type); // This clears the dirty flag too. usage_cache()->UpdateUsage(usage_file_path, usage); @@ -440,11 +447,12 @@ int64_t SandboxFileSystemBackendDelegate::GetOriginUsageOnFileTaskRunner( scoped_refptr<QuotaReservation> SandboxFileSystemBackendDelegate::CreateQuotaReservationOnFileTaskRunner( - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type) { DCHECK(file_task_runner_->RunsTasksInCurrentSequence()); DCHECK(quota_reservation_manager_); - return quota_reservation_manager_->CreateReservation(origin, type); + return quota_reservation_manager_->CreateReservation(storage_key.origin(), + type); } void SandboxFileSystemBackendDelegate::AddFileUpdateObserver( @@ -510,22 +518,22 @@ void SandboxFileSystemBackendDelegate::RegisterQuotaUpdateObserver( } void SandboxFileSystemBackendDelegate::InvalidateUsageCache( - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type) { base::File::Error error = base::File::FILE_OK; - base::FilePath usage_file_path = GetUsageCachePathForOriginAndType( - obfuscated_file_util(), origin, type, &error); + base::FilePath usage_file_path = GetUsageCachePathForStorageKeyAndType( + obfuscated_file_util(), storage_key, type, &error); if (error != base::File::FILE_OK) return; usage_cache()->IncrementDirty(usage_file_path); } void SandboxFileSystemBackendDelegate::StickyInvalidateUsageCache( - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type) { - sticky_dirty_origins_.insert(std::make_pair(origin, type)); - quota_observer()->SetUsageCacheEnabled(origin, type, false); - InvalidateUsageCache(origin, type); + sticky_dirty_origins_.insert(std::make_pair(storage_key.origin(), type)); + quota_observer()->SetUsageCacheEnabled(storage_key.origin(), type, false); + InvalidateUsageCache(storage_key, type); } FileSystemFileUtil* SandboxFileSystemBackendDelegate::sync_file_util() { @@ -582,12 +590,12 @@ bool SandboxFileSystemBackendDelegate::IsAllowedScheme(const GURL& url) const { } base::FilePath -SandboxFileSystemBackendDelegate::GetUsageCachePathForOriginAndType( - const url::Origin& origin, +SandboxFileSystemBackendDelegate::GetUsageCachePathForStorageKeyAndType( + const blink::StorageKey& storage_key, FileSystemType type) { base::File::Error error; - base::FilePath path = GetUsageCachePathForOriginAndType( - obfuscated_file_util(), origin, type, &error); + base::FilePath path = GetUsageCachePathForStorageKeyAndType( + obfuscated_file_util(), storage_key, type, &error); if (error != base::File::FILE_OK) return base::FilePath(); return path; @@ -595,15 +603,16 @@ SandboxFileSystemBackendDelegate::GetUsageCachePathForOriginAndType( // static base::FilePath -SandboxFileSystemBackendDelegate::GetUsageCachePathForOriginAndType( +SandboxFileSystemBackendDelegate::GetUsageCachePathForStorageKeyAndType( ObfuscatedFileUtil* sandbox_file_util, - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type, base::File::Error* error_out) { DCHECK(error_out); *error_out = base::File::FILE_OK; - base::FilePath base_path = sandbox_file_util->GetDirectoryForOriginAndType( - origin, GetTypeString(type), false /* create */, error_out); + base::FilePath base_path = + sandbox_file_util->GetDirectoryForStorageKeyAndType( + storage_key, GetTypeString(type), false /* create */, error_out); if (*error_out != base::File::FILE_OK) return base::FilePath(); return base_path.Append(FileSystemUsageCache::kUsageFileName); @@ -611,11 +620,11 @@ SandboxFileSystemBackendDelegate::GetUsageCachePathForOriginAndType( int64_t SandboxFileSystemBackendDelegate::RecalculateUsage( FileSystemContext* context, - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type) { FileSystemOperationContext operation_context(context); - FileSystemURL url = context->CreateCrackedFileSystemURL( - blink::StorageKey(origin), type, base::FilePath()); + FileSystemURL url = + context->CreateCrackedFileSystemURL(storage_key, type, base::FilePath()); std::unique_ptr<FileSystemFileUtil::AbstractFileEnumerator> enumerator( obfuscated_file_util()->CreateFileEnumerator(&operation_context, url, true)); @@ -637,7 +646,7 @@ void SandboxFileSystemBackendDelegate::CollectOpenFileSystemMetrics( bool throttled = now < next_release_time_for_open_filesystem_stat_; if (!throttled) { next_release_time_for_open_filesystem_stat_ = - now + base::TimeDelta::FromHours(kMinimumStatsCollectionIntervalHours); + now + base::Hours(kMinimumStatsCollectionIntervalHours); } #define REPORT(report_value) \ @@ -666,34 +675,6 @@ void SandboxFileSystemBackendDelegate::CollectOpenFileSystemMetrics( #undef REPORT } -void SandboxFileSystemBackendDelegate::CopyFileSystem( - const url::Origin& origin, - FileSystemType type, - SandboxFileSystemBackendDelegate* destination) { - DCHECK(file_task_runner()->RunsTasksInCurrentSequence()); - - base::FilePath base_path = - GetBaseDirectoryForOriginAndType(origin, type, /*create=*/false); - if (base::PathExists(base_path)) { - // Delete any existing file system directories in the destination. A - // previously failed migration - // may have left behind partially copied directories. - base::FilePath dest_path = destination->GetBaseDirectoryForOriginAndType( - origin, type, /*create=*/false); - - // Make sure we're not about to delete our own file system. - CHECK_NE(base_path.value(), dest_path.value()); - base::DeletePathRecursively(dest_path); - - dest_path = destination->GetBaseDirectoryForOriginAndType(origin, type, - /*create=*/true); - - obfuscated_file_util()->CloseFileSystemForOriginAndType( - origin, GetTypeString(type)); - base::CopyDirectory(base_path, dest_path.DirName(), true /* rescursive */); - } -} - ObfuscatedFileUtil* SandboxFileSystemBackendDelegate::obfuscated_file_util() { return static_cast<ObfuscatedFileUtil*>(sync_file_util()); } 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 1c730d79450..cc1cc70dc73 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 @@ -28,7 +28,11 @@ namespace base { class SequencedTaskRunner; -} +} // namespace base + +namespace blink { +class StorageKey; +} // namespace blink namespace storage { class SandboxFileSystemBackendDelegateTest; @@ -37,11 +41,11 @@ class SandboxFileSystemTestHelper; namespace leveldb { class Env; -} +} // namespace leveldb namespace url { class Origin; -} +} // namespace url namespace storage { @@ -69,23 +73,23 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SandboxFileSystemBackendDelegate // The FileSystem directory name. static const base::FilePath::CharType kFileSystemDirectory[]; - // Origin enumerator interface. + // StorageKey enumerator interface. // An instance of this interface is assumed to be called on the file thread. - class OriginEnumerator { + class StorageKeyEnumerator { public: - OriginEnumerator(const OriginEnumerator&) = delete; - OriginEnumerator& operator=(const OriginEnumerator&) = delete; - virtual ~OriginEnumerator() = default; + StorageKeyEnumerator(const StorageKeyEnumerator&) = delete; + StorageKeyEnumerator& operator=(const StorageKeyEnumerator&) = delete; + virtual ~StorageKeyEnumerator() = default; - // Returns the next origin. Returns absl::nullopt if there are no more - // origins. - virtual absl::optional<url::Origin> Next() = 0; + // Returns the next StorageKey. Returns absl::nullopt if there are no more + // StorageKey. + virtual absl::optional<blink::StorageKey> Next() = 0; - // Returns the current origin's information. + // Returns the current StorageKey's information. virtual bool HasFileSystemType(FileSystemType type) const = 0; protected: - OriginEnumerator() = default; + StorageKeyEnumerator() = default; }; // Returns the type directory name in sandbox directory for given |type|. @@ -105,22 +109,23 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SandboxFileSystemBackendDelegate const SandboxFileSystemBackendDelegate&) = delete; ~SandboxFileSystemBackendDelegate() override; - // Returns an origin enumerator of sandbox filesystem. + // Returns a StorageKey enumerator of sandbox filesystem. // This method can only be called on the file thread. - OriginEnumerator* CreateOriginEnumerator(); + StorageKeyEnumerator* CreateStorageKeyEnumerator(); // Gets a base directory path of the sandboxed filesystem that is - // specified by |origin_url| and |type|. + // specified by `storage_key` and `type`. // (The path is similar to the origin's root path but doesn't contain // the 'unique' part.) // Returns an empty path if the given type is invalid. // This method can only be called on the file thread. - base::FilePath GetBaseDirectoryForOriginAndType(const url::Origin& origin, - FileSystemType type, - bool create); + base::FilePath GetBaseDirectoryForStorageKeyAndType( + const blink::StorageKey& storage_key, + FileSystemType type, + bool create); // FileSystemBackend helpers. - void OpenFileSystem(const url::Origin& origin, + void OpenFileSystem(const blink::StorageKey& storage_key, FileSystemType type, OpenFileSystemMode mode, OpenFileSystemCallback callback, @@ -141,24 +146,25 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SandboxFileSystemBackendDelegate FileSystemType type) const; // FileSystemQuotaUtil overrides. - base::File::Error DeleteOriginDataOnFileTaskRunner( + base::File::Error DeleteStorageKeyDataOnFileTaskRunner( FileSystemContext* context, QuotaManagerProxy* proxy, - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type) override; void PerformStorageCleanupOnFileTaskRunner(FileSystemContext* context, QuotaManagerProxy* proxy, FileSystemType type) override; - std::vector<url::Origin> GetOriginsForTypeOnFileTaskRunner( + std::vector<blink::StorageKey> GetStorageKeysForTypeOnFileTaskRunner( FileSystemType type) override; - std::vector<url::Origin> GetOriginsForHostOnFileTaskRunner( + std::vector<blink::StorageKey> GetStorageKeysForHostOnFileTaskRunner( FileSystemType type, const std::string& host) override; - int64_t GetOriginUsageOnFileTaskRunner(FileSystemContext* context, - const url::Origin& origin, - FileSystemType type) override; + int64_t GetStorageKeyUsageOnFileTaskRunner( + FileSystemContext* context, + const blink::StorageKey& storage_key, + FileSystemType type) override; scoped_refptr<QuotaReservation> CreateQuotaReservationOnFileTaskRunner( - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type) override; // Adds an observer for the secified |type| of a file system, bound to @@ -184,18 +190,13 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SandboxFileSystemBackendDelegate // Registers quota observer for file updates on filesystem of |type|. void RegisterQuotaUpdateObserver(FileSystemType type); - void InvalidateUsageCache(const url::Origin& origin, FileSystemType type); - void StickyInvalidateUsageCache(const url::Origin& origin, + void InvalidateUsageCache(const blink::StorageKey& storage_key, + FileSystemType type); + void StickyInvalidateUsageCache(const blink::StorageKey& storage_key, FileSystemType type); void CollectOpenFileSystemMetrics(base::File::Error error_code); - // Used for migrating from the general storage partition to an isolated - // storage partition - void CopyFileSystem(const url::Origin& origin, - FileSystemType type, - SandboxFileSystemBackendDelegate* destination); - base::SequencedTaskRunner* file_task_runner() { return file_task_runner_.get(); } @@ -231,18 +232,19 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SandboxFileSystemBackendDelegate bool IsAllowedScheme(const GURL& url) const; // Returns a path to the usage cache file. - base::FilePath GetUsageCachePathForOriginAndType(const url::Origin& origin, - FileSystemType type); + base::FilePath GetUsageCachePathForStorageKeyAndType( + const blink::StorageKey& storage_key, + FileSystemType type); // Returns a path to the usage cache file (static version). - static base::FilePath GetUsageCachePathForOriginAndType( + static base::FilePath GetUsageCachePathForStorageKeyAndType( ObfuscatedFileUtil* sandbox_file_util, - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type, base::File::Error* error_out); int64_t RecalculateUsage(FileSystemContext* context, - const url::Origin& origin, + const blink::StorageKey& storage_key, FileSystemType type); ObfuscatedFileUtil* obfuscated_file_util(); diff --git a/chromium/storage/browser/file_system/sandbox_file_system_backend_delegate_unittest.cc b/chromium/storage/browser/file_system/sandbox_file_system_backend_delegate_unittest.cc index 941c8495296..c6fb104ae60 100644 --- a/chromium/storage/browser/file_system/sandbox_file_system_backend_delegate_unittest.cc +++ b/chromium/storage/browser/file_system/sandbox_file_system_backend_delegate_unittest.cc @@ -48,11 +48,11 @@ class SandboxFileSystemBackendDelegateTest : public testing::Test { return delegate_->IsAccessValid(url); } - void OpenFileSystem(const url::Origin& origin, + void OpenFileSystem(const blink::StorageKey& storage_key, FileSystemType type, OpenFileSystemMode mode) { delegate_->OpenFileSystem( - origin, type, mode, + storage_key, type, mode, base::BindOnce( &SandboxFileSystemBackendDelegateTest::OpenFileSystemCallback, base::Unretained(this)), @@ -120,19 +120,19 @@ TEST_F(SandboxFileSystemBackendDelegateTest, IsAccessValid) { } TEST_F(SandboxFileSystemBackendDelegateTest, OpenFileSystemAccessesStorage) { - GURL origin("http://example.com"); - EXPECT_EQ(quota_manager_proxy()->notify_storage_accessed_count(), 0); EXPECT_EQ(callback_count(), 0); - OpenFileSystem(url::Origin::Create(origin), kFileSystemTypeTemporary, + const blink::StorageKey& storage_key = + blink::StorageKey::CreateFromStringForTesting("http://example.com"); + + OpenFileSystem(storage_key, kFileSystemTypeTemporary, OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT); EXPECT_EQ(callback_count(), 1); EXPECT_EQ(last_error(), base::File::FILE_OK); EXPECT_EQ(quota_manager_proxy()->notify_storage_accessed_count(), 1); - EXPECT_EQ(quota_manager_proxy()->last_notified_storage_key(), - blink::StorageKey(url::Origin::Create(origin))); + EXPECT_EQ(quota_manager_proxy()->last_notified_storage_key(), storage_key); EXPECT_EQ(quota_manager_proxy()->last_notified_type(), blink::mojom::StorageType::kTemporary); } 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 2a6cb0ec661..11ba94b9bf9 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 @@ -30,7 +30,6 @@ #include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/leveldatabase/leveldb_chrome.h" #include "url/gurl.h" -#include "url/origin.h" // PS stands for path separator. #if defined(FILE_PATH_USES_WIN_SEPARATORS) @@ -105,14 +104,14 @@ class SandboxFileSystemBackendTest backend_ = std::make_unique<SandboxFileSystemBackend>(delegate_.get()); } - SandboxFileSystemBackendDelegate::OriginEnumerator* CreateOriginEnumerator() - const { - return backend_->CreateOriginEnumerator(); + SandboxFileSystemBackendDelegate::StorageKeyEnumerator* + CreateStorageKeyEnumerator() const { + return backend_->CreateStorageKeyEnumerator(); } void CreateOriginTypeDirectory(const char* origin_url, FileSystemType type) { - base::FilePath target = delegate_->GetBaseDirectoryForOriginAndType( - url::Origin::Create(GURL(origin_url)), type, true); + base::FilePath target = delegate_->GetBaseDirectoryForStorageKeyAndType( + blink::StorageKey::CreateFromStringForTesting(origin_url), type, true); ASSERT_TRUE(!target.empty()); ASSERT_TRUE(base::DirectoryExists(target)); } @@ -131,8 +130,8 @@ class SandboxFileSystemBackendTest if (error != base::File::FILE_OK) return false; base::FilePath returned_root_path = - delegate_->GetBaseDirectoryForOriginAndType( - url::Origin::Create(GURL(origin_url)), type, + delegate_->GetBaseDirectoryForStorageKeyAndType( + blink::StorageKey::CreateFromStringForTesting(origin_url), type, /*create=*/false); if (root_path) *root_path = returned_root_path; @@ -158,8 +157,8 @@ INSTANTIATE_TEST_SUITE_P(All, SandboxFileSystemBackendTest, ::testing::Bool()); TEST_P(SandboxFileSystemBackendTest, Empty) { SetUpNewBackend(CreateAllowFileAccessOptions()); - std::unique_ptr<SandboxFileSystemBackendDelegate::OriginEnumerator> - enumerator(CreateOriginEnumerator()); + std::unique_ptr<SandboxFileSystemBackendDelegate::StorageKeyEnumerator> + enumerator(CreateStorageKeyEnumerator()); ASSERT_FALSE(enumerator->Next()); } @@ -177,25 +176,27 @@ TEST_P(SandboxFileSystemBackendTest, EnumerateOrigins) { }; size_t temporary_size = base::size(temporary_origins); size_t persistent_size = base::size(persistent_origins); - std::set<url::Origin> temporary_set, persistent_set; + std::set<blink::StorageKey> temporary_set, persistent_set; for (size_t i = 0; i < temporary_size; ++i) { CreateOriginTypeDirectory(temporary_origins[i], kFileSystemTypeTemporary); - temporary_set.insert(url::Origin::Create(GURL(temporary_origins[i]))); + temporary_set.insert( + blink::StorageKey::CreateFromStringForTesting(temporary_origins[i])); } for (size_t i = 0; i < persistent_size; ++i) { CreateOriginTypeDirectory(persistent_origins[i], kFileSystemTypePersistent); - persistent_set.insert(url::Origin::Create(GURL(persistent_origins[i]))); + persistent_set.insert( + blink::StorageKey::CreateFromStringForTesting(persistent_origins[i])); } - std::unique_ptr<SandboxFileSystemBackendDelegate::OriginEnumerator> - enumerator(CreateOriginEnumerator()); + std::unique_ptr<SandboxFileSystemBackendDelegate::StorageKeyEnumerator> + enumerator(CreateStorageKeyEnumerator()); size_t temporary_actual_size = 0; size_t persistent_actual_size = 0; - absl::optional<url::Origin> current; + absl::optional<blink::StorageKey> current; while ((current = enumerator->Next()).has_value()) { SCOPED_TRACE(testing::Message() - << "EnumerateOrigin " << current->Serialize()); + << "EnumerateOrigin " << current->origin().Serialize()); if (enumerator->HasFileSystemType(kFileSystemTypeTemporary)) { ASSERT_TRUE(temporary_set.find(current.value()) != temporary_set.end()); ++temporary_actual_size; diff --git a/chromium/storage/browser/file_system/sandbox_origin_database.cc b/chromium/storage/browser/file_system/sandbox_origin_database.cc index c00a5349508..21c8ec86631 100644 --- a/chromium/storage/browser/file_system/sandbox_origin_database.cc +++ b/chromium/storage/browser/file_system/sandbox_origin_database.cc @@ -194,7 +194,7 @@ void SandboxOriginDatabase::HandleError(const base::Location& from_here, void SandboxOriginDatabase::ReportInitStatus(const leveldb::Status& status) { base::Time now = base::Time::Now(); base::TimeDelta minimum_interval = - base::TimeDelta::FromHours(kSandboxOriginMinimumReportIntervalHours); + base::Hours(kSandboxOriginMinimumReportIntervalHours); if (last_reported_time_ + minimum_interval >= now) return; last_reported_time_ = now; diff --git a/chromium/storage/browser/file_system/sandbox_origin_database.h b/chromium/storage/browser/file_system/sandbox_origin_database.h index fa3bd8a60e1..709ac336e46 100644 --- a/chromium/storage/browser/file_system/sandbox_origin_database.h +++ b/chromium/storage/browser/file_system/sandbox_origin_database.h @@ -35,6 +35,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SandboxOriginDatabase // at a given time. SandboxOriginDatabase(const base::FilePath& file_system_directory, leveldb::Env* env_override); + + SandboxOriginDatabase(const SandboxOriginDatabase&) = delete; + SandboxOriginDatabase& operator=(const SandboxOriginDatabase&) = delete; + ~SandboxOriginDatabase() override; // SandboxOriginDatabaseInterface overrides. @@ -74,7 +78,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SandboxOriginDatabase leveldb::Env* env_override_; std::unique_ptr<leveldb::DB> db_; base::Time last_reported_time_; - DISALLOW_COPY_AND_ASSIGN(SandboxOriginDatabase); }; } // namespace storage diff --git a/chromium/storage/browser/file_system/sandbox_quota_observer.cc b/chromium/storage/browser/file_system/sandbox_quota_observer.cc index 9e43d5e6e5f..f9a4a6c794e 100644 --- a/chromium/storage/browser/file_system/sandbox_quota_observer.cc +++ b/chromium/storage/browser/file_system/sandbox_quota_observer.cc @@ -101,8 +101,8 @@ base::FilePath SandboxQuotaObserver::GetUsageCachePath( DCHECK(sandbox_file_util_); base::File::Error error = base::File::FILE_OK; base::FilePath path = - SandboxFileSystemBackendDelegate::GetUsageCachePathForOriginAndType( - sandbox_file_util_, url.origin(), url.type(), &error); + SandboxFileSystemBackendDelegate::GetUsageCachePathForStorageKeyAndType( + sandbox_file_util_, url.storage_key(), url.type(), &error); if (error != base::File::FILE_OK) { LOG(WARNING) << "Could not get usage cache path for: " << url.DebugString(); return base::FilePath(); diff --git a/chromium/storage/browser/file_system/sandbox_quota_observer.h b/chromium/storage/browser/file_system/sandbox_quota_observer.h index 2be5fe4b505..ed05a185962 100644 --- a/chromium/storage/browser/file_system/sandbox_quota_observer.h +++ b/chromium/storage/browser/file_system/sandbox_quota_observer.h @@ -42,6 +42,10 @@ class SandboxQuotaObserver : public FileUpdateObserver, scoped_refptr<base::SequencedTaskRunner> update_notify_runner, ObfuscatedFileUtil* sandbox_file_util, FileSystemUsageCache* file_system_usage_cache_); + + SandboxQuotaObserver(const SandboxQuotaObserver&) = delete; + SandboxQuotaObserver& operator=(const SandboxQuotaObserver&) = delete; + ~SandboxQuotaObserver() override; // FileUpdateObserver overrides. @@ -74,8 +78,6 @@ class SandboxQuotaObserver : public FileUpdateObserver, std::map<base::FilePath, int64_t> pending_update_notification_; base::OneShotTimer delayed_cache_update_helper_; - - DISALLOW_COPY_AND_ASSIGN(SandboxQuotaObserver); }; } // 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 0c29ba28fd2..64f6202928d 100644 --- a/chromium/storage/browser/file_system/transient_file_util.h +++ b/chromium/storage/browser/file_system/transient_file_util.h @@ -17,6 +17,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) TransientFileUtil : public LocalFileUtil { public: TransientFileUtil() = default; + + TransientFileUtil(const TransientFileUtil&) = delete; + TransientFileUtil& operator=(const TransientFileUtil&) = delete; + ~TransientFileUtil() override = default; // LocalFileUtil overrides. @@ -25,9 +29,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) TransientFileUtil base::File::Error* error, base::File::Info* file_info, base::FilePath* platform_path) override; - - private: - DISALLOW_COPY_AND_ASSIGN(TransientFileUtil); }; } // namespace storage diff --git a/chromium/storage/browser/file_system/transient_file_util_unittest.cc b/chromium/storage/browser/file_system/transient_file_util_unittest.cc index 3d4fa9490a0..a90a401e26f 100644 --- a/chromium/storage/browser/file_system/transient_file_util_unittest.cc +++ b/chromium/storage/browser/file_system/transient_file_util_unittest.cc @@ -27,6 +27,10 @@ namespace storage { class TransientFileUtilTest : public testing::Test { public: TransientFileUtilTest() = default; + + TransientFileUtilTest(const TransientFileUtilTest&) = delete; + TransientFileUtilTest& operator=(const TransientFileUtilTest&) = delete; + ~TransientFileUtilTest() override = default; void SetUp() override { @@ -73,8 +77,6 @@ class TransientFileUtilTest : public testing::Test { base::ScopedTempDir data_dir_; scoped_refptr<FileSystemContext> file_system_context_; std::unique_ptr<TransientFileUtil> transient_file_util_; - - DISALLOW_COPY_AND_ASSIGN(TransientFileUtilTest); }; TEST_F(TransientFileUtilTest, TransientFile) { diff --git a/chromium/storage/browser/quota/COMMON_METADATA b/chromium/storage/browser/quota/COMMON_METADATA new file mode 100644 index 00000000000..cf9ebe3f99d --- /dev/null +++ b/chromium/storage/browser/quota/COMMON_METADATA @@ -0,0 +1,3 @@ +monorail { + component: "Blink>Storage>Quota" +} diff --git a/chromium/storage/browser/quota/DIR_METADATA b/chromium/storage/browser/quota/DIR_METADATA index f3365fa6fce..406a1ebffd7 100644 --- a/chromium/storage/browser/quota/DIR_METADATA +++ b/chromium/storage/browser/quota/DIR_METADATA @@ -6,6 +6,4 @@ # For the schema of this file, see Metadata message: # https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/proto/dir_metadata.proto -monorail { - component: "Blink>Storage>Quota" -} +mixins: "//storage/browser/quota/COMMON_METADATA" diff --git a/chromium/storage/browser/quota/client_usage_tracker.cc b/chromium/storage/browser/quota/client_usage_tracker.cc index 879748f212b..87fd0d5690c 100644 --- a/chromium/storage/browser/quota/client_usage_tracker.cc +++ b/chromium/storage/browser/quota/client_usage_tracker.cc @@ -256,10 +256,10 @@ void ClientUsageTracker::DidGetStorageKeysForGlobalUsage( for (const auto& host_and_storage_keys : storage_keys_by_host) { const std::string& host = host_and_storage_keys.first; - const std::vector<blink::StorageKey>& storage_keys = + const std::vector<blink::StorageKey>& storage_keys_for_host = host_and_storage_keys.second; if (host_usage_accumulators_.Add(host, accumulator)) - GetUsageForStorageKeys(host, storage_keys); + GetUsageForStorageKeys(host, storage_keys_for_host); } // Fire the sentinel as we've now called GetUsageForStorageKeys for all diff --git a/chromium/storage/browser/quota/quota_database.cc b/chromium/storage/browser/quota/quota_database.cc index f93459db71c..d1421d28dba 100644 --- a/chromium/storage/browser/quota/quota_database.cc +++ b/chromium/storage/browser/quota/quota_database.cc @@ -17,6 +17,7 @@ #include "base/dcheck_is_on.h" #include "base/files/file_util.h" #include "base/metrics/histogram_functions.h" +#include "components/services/storage/public/cpp/buckets/constants.h" #include "sql/database.h" #include "sql/meta_table.h" #include "sql/statement.h" @@ -44,8 +45,9 @@ namespace { // Version 5 - 2015-10-19 - https://crrev.com/354932 // Version 6 - 2021-04-27 - https://crrev.com/c/2757450 // Version 7 - 2021-05-20 - https://crrev.com/c/2910136 -const int kQuotaDatabaseCurrentSchemaVersion = 7; -const int kQuotaDatabaseCompatibleVersion = 7; +// Version 8 - 2021-09-01 - https://crrev.com/c/3119831 +const int kQuotaDatabaseCurrentSchemaVersion = 8; +const int kQuotaDatabaseCompatibleVersion = 8; // Definitions for database schema. const char kHostQuotaTable[] = "quota"; @@ -69,9 +71,8 @@ const QuotaDatabase::TableSchema QuotaDatabase::kTables[] = { " WITHOUT ROWID"}, {kBucketTable, "(id INTEGER PRIMARY KEY," - // TODO(crbug.com/1215208): Rename column to storage_key and create a DB - // migration for it. - " origin TEXT NOT NULL," + " storage_key TEXT NOT NULL," + " host TEXT NOT NULL," " type INTEGER NOT NULL," " name TEXT NOT NULL," " use_count INTEGER NOT NULL," @@ -83,7 +84,8 @@ const size_t QuotaDatabase::kTableCount = base::size(QuotaDatabase::kTables); // static const QuotaDatabase::IndexSchema QuotaDatabase::kIndexes[] = { - {"buckets_by_storage_key", kBucketTable, "(origin, type, name)", true}, + {"buckets_by_storage_key", kBucketTable, "(storage_key, type, name)", true}, + {"buckets_by_host", kBucketTable, "(type, host)", false}, {"buckets_by_last_accessed", kBucketTable, "(type, last_accessed)", false}, {"buckets_by_last_modified", kBucketTable, "(type, last_modified)", false}, {"buckets_by_expiration", kBucketTable, "(expiration)", false}, @@ -116,10 +118,7 @@ QuotaDatabase::BucketTableEntry::BucketTableEntry( last_modified(last_modified) {} // QuotaDatabase ------------------------------------------------------------ -QuotaDatabase::QuotaDatabase(const base::FilePath& path) - : db_file_path_(path), - is_recreating_(false), - is_disabled_(false) { +QuotaDatabase::QuotaDatabase(const base::FilePath& path) : db_file_path_(path) { DETACH_FROM_SEQUENCE(sequence_checker_); } @@ -135,7 +134,7 @@ bool QuotaDatabase::GetHostQuota(const std::string& host, int64_t* quota) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(quota); - if (LazyOpen(LazyOpenMode::kFailIfNotFound) != QuotaError::kNone) + if (EnsureOpened(EnsureOpenedMode::kFailIfNotFound) != QuotaError::kNone) return false; static constexpr char kSql[] = @@ -156,7 +155,7 @@ bool QuotaDatabase::SetHostQuota(const std::string& host, int64_t quota) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_GE(quota, 0); - if (LazyOpen(LazyOpenMode::kCreateIfNotFound) != QuotaError::kNone) + if (EnsureOpened(EnsureOpenedMode::kCreateIfNotFound) != QuotaError::kNone) return false; if (quota == 0) @@ -212,7 +211,7 @@ QuotaErrorOr<BucketInfo> QuotaDatabase::GetBucket( const std::string& bucket_name, blink::mojom::StorageType storage_type) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - QuotaError open_error = LazyOpen(LazyOpenMode::kFailIfNotFound); + QuotaError open_error = EnsureOpened(EnsureOpenedMode::kFailIfNotFound); if (open_error != QuotaError::kNone) return open_error; @@ -220,7 +219,7 @@ QuotaErrorOr<BucketInfo> QuotaDatabase::GetBucket( // clang-format off "SELECT id, expiration, quota " "FROM buckets " - "WHERE origin = ? AND type = ? AND name = ?"; + "WHERE storage_key = ? AND type = ? AND name = ?"; // clang-format on sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); statement.BindString(0, storage_key.Serialize()); @@ -237,112 +236,201 @@ QuotaErrorOr<BucketInfo> QuotaDatabase::GetBucket( statement.ColumnInt(2)); } -bool QuotaDatabase::SetStorageKeyLastAccessTime(const StorageKey& storage_key, - StorageType type, - base::Time last_accessed) { +QuotaErrorOr<std::set<BucketLocator>> QuotaDatabase::GetBucketsForType( + StorageType type) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (LazyOpen(LazyOpenMode::kCreateIfNotFound) != QuotaError::kNone) - return false; + QuotaError open_error = EnsureOpened(EnsureOpenedMode::kFailIfNotFound); + if (open_error != QuotaError::kNone) + return open_error; - BucketTableEntry entry; - if (!GetStorageKeyInfo(storage_key, type, &entry)) { - QuotaErrorOr<BucketInfo> result = + static constexpr char kSql[] = + "SELECT id, storage_key, name FROM buckets WHERE type = ?"; + + sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); + statement.BindInt(0, static_cast<int>(type)); + + std::set<BucketLocator> buckets; + while (statement.Step()) { + absl::optional<StorageKey> read_storage_key = + StorageKey::Deserialize(statement.ColumnString(1)); + if (!read_storage_key.has_value()) + continue; + buckets.emplace(BucketId(statement.ColumnInt64(0)), + read_storage_key.value(), type, + statement.ColumnString(2) == kDefaultBucketName); + } + return buckets; +} + +QuotaErrorOr<std::set<BucketLocator>> QuotaDatabase::GetBucketsForHost( + const std::string& host, + blink::mojom::StorageType storage_type) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + QuotaError open_error = EnsureOpened(EnsureOpenedMode::kFailIfNotFound); + if (open_error != QuotaError::kNone) + return open_error; + + static constexpr char kSql[] = + "SELECT id, storage_key, name FROM buckets WHERE host = ? AND type = ?"; + + sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); + statement.BindString(0, host); + statement.BindInt(1, static_cast<int>(storage_type)); + + std::set<BucketLocator> buckets; + while (statement.Step()) { + absl::optional<StorageKey> read_storage_key = + StorageKey::Deserialize(statement.ColumnString(1)); + if (!read_storage_key.has_value()) + continue; + buckets.emplace(BucketId(statement.ColumnInt64(0)), + read_storage_key.value(), storage_type, + statement.ColumnString(2) == kDefaultBucketName); + } + return buckets; +} + +QuotaErrorOr<std::set<BucketLocator>> QuotaDatabase::GetBucketsForStorageKey( + const StorageKey& storage_key, + StorageType type) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + QuotaError open_error = EnsureOpened(EnsureOpenedMode::kFailIfNotFound); + if (open_error != QuotaError::kNone) + return open_error; + + static constexpr char kSql[] = + "SELECT id, name FROM buckets WHERE storage_key = ? AND type = ?"; + + sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); + statement.BindString(0, storage_key.Serialize()); + statement.BindInt(1, static_cast<int>(type)); + + std::set<BucketLocator> buckets; + while (statement.Step()) { + buckets.emplace(BucketId(statement.ColumnInt64(0)), storage_key, type, + statement.ColumnString(1) == kDefaultBucketName); + } + return buckets; +} + +QuotaError QuotaDatabase::SetStorageKeyLastAccessTime( + const StorageKey& storage_key, + StorageType type, + base::Time last_accessed) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + QuotaError open_error = EnsureOpened(EnsureOpenedMode::kCreateIfNotFound); + if (open_error != QuotaError::kNone) + return open_error; + + // Check if bucket exists first. Running an update statement on a bucket that + // doesn't exist fails DCHECK and crashes. + // TODO(crbug/1210252): Update to not execute 2 sql statements. + QuotaErrorOr<BucketInfo> result = + GetBucket(storage_key, kDefaultBucketName, type); + if (!result.ok()) { + if (result.error() != QuotaError::kNotFound) + return result.error(); + + QuotaErrorOr<BucketInfo> created_bucket = CreateBucketInternal(storage_key, type, kDefaultBucketName, /*use_count=*/1, last_accessed, last_accessed); - return result.ok(); + return created_bucket.ok() ? QuotaError::kNone : created_bucket.error(); } - ++entry.use_count; + // clang-format off static constexpr char kSql[] = - // clang-format off "UPDATE buckets " - "SET use_count = ?, last_accessed = ? " - "WHERE origin = ? AND type = ? AND name = ?"; + "SET use_count = use_count + 1, last_accessed = ? " + "WHERE id = ?"; // clang-format on sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); - statement.BindInt(0, entry.use_count); - statement.BindTime(1, last_accessed); - statement.BindString(2, storage_key.Serialize()); - statement.BindInt(3, static_cast<int>(type)); - statement.BindString(4, kDefaultBucketName); + statement.BindTime(0, last_accessed); + statement.BindInt64(1, result->id.value()); if (!statement.Run()) - return false; + return QuotaError::kDatabaseError; ScheduleCommit(); - return true; + return QuotaError::kNone; } -bool QuotaDatabase::SetBucketLastAccessTime(const BucketId bucket_id, - base::Time last_accessed) { +QuotaError QuotaDatabase::SetBucketLastAccessTime(const BucketId bucket_id, + base::Time last_accessed) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!bucket_id.is_null()); - if (LazyOpen(LazyOpenMode::kCreateIfNotFound) != QuotaError::kNone) - return false; + QuotaError open_error = EnsureOpened(EnsureOpenedMode::kFailIfNotFound); + if (open_error != QuotaError::kNone) + return open_error; BucketTableEntry entry; if (!GetBucketInfo(bucket_id, &entry)) - return false; + return QuotaError::kNotFound; - ++entry.use_count; + // clang-format off static constexpr char kSql[] = - "UPDATE buckets SET use_count = ?, last_accessed = ? WHERE id = ?"; + "UPDATE buckets " + "SET use_count = use_count + 1, last_accessed = ? " + "WHERE id = ?"; + // clang-format on 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.value()); + statement.BindTime(0, last_accessed); + statement.BindInt64(1, bucket_id.value()); if (!statement.Run()) - return false; + return QuotaError::kDatabaseError; ScheduleCommit(); - return true; + return QuotaError::kNone; } -bool QuotaDatabase::SetStorageKeyLastModifiedTime(const StorageKey& storage_key, - StorageType type, - base::Time last_modified) { +QuotaError QuotaDatabase::SetStorageKeyLastModifiedTime( + const StorageKey& storage_key, + StorageType type, + base::Time last_modified) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (LazyOpen(LazyOpenMode::kCreateIfNotFound) != QuotaError::kNone) - return false; + QuotaError open_error = EnsureOpened(EnsureOpenedMode::kCreateIfNotFound); + if (open_error != QuotaError::kNone) + return open_error; - BucketTableEntry entry; - if (!GetStorageKeyInfo(storage_key, type, &entry)) { - QuotaErrorOr<BucketInfo> result = + // Check if bucket exists first. Running an update statement on a bucket that + // doesn't exist fails DCHECK and crashes. + // TODO(crbug/1210252): Update to not execute 2 sql statements. + QuotaErrorOr<BucketInfo> result = + GetBucket(storage_key, kDefaultBucketName, type); + if (!result.ok()) { + if (result.error() != QuotaError::kNotFound) + return result.error(); + + QuotaErrorOr<BucketInfo> created_bucket = CreateBucketInternal(storage_key, type, kDefaultBucketName, /*use_count=*/0, last_modified, last_modified); - return result.ok(); + return created_bucket.ok() ? QuotaError::kNone : created_bucket.error(); } static constexpr char kSql[] = - // clang-format off - "UPDATE buckets " - "SET last_modified = ? " - "WHERE origin = ? AND type = ? AND name = ?"; - // clang-format on + "UPDATE buckets SET last_modified = ? WHERE id = ?"; sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); statement.BindTime(0, last_modified); - statement.BindString(1, storage_key.Serialize()); - statement.BindInt(2, static_cast<int>(type)); - statement.BindString(3, kDefaultBucketName); + statement.BindInt64(1, result->id.value()); if (!statement.Run()) - return false; + return QuotaError::kDatabaseError; ScheduleCommit(); - return true; + return QuotaError::kNone; } -bool QuotaDatabase::SetBucketLastModifiedTime(const BucketId bucket_id, - base::Time last_modified) { +QuotaError QuotaDatabase::SetBucketLastModifiedTime(const BucketId bucket_id, + base::Time last_modified) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!bucket_id.is_null()); - if (LazyOpen(LazyOpenMode::kCreateIfNotFound) != QuotaError::kNone) - return false; + QuotaError open_error = EnsureOpened(EnsureOpenedMode::kFailIfNotFound); + if (open_error != QuotaError::kNone) + return open_error; BucketTableEntry entry; if (!GetBucketInfo(bucket_id, &entry)) - return false; + return QuotaError::kNotFound; static constexpr char kSql[] = "UPDATE buckets SET last_modified = ? WHERE id = ?"; @@ -351,24 +439,25 @@ bool QuotaDatabase::SetBucketLastModifiedTime(const BucketId bucket_id, statement.BindInt64(1, bucket_id.value()); if (!statement.Run()) - return false; + return QuotaError::kDatabaseError; ScheduleCommit(); - return true; + return QuotaError::kNone; } bool QuotaDatabase::RegisterInitialStorageKeyInfo( const std::set<StorageKey>& storage_keys, StorageType type) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (LazyOpen(LazyOpenMode::kCreateIfNotFound) != QuotaError::kNone) + if (EnsureOpened(EnsureOpenedMode::kCreateIfNotFound) != QuotaError::kNone) return false; for (const auto& storage_key : storage_keys) { static constexpr char kSql[] = // clang-format off "INSERT OR IGNORE INTO buckets(" - "origin," + "storage_key," + "host," "type," "name," "use_count," @@ -376,13 +465,14 @@ bool QuotaDatabase::RegisterInitialStorageKeyInfo( "last_modified," "expiration," "quota) " - "VALUES (?, ?, ?, 0, 0, 0, ?, 0)"; + "VALUES (?, ?, ?, ?, 0, 0, 0, ?, 0)"; // clang-format on sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); statement.BindString(0, storage_key.Serialize()); - statement.BindInt(1, static_cast<int>(type)); - statement.BindString(2, kDefaultBucketName); - statement.BindTime(3, base::Time::Max()); + statement.BindString(1, storage_key.origin().host()); + statement.BindInt(2, static_cast<int>(type)); + statement.BindString(3, kDefaultBucketName); + statement.BindTime(4, base::Time::Max()); if (!statement.Run()) return false; @@ -392,48 +482,17 @@ bool QuotaDatabase::RegisterInitialStorageKeyInfo( return true; } -bool QuotaDatabase::GetStorageKeyInfo(const StorageKey& storage_key, - StorageType type, - QuotaDatabase::BucketTableEntry* entry) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (LazyOpen(LazyOpenMode::kFailIfNotFound) != QuotaError::kNone) - return false; - - 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, storage_key.Serialize()); - statement.BindInt(1, static_cast<int>(type)); - statement.BindString(2, kDefaultBucketName); - - if (!statement.Step()) - return false; - - *entry = BucketTableEntry(BucketId(statement.ColumnInt64(0)), storage_key, - type, kDefaultBucketName, statement.ColumnInt(1), - statement.ColumnTime(2), statement.ColumnTime(3)); - return true; -} - bool QuotaDatabase::GetBucketInfo(const BucketId bucket_id, QuotaDatabase::BucketTableEntry* entry) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!bucket_id.is_null()); - if (LazyOpen(LazyOpenMode::kFailIfNotFound) != QuotaError::kNone) + if (EnsureOpened(EnsureOpenedMode::kFailIfNotFound) != QuotaError::kNone) return false; static constexpr char kSql[] = // clang-format off "SELECT " - "origin," + "storage_key," "type," "name," "use_count," @@ -463,7 +522,7 @@ bool QuotaDatabase::GetBucketInfo(const BucketId bucket_id, bool QuotaDatabase::DeleteHostQuota( const std::string& host, StorageType type) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (LazyOpen(LazyOpenMode::kFailIfNotFound) != QuotaError::kNone) + if (EnsureOpened(EnsureOpenedMode::kFailIfNotFound) != QuotaError::kNone) return false; static constexpr char kSql[] = @@ -482,11 +541,11 @@ bool QuotaDatabase::DeleteHostQuota( bool QuotaDatabase::DeleteStorageKeyInfo(const StorageKey& storage_key, StorageType type) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (LazyOpen(LazyOpenMode::kFailIfNotFound) != QuotaError::kNone) + if (EnsureOpened(EnsureOpenedMode::kFailIfNotFound) != QuotaError::kNone) return false; static constexpr char kSql[] = - "DELETE FROM buckets WHERE origin = ? AND type = ?"; + "DELETE FROM buckets WHERE storage_key = ? AND type = ?"; sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); statement.BindString(0, storage_key.Serialize()); statement.BindInt(1, static_cast<int>(type)); @@ -501,7 +560,7 @@ bool QuotaDatabase::DeleteStorageKeyInfo(const StorageKey& storage_key, bool QuotaDatabase::DeleteBucketInfo(const BucketId bucket_id) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!bucket_id.is_null()); - if (LazyOpen(LazyOpenMode::kFailIfNotFound) != QuotaError::kNone) + if (EnsureOpened(EnsureOpenedMode::kFailIfNotFound) != QuotaError::kNone) return false; static constexpr char kSql[] = "DELETE FROM buckets WHERE id = ?"; @@ -520,13 +579,13 @@ QuotaErrorOr<BucketInfo> QuotaDatabase::GetLRUBucket( const std::set<BucketId>& bucket_exceptions, SpecialStoragePolicy* special_storage_policy) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - QuotaError open_error = LazyOpen(LazyOpenMode::kFailIfNotFound); + QuotaError open_error = EnsureOpened(EnsureOpenedMode::kFailIfNotFound); if (open_error != QuotaError::kNone) return open_error; // clang-format off static constexpr char kSql[] = - "SELECT id, origin, name, expiration, quota " + "SELECT id, storage_key, name, expiration, quota " "FROM buckets " "WHERE type = ? " "ORDER BY last_accessed"; @@ -563,12 +622,12 @@ QuotaErrorOr<BucketInfo> QuotaDatabase::GetLRUBucket( QuotaErrorOr<std::set<StorageKey>> QuotaDatabase::GetStorageKeysForType( StorageType type) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - QuotaError open_error = LazyOpen(LazyOpenMode::kFailIfNotFound); + QuotaError open_error = EnsureOpened(EnsureOpenedMode::kFailIfNotFound); if (open_error != QuotaError::kNone) return open_error; static constexpr char kSql[] = - "SELECT DISTINCT origin FROM buckets WHERE type = ?"; + "SELECT DISTINCT storage_key FROM buckets WHERE type = ?"; sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); statement.BindInt(0, static_cast<int>(type)); @@ -589,7 +648,7 @@ QuotaErrorOr<std::set<BucketInfo>> QuotaDatabase::GetBucketsModifiedBetween( base::Time begin, base::Time end) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - QuotaError open_error = LazyOpen(LazyOpenMode::kFailIfNotFound); + QuotaError open_error = EnsureOpened(EnsureOpenedMode::kFailIfNotFound); if (open_error != QuotaError::kNone) return open_error; @@ -597,7 +656,7 @@ QuotaErrorOr<std::set<BucketInfo>> QuotaDatabase::GetBucketsModifiedBetween( DCHECK(end != base::Time()); // clang-format off static constexpr char kSql[] = - "SELECT id, origin, name, expiration, quota FROM buckets " + "SELECT id, storage_key, name, expiration, quota FROM buckets " "WHERE type = ? AND last_modified >= ? AND last_modified < ?"; // clang-format on @@ -612,17 +671,16 @@ QuotaErrorOr<std::set<BucketInfo>> QuotaDatabase::GetBucketsModifiedBetween( StorageKey::Deserialize(statement.ColumnString(1)); if (!read_storage_key.has_value()) continue; - buckets.emplace( - BucketInfo(BucketId(statement.ColumnInt64(0)), read_storage_key.value(), - type, statement.ColumnString(2), statement.ColumnTime(3), - statement.ColumnInt(4))); + buckets.emplace(BucketId(statement.ColumnInt64(0)), + read_storage_key.value(), type, statement.ColumnString(2), + statement.ColumnTime(3), statement.ColumnInt(4)); } return buckets; } bool QuotaDatabase::IsBootstrappedForEviction() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (LazyOpen(LazyOpenMode::kCreateIfNotFound) != QuotaError::kNone) + if (EnsureOpened(EnsureOpenedMode::kCreateIfNotFound) != QuotaError::kNone) return false; int flag = 0; @@ -631,7 +689,7 @@ bool QuotaDatabase::IsBootstrappedForEviction() { bool QuotaDatabase::SetBootstrappedForEviction(bool bootstrap_flag) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (LazyOpen(LazyOpenMode::kCreateIfNotFound) != QuotaError::kNone) + if (EnsureOpened(EnsureOpenedMode::kCreateIfNotFound) != QuotaError::kNone) return false; return meta_table_->SetValue(kIsOriginTableBootstrapped, bootstrap_flag); @@ -656,11 +714,11 @@ void QuotaDatabase::ScheduleCommit() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (timer_.IsRunning()) return; - timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(kCommitIntervalMs), - this, &QuotaDatabase::Commit); + timer_.Start(FROM_HERE, base::Milliseconds(kCommitIntervalMs), this, + &QuotaDatabase::Commit); } -QuotaError QuotaDatabase::LazyOpen(LazyOpenMode mode) { +QuotaError QuotaDatabase::EnsureOpened(EnsureOpenedMode mode) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (db_) return QuotaError::kNone; @@ -671,7 +729,7 @@ QuotaError QuotaDatabase::LazyOpen(LazyOpenMode mode) { return QuotaError::kDatabaseError; bool in_memory_only = db_file_path_.empty(); - if (mode == LazyOpenMode::kFailIfNotFound && + if (mode == EnsureOpenedMode::kFailIfNotFound && (in_memory_only || !base::PathExists(db_file_path_))) { return QuotaError::kNotFound; } @@ -833,7 +891,7 @@ bool QuotaDatabase::ResetSchema() { return false; base::AutoReset<bool> auto_reset(&is_recreating_, true); - return LazyOpen(LazyOpenMode::kCreateIfNotFound) == QuotaError::kNone; + return EnsureOpened(EnsureOpenedMode::kCreateIfNotFound) == QuotaError::kNone; } bool QuotaDatabase::InsertOrReplaceHostQuota(const std::string& host, @@ -855,7 +913,7 @@ bool QuotaDatabase::InsertOrReplaceHostQuota(const std::string& host, bool QuotaDatabase::DumpQuotaTable(const QuotaTableCallback& callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (LazyOpen(LazyOpenMode::kCreateIfNotFound) != QuotaError::kNone) + if (EnsureOpened(EnsureOpenedMode::kCreateIfNotFound) != QuotaError::kNone) return false; static constexpr char kSql[] = "SELECT * FROM quota"; @@ -877,14 +935,14 @@ bool QuotaDatabase::DumpQuotaTable(const QuotaTableCallback& callback) { bool QuotaDatabase::DumpBucketTable(const BucketTableCallback& callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (LazyOpen(LazyOpenMode::kCreateIfNotFound) != QuotaError::kNone) + if (EnsureOpened(EnsureOpenedMode::kCreateIfNotFound) != QuotaError::kNone) return false; static constexpr char kSql[] = // clang-format off "SELECT " "id," - "origin," + "storage_key," "type," "name," "use_count," @@ -922,14 +980,15 @@ QuotaErrorOr<BucketInfo> QuotaDatabase::CreateBucketInternal( base::Time last_modified) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // TODO(crbug/1210259): Add DCHECKs for input validation. - QuotaError open_error = LazyOpen(LazyOpenMode::kCreateIfNotFound); + QuotaError open_error = EnsureOpened(EnsureOpenedMode::kCreateIfNotFound); if (open_error != QuotaError::kNone) return open_error; static constexpr char kSql[] = // clang-format off "INSERT INTO buckets(" - "origin," + "storage_key," + "host," "type," "name," "use_count," @@ -937,16 +996,17 @@ QuotaErrorOr<BucketInfo> QuotaDatabase::CreateBucketInternal( "last_modified," "expiration," "quota) " - "VALUES (?, ?, ?, ?, ?, ?, ?, 0)"; + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0)"; // clang-format on sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); statement.BindString(0, storage_key.Serialize()); - statement.BindInt(1, static_cast<int>(type)); - statement.BindString(2, bucket_name); - statement.BindInt(3, use_count); - statement.BindTime(4, last_accessed); - statement.BindTime(5, last_modified); - statement.BindTime(6, base::Time::Max()); + statement.BindString(1, storage_key.origin().host()); + statement.BindInt(2, static_cast<int>(type)); + statement.BindString(3, bucket_name); + statement.BindInt(4, use_count); + statement.BindTime(5, last_accessed); + statement.BindTime(6, last_modified); + statement.BindTime(7, base::Time::Max()); if (!statement.Run()) return QuotaError::kDatabaseError; diff --git a/chromium/storage/browser/quota/quota_database.h b/chromium/storage/browser/quota/quota_database.h index a9ce00f1c7d..5864a9a3bf3 100644 --- a/chromium/storage/browser/quota/quota_database.h +++ b/chromium/storage/browser/quota/quota_database.h @@ -13,6 +13,7 @@ #include <string> #include "base/callback.h" +#include "base/compiler_specific.h" #include "base/component_export.h" #include "base/files/file_path.h" #include "base/macros.h" @@ -22,6 +23,7 @@ #include "base/types/id_type.h" #include "components/services/storage/public/cpp/buckets/bucket_id.h" #include "components/services/storage/public/cpp/buckets/bucket_info.h" +#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "components/services/storage/public/cpp/buckets/constants.h" #include "components/services/storage/public/cpp/quota_error_or.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -81,10 +83,12 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaDatabase { base::Time last_modified; }; - enum class LazyOpenMode { kCreateIfNotFound, kFailIfNotFound }; - // If 'path' is empty, an in memory database will be used. explicit QuotaDatabase(const base::FilePath& path); + + QuotaDatabase(const QuotaDatabase&) = delete; + QuotaDatabase& operator=(const QuotaDatabase&) = delete; + ~QuotaDatabase(); // Returns whether the record could be found. @@ -121,27 +125,50 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaDatabase { const std::string& bucket_name, blink::mojom::StorageType storage_type); + // Returns all buckets for `type` in the buckets table. Returns a QuotaError + // if the operation has failed. + QuotaErrorOr<std::set<BucketLocator>> GetBucketsForType( + blink::mojom::StorageType type); + + // Retrieves all buckets for `host` and `type`. Returns a QuotaError if the + // operation has failed. + QuotaErrorOr<std::set<BucketLocator>> GetBucketsForHost( + const std::string& host, + blink::mojom::StorageType type); + + // Returns all buckets for `storage_key` in the buckets table. Returns a + // QuotaError if the operation has failed. + QuotaErrorOr<std::set<BucketLocator>> GetBucketsForStorageKey( + const blink::StorageKey& storage_key, + blink::mojom::StorageType type); + // TODO(crbug.com/1202167): Remove once all usages have updated to use // SetBucketLastAccessTime. - bool SetStorageKeyLastAccessTime(const blink::StorageKey& storage_key, - blink::mojom::StorageType type, - base::Time last_accessed); + QuotaError SetStorageKeyLastAccessTime(const blink::StorageKey& storage_key, + blink::mojom::StorageType type, + base::Time last_accessed) + WARN_UNUSED_RESULT; // Called by QuotaClient implementers to update when the bucket was last // accessed. If `bucket_id` refers to a bucket with an opaque StorageKey, the // bucket's last access time will not be updated and the function will return - // false. - bool SetBucketLastAccessTime(BucketId bucket_id, base::Time last_accessed); + // QuotaError::kNotFound. Returns QuotaError::kNone on a successful update. + QuotaError SetBucketLastAccessTime(BucketId bucket_id, + base::Time last_accessed) + WARN_UNUSED_RESULT; // TODO(crbug.com/1202167): Remove once all usages have updated to use // SetBucketLastModifiedTime. - bool SetStorageKeyLastModifiedTime(const blink::StorageKey& storage_key, - blink::mojom::StorageType type, - base::Time last_modified); + QuotaError SetStorageKeyLastModifiedTime(const blink::StorageKey& storage_key, + blink::mojom::StorageType type, + base::Time last_modified) + WARN_UNUSED_RESULT; // Called by QuotaClient implementers to update when the bucket was last - // modified. - bool SetBucketLastModifiedTime(BucketId bucket_id, base::Time last_modified); + // modified. Returns QuotaError::kNone on a successful update. + QuotaError SetBucketLastModifiedTime(BucketId bucket_id, + base::Time last_modified) + WARN_UNUSED_RESULT; // Register initial `storage_keys` info `type` to the database. // This method is assumed to be called only after the installation or @@ -150,13 +177,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaDatabase { const std::set<blink::StorageKey>& storage_keys, blink::mojom::StorageType type); - // TODO(crbug.com/1202167): Remove once all usages have been updated to use - // GetBucketInfo. Gets the BucketTableEntry for `storage_key`. Returns whether - // the record for a storage key's default bucket could be found. - bool GetStorageKeyInfo(const blink::StorageKey& storage_key, - blink::mojom::StorageType type, - BucketTableEntry* entry); - // Gets the table entry for `bucket`. Returns whether the record for an // origin bucket can be found. bool GetBucketInfo(BucketId bucket_id, BucketTableEntry* entry); @@ -176,7 +196,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaDatabase { const std::set<BucketId>& bucket_exceptions, SpecialStoragePolicy* special_storage_policy); - // Returns all storage keys for `type` in the bucket database. + // Returns all storage keys for `type` in the buckets table. QuotaErrorOr<std::set<blink::StorageKey>> GetStorageKeysForType( blink::mojom::StorageType type); @@ -197,6 +217,8 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaDatabase { void SetDisabledForTesting(bool disable) { is_disabled_ = disable; } private: + enum class EnsureOpenedMode { kCreateIfNotFound, kFailIfNotFound }; + struct COMPONENT_EXPORT(STORAGE_BROWSER) QuotaTableEntry { std::string host; blink::mojom::StorageType type = blink::mojom::StorageType::kUnknown; @@ -236,7 +258,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaDatabase { void Commit(); void ScheduleCommit(); - QuotaError LazyOpen(LazyOpenMode mode); + QuotaError EnsureOpened(EnsureOpenedMode mode); bool OpenDatabase(); bool EnsureDatabaseVersion(); bool ResetSchema(); @@ -267,8 +289,8 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaDatabase { std::unique_ptr<sql::Database> db_; std::unique_ptr<sql::MetaTable> meta_table_; - bool is_recreating_; - bool is_disabled_; + bool is_recreating_ = false; + bool is_disabled_ = false; base::OneShotTimer timer_; @@ -283,7 +305,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaDatabase { static const size_t kIndexCount; SEQUENCE_CHECKER(sequence_checker_); - DISALLOW_COPY_AND_ASSIGN(QuotaDatabase); }; } // namespace storage diff --git a/chromium/storage/browser/quota/quota_database_migrations.cc b/chromium/storage/browser/quota/quota_database_migrations.cc index f4c78254c91..31780a3f513 100644 --- a/chromium/storage/browser/quota/quota_database_migrations.cc +++ b/chromium/storage/browser/quota/quota_database_migrations.cc @@ -6,11 +6,13 @@ #include <string> +#include "components/services/storage/public/cpp/buckets/bucket_id.h" #include "sql/database.h" #include "sql/meta_table.h" #include "sql/statement.h" #include "sql/transaction.h" #include "storage/browser/quota/quota_database.h" +#include "third_party/blink/public/common/storage_key/storage_key.h" namespace storage { @@ -32,7 +34,12 @@ bool QuotaDatabaseMigrations::UpgradeSchema(QuotaDatabase& quota_database) { return false; } - return quota_database.meta_table_->GetVersionNumber() == 7; + if (quota_database.meta_table_->GetVersionNumber() == 7) { + if (!MigrateFromVersion7ToVersion8(quota_database)) + return false; + } + + return quota_database.meta_table_->GetVersionNumber() == 8; } bool QuotaDatabaseMigrations::MigrateFromVersion5ToVersion7( @@ -42,21 +49,39 @@ bool QuotaDatabaseMigrations::MigrateFromVersion5ToVersion7( 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 host quota table version 7. + // clang-format off + static constexpr char kQuotaTableSql[] = + "CREATE TABLE IF NOT EXISTS quota(" + "host TEXT NOT NULL, " + "type INTEGER NOT NULL, " + "quota INTEGER NOT NULL, " + "PRIMARY KEY(host, type)) " + "WITHOUT ROWID"; + // clang-format on + if (!db->Execute(kQuotaTableSql)) + 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; - } + // Create buckets table version 7. + // clang-format off + static constexpr char kBucketsTableSql[] = + "CREATE TABLE IF NOT EXISTS buckets(" + "id INTEGER PRIMARY KEY, " + "origin TEXT NOT NULL, " + "type INTEGER NOT NULL, " + "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)"; + // clang-format on + if (!db->Execute(kBucketsTableSql)) + return false; - // Copy OriginInfoTable data into new bucket table. - const char kImportOriginInfoSql[] = - // clang-format off + // Copy OriginInfoTable data into new buckets table. + // clang-format off + static constexpr char kImportOriginInfoSql[] = "INSERT INTO buckets(" "origin," "type," @@ -85,13 +110,14 @@ bool QuotaDatabaseMigrations::MigrateFromVersion5ToVersion7( return false; // Delete OriginInfoTable. - const char kDeleteOriginInfoTableSql[] = "DROP TABLE OriginInfoTable"; + static constexpr 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 + // clang-format off + static constexpr char kImportQuotaSql[] = "INSERT INTO quota(host, type, quota) " "SELECT host, type, quota " "FROM HostQuotaTable"; @@ -102,12 +128,14 @@ bool QuotaDatabaseMigrations::MigrateFromVersion5ToVersion7( return false; // Delete HostQuotaTable. - const char kDeleteQuotaHostTableSql[] = "DROP TABLE HostQuotaTable"; + static constexpr char kDeleteQuotaHostTableSql[] = + "DROP TABLE HostQuotaTable"; if (!db->Execute(kDeleteQuotaHostTableSql)) return false; // Delete EvictionInfoTable. - const char kDeleteEvictionInfoTableSql[] = "DROP TABLE EvictionInfoTable"; + static constexpr char kDeleteEvictionInfoTableSql[] = + "DROP TABLE EvictionInfoTable"; if (!db->Execute(kDeleteEvictionInfoTableSql)) return false; @@ -124,7 +152,8 @@ bool QuotaDatabaseMigrations::MigrateFromVersion6ToVersion7( if (!transaction.Begin()) return false; - const char kDeleteEvictionInfoTableSql[] = "DROP TABLE eviction_info"; + static constexpr char kDeleteEvictionInfoTableSql[] = + "DROP TABLE eviction_info"; if (!db->Execute(kDeleteEvictionInfoTableSql)) return false; @@ -133,4 +162,137 @@ bool QuotaDatabaseMigrations::MigrateFromVersion6ToVersion7( return transaction.Commit(); } +bool QuotaDatabaseMigrations::MigrateFromVersion7ToVersion8( + QuotaDatabase& quota_database) { + sql::Database* db = quota_database.db_.get(); + sql::Transaction transaction(db); + if (!transaction.Begin()) + return false; + + // Create new buckets table. + // clang-format off + static constexpr char kNewBucketsTableSql[] = + "CREATE TABLE IF NOT EXISTS new_buckets(" + "id INTEGER PRIMARY KEY, " + "storage_key TEXT NOT NULL, " + "host TEXT NOT NULL, " + "type INTEGER NOT NULL, " + "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)"; + // clang-format on + if (!db->Execute(kNewBucketsTableSql)) + return false; + + // clang-format off + static constexpr char kSelectBucketSql[] = + "SELECT " + "id,origin,type,name,use_count,last_accessed,last_modified," + "expiration, quota " + "FROM buckets " + "WHERE id > ? " + "ORDER BY id " + "LIMIT 1"; + // clang-format on + sql::Statement select_statement( + db->GetCachedStatement(SQL_FROM_HERE, kSelectBucketSql)); + + // clang-format off + static constexpr char kInsertBucketSql[] = + "INSERT into new_buckets(" + "id,storage_key,host,type,name,use_count,last_accessed," + "last_modified,expiration,quota) " + "VALUES(?,?,?,?,?,?,?,?,?,?)"; + // clang-format on + sql::Statement insert_statement( + db->GetCachedStatement(SQL_FROM_HERE, kInsertBucketSql)); + + // Transfer bucket data to the new table one at a time with new host data. + BucketId lastBucketId(0); + while (true) { + select_statement.BindInt64(0, lastBucketId.value()); + if (!select_statement.Step()) + break; + + // Populate bucket id. + BucketId bucket_id(select_statement.ColumnInt64(0)); + insert_statement.BindInt64(0, bucket_id.value()); + + // Populate storage key and host. + std::string storage_key_string = select_statement.ColumnString(1); + insert_statement.BindString(1, storage_key_string); + + absl::optional<blink::StorageKey> storage_key = + blink::StorageKey::Deserialize(storage_key_string); + const std::string& host = storage_key.has_value() + ? storage_key.value().origin().host() + : std::string(); + insert_statement.BindString(2, host); + + // Populate type, name, use_count, last_accessed, last_modified, + // expiration and quota. + insert_statement.BindInt(3, select_statement.ColumnInt(2)); + insert_statement.BindString(4, select_statement.ColumnString(3)); + insert_statement.BindInt(5, select_statement.ColumnInt(4)); + insert_statement.BindTime(6, select_statement.ColumnTime(5)); + insert_statement.BindTime(7, select_statement.ColumnTime(6)); + insert_statement.BindTime(8, select_statement.ColumnTime(7)); + insert_statement.BindInt(9, select_statement.ColumnInt(8)); + + if (!insert_statement.Run()) + return false; + + select_statement.Reset(/*clear_bound_vars=*/true); + insert_statement.Reset(/*clear_bound_vars=*/true); + lastBucketId = bucket_id; + } + + // Replace buckets table with new table. + static constexpr char kDeleteBucketTableSql[] = "DROP TABLE buckets"; + if (!db->Execute(kDeleteBucketTableSql)) + return false; + + static constexpr char kRenameBucketTableSql[] = + "ALTER TABLE new_buckets RENAME to buckets"; + if (!db->Execute(kRenameBucketTableSql)) + return false; + + // Create indices on new table. + // clang-format off + static constexpr char kStorageKeyIndexSql[] = + "CREATE UNIQUE INDEX buckets_by_storage_key " + "ON buckets(storage_key, type, name)"; + // clang-format on + if (!db->Execute(kStorageKeyIndexSql)) + return false; + + static constexpr char kHostIndexSql[] = + "CREATE INDEX buckets_by_host ON buckets(host, type)"; + if (!db->Execute(kHostIndexSql)) + return false; + + static constexpr char kLastAccessedIndexSql[] = + "CREATE INDEX buckets_by_last_accessed ON buckets(type, last_accessed)"; + if (!db->Execute(kLastAccessedIndexSql)) + return false; + + static constexpr char kLastModifiedIndexSql[] = + "CREATE INDEX buckets_by_last_modified ON buckets(type, last_modified)"; + if (!db->Execute(kLastModifiedIndexSql)) + return false; + + static constexpr char kExpirationIndexSql[] = + "CREATE INDEX buckets_by_expiration ON buckets(expiration)"; + if (!db->Execute(kExpirationIndexSql)) + return false; + + // Mark database as up to date. + quota_database.meta_table_->SetVersionNumber(8); + quota_database.meta_table_->SetCompatibleVersionNumber(8); + 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 index b30f6362a2c..2806597d327 100644 --- a/chromium/storage/browser/quota/quota_database_migrations.h +++ b/chromium/storage/browser/quota/quota_database_migrations.h @@ -25,6 +25,7 @@ class QuotaDatabaseMigrations { private: static bool MigrateFromVersion5ToVersion7(QuotaDatabase& quota_database); static bool MigrateFromVersion6ToVersion7(QuotaDatabase& quota_database); + static bool MigrateFromVersion7ToVersion8(QuotaDatabase& quota_database); }; } // namespace storage diff --git a/chromium/storage/browser/quota/quota_database_migrations_unittest.cc b/chromium/storage/browser/quota/quota_database_migrations_unittest.cc index d5970f19d72..436552e8cf9 100644 --- a/chromium/storage/browser/quota/quota_database_migrations_unittest.cc +++ b/chromium/storage/browser/quota/quota_database_migrations_unittest.cc @@ -16,8 +16,14 @@ namespace storage { namespace { -const int kCurrentSchemaVersion = 7; -const int kCurrentCompatibleVersion = 7; +const int kCurrentSchemaVersion = 8; +const int kCurrentCompatibleVersion = 8; + +std::string RemoveQuotes(std::string input) { + std::string output; + base::RemoveChars(input, "\"", &output); + return output; +} } // namespace @@ -59,15 +65,16 @@ class QuotaDatabaseMigrationsTest : public testing::Test { void MigrateDatabase() { QuotaDatabase db(DbPath()); - EXPECT_EQ(db.LazyOpen(QuotaDatabase::LazyOpenMode::kCreateIfNotFound), - QuotaError::kNone); + EXPECT_EQ( + db.EnsureOpened(QuotaDatabase::EnsureOpenedMode::kCreateIfNotFound), + QuotaError::kNone); EXPECT_TRUE(db.db_.get()); } std::string GetCurrentSchema() { base::FilePath current_version_path = temp_directory_.GetPath().AppendASCII("current_version.db"); - EXPECT_TRUE(LoadDatabase("version_7.sql", current_version_path)); + EXPECT_TRUE(LoadDatabase("version_8.sql", current_version_path)); sql::Database db; EXPECT_TRUE(db.Open(current_version_path)); return db.GetSchema(); @@ -131,21 +138,21 @@ TEST_F(QuotaDatabaseMigrationsTest, UpgradeSchemaFromV5) { // Check that OriginInfoTable data is migrated to bucket table. EXPECT_EQ( - "1|http://a/|0|default|123|13260644621105493|13242931862595604|" + "1|http://a/|a|0|default|123|13260644621105493|13242931862595604|" "9223372036854775807|0," - "2|http://b/|0|default|111|13250042735631065|13260999511438890|" + "2|http://b/|b|0|default|111|13250042735631065|13260999511438890|" "9223372036854775807|0," - "3|http://c/|1|default|321|13261163582572088|13261079941303629|" + "3|http://c/|c|1|default|321|13261163582572088|13261079941303629|" "9223372036854775807|0", sql::test::ExecuteWithResults( - &db, "SELECT * FROM buckets ORDER BY origin ASC", "|", ",")); + &db, "SELECT * FROM buckets ORDER BY storage_key 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()); + EXPECT_EQ(GetCurrentSchema(), RemoveQuotes(db.GetSchema())); } } @@ -176,7 +183,7 @@ TEST_F(QuotaDatabaseMigrationsTest, UpgradeSchemaFromV6) { "3|http://c/|1|bucket_c|321|13261163582572088|13261079941303629|" "9223372036854775807|10000", sql::test::ExecuteWithResults( - &db, "SELECT * FROM buckets ORDER BY origin ASC", "|", ",")); + &db, "SELECT * FROM buckets ORDER BY id ASC", "|", ",")); EXPECT_EQ("a.com,b.com,c.com", sql::test::ExecuteWithResults( @@ -203,21 +210,92 @@ TEST_F(QuotaDatabaseMigrationsTest, UpgradeSchemaFromV6) { // Check that buckets data is still present. EXPECT_EQ( + "1|http://a/|a|0|bucket_a|123|13260644621105493|13242931862595604|" + "9223372036854775807|0," + "2|http://b/|b|0|bucket_b|111|13250042735631065|13260999511438890|" + "9223372036854775807|1000," + "3|http://c/|c|1|bucket_c|321|13261163582572088|13261079941303629|" + "9223372036854775807|10000", + sql::test::ExecuteWithResults( + &db, "SELECT * FROM buckets ORDER BY id ASC", "|", ",")); + + // Check that quota data is still present. + EXPECT_EQ("a.com,b.com,c.com", + sql::test::ExecuteWithResults( + &db, "SELECT host FROM quota ORDER BY host ASC", "|", ",")); + + EXPECT_EQ(GetCurrentSchema(), RemoveQuotes(db.GetSchema())); + } +} + +TEST_F(QuotaDatabaseMigrationsTest, UpgradeSchemaFromV7) { + ASSERT_TRUE(LoadDatabase("version_7.sql", DbPath())); + + { + sql::Database db; + ASSERT_TRUE(db.Open(DbPath())); + + ASSERT_TRUE(sql::MetaTable::DoesTableExist(&db)); + sql::MetaTable meta_table; + ASSERT_TRUE( + meta_table.Init(&db, kCurrentSchemaVersion, kCurrentCompatibleVersion)); + ASSERT_EQ(meta_table.GetVersionNumber(), 7); + ASSERT_EQ(meta_table.GetCompatibleVersionNumber(), 7); + + ASSERT_TRUE(db.DoesTableExist("quota")); + ASSERT_TRUE(db.DoesTableExist("buckets")); + + // Check populated data. + EXPECT_EQ( "1|http://a/|0|bucket_a|123|13260644621105493|13242931862595604|" "9223372036854775807|0," "2|http://b/|0|bucket_b|111|13250042735631065|13260999511438890|" "9223372036854775807|1000," - "3|http://c/|1|bucket_c|321|13261163582572088|13261079941303629|" - "9223372036854775807|10000", + "3|chrome-extension://abc/|1|default|321|13261163582572088|" + "13261079941303629|9223372036854775807|10000", + sql::test::ExecuteWithResults( + &db, "SELECT * FROM buckets ORDER BY id ASC", "|", ",")); + + EXPECT_EQ("a.com,b.com,c.com", + sql::test::ExecuteWithResults( + &db, "SELECT host FROM quota ORDER BY host ASC", "|", ",")); + } + + MigrateDatabase(); + + // Verify upgraded schema. + { + sql::Database db; + ASSERT_TRUE(db.Open(DbPath())); + + ASSERT_TRUE(sql::MetaTable::DoesTableExist(&db)); + sql::MetaTable meta_table; + ASSERT_TRUE( + meta_table.Init(&db, kCurrentSchemaVersion, kCurrentCompatibleVersion)); + ASSERT_EQ(meta_table.GetVersionNumber(), kCurrentSchemaVersion); + ASSERT_EQ(meta_table.GetCompatibleVersionNumber(), kCurrentSchemaVersion); + + ASSERT_TRUE(db.DoesTableExist("quota")); + ASSERT_TRUE(db.DoesTableExist("buckets")); + ASSERT_FALSE(db.DoesTableExist("eviction_info")); + + // Check that buckets data is still present. + EXPECT_EQ( + "1|http://a/|a|0|bucket_a|123|13260644621105493|13242931862595604|" + "9223372036854775807|0," + "2|http://b/|b|0|bucket_b|111|13250042735631065|13260999511438890|" + "9223372036854775807|1000," + "3|chrome-extension://abc/||1|default|321|13261163582572088|" + "13261079941303629|9223372036854775807|10000", sql::test::ExecuteWithResults( - &db, "SELECT * FROM buckets ORDER BY origin ASC", "|", ",")); + &db, "SELECT * FROM buckets ORDER BY id ASC", "|", ",")); // Check that quota data is still present. 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()); + EXPECT_EQ(GetCurrentSchema(), RemoveQuotes(db.GetSchema())); } } diff --git a/chromium/storage/browser/quota/quota_database_unittest.cc b/chromium/storage/browser/quota/quota_database_unittest.cc index 008b65e426f..0a82637cb26 100644 --- a/chromium/storage/browser/quota/quota_database_unittest.cc +++ b/chromium/storage/browser/quota/quota_database_unittest.cc @@ -17,6 +17,7 @@ #include "base/test/metrics/histogram_tester.h" #include "base/test/task_environment.h" #include "build/build_config.h" +#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "components/services/storage/public/cpp/buckets/constants.h" #include "sql/database.h" #include "sql/meta_table.h" @@ -41,6 +42,15 @@ static const blink::mojom::StorageType kTemp = static const blink::mojom::StorageType kPerm = blink::mojom::StorageType::kPersistent; +bool ContainsBucket(const std::set<BucketLocator>& buckets, + const BucketInfo& target_bucket) { + BucketLocator target_bucket_locator( + target_bucket.id, target_bucket.storage_key, target_bucket.type, + target_bucket.name == kDefaultBucketName); + auto it = buckets.find(target_bucket_locator); + return it != buckets.end(); +} + } // namespace // Test parameter indicates if the database should be created for incognito @@ -49,7 +59,7 @@ class QuotaDatabaseTest : public testing::TestWithParam<bool> { protected: using QuotaTableEntry = QuotaDatabase::QuotaTableEntry; using BucketTableEntry = QuotaDatabase::BucketTableEntry; - using LazyOpenMode = QuotaDatabase::LazyOpenMode; + using EnsureOpenedMode = QuotaDatabase::EnsureOpenedMode; void SetUp() override { ASSERT_TRUE(temp_directory_.CreateUniqueTempDir()); } @@ -61,8 +71,8 @@ class QuotaDatabaseTest : public testing::TestWithParam<bool> { return temp_directory_.GetPath().AppendASCII("quota_manager.db"); } - bool LazyOpen(QuotaDatabase* db, LazyOpenMode mode) { - return db->LazyOpen(mode) == QuotaError::kNone; + bool EnsureOpened(QuotaDatabase* db, EnsureOpenedMode mode) { + return db->EnsureOpened(mode) == QuotaError::kNone; } template <typename EntryType> @@ -119,7 +129,8 @@ class QuotaDatabaseTest : public testing::TestWithParam<bool> { // clang-format off "INSERT INTO buckets(" "id," - "origin," + "storage_key," + "host," "type," "name," "use_count," @@ -127,7 +138,7 @@ class QuotaDatabaseTest : public testing::TestWithParam<bool> { "last_modified," "expiration," "quota) " - "VALUES (?, ?, ?, ?, ?, ?, ?, 0, 0)"; + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0, 0)"; // clang-format on sql::Statement statement; statement.Assign( @@ -136,11 +147,12 @@ class QuotaDatabaseTest : public testing::TestWithParam<bool> { statement.BindInt64(0, entry.bucket_id.value()); statement.BindString(1, entry.storage_key.Serialize()); - 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); + statement.BindString(2, entry.storage_key.origin().host()); + statement.BindInt(3, static_cast<int>(entry.type)); + statement.BindString(4, entry.name); + statement.BindInt(5, entry.use_count); + statement.BindTime(6, entry.last_accessed); + statement.BindTime(7, entry.last_modified); EXPECT_TRUE(statement.Run()); } quota_database->Commit(); @@ -151,10 +163,10 @@ class QuotaDatabaseTest : public testing::TestWithParam<bool> { base::ScopedTempDir temp_directory_; }; -TEST_P(QuotaDatabaseTest, LazyOpen) { +TEST_P(QuotaDatabaseTest, EnsureOpened) { QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); - EXPECT_FALSE(LazyOpen(&db, LazyOpenMode::kFailIfNotFound)); - EXPECT_TRUE(LazyOpen(&db, LazyOpenMode::kCreateIfNotFound)); + EXPECT_FALSE(EnsureOpened(&db, EnsureOpenedMode::kFailIfNotFound)); + EXPECT_TRUE(EnsureOpened(&db, EnsureOpenedMode::kCreateIfNotFound)); if (GetParam()) { // Path should not exist for incognito mode. @@ -166,7 +178,7 @@ TEST_P(QuotaDatabaseTest, LazyOpen) { TEST_P(QuotaDatabaseTest, HostQuota) { QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); - EXPECT_TRUE(LazyOpen(&db, LazyOpenMode::kCreateIfNotFound)); + EXPECT_TRUE(EnsureOpened(&db, EnsureOpenedMode::kCreateIfNotFound)); const char* kHost = "foo.com"; const int kQuota1 = 13579; @@ -200,7 +212,7 @@ TEST_P(QuotaDatabaseTest, HostQuota) { TEST_P(QuotaDatabaseTest, GetOrCreateBucket) { QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); - EXPECT_TRUE(LazyOpen(&db, LazyOpenMode::kCreateIfNotFound)); + EXPECT_TRUE(EnsureOpened(&db, EnsureOpenedMode::kCreateIfNotFound)); StorageKey storage_key = StorageKey::CreateFromStringForTesting("http://google/"); std::string bucket_name = "google_bucket"; @@ -228,7 +240,7 @@ TEST_P(QuotaDatabaseTest, GetOrCreateBucket) { TEST_P(QuotaDatabaseTest, GetBucket) { QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); - EXPECT_TRUE(LazyOpen(&db, LazyOpenMode::kCreateIfNotFound)); + EXPECT_TRUE(EnsureOpened(&db, EnsureOpenedMode::kCreateIfNotFound)); // Add a bucket entry into the bucket table. StorageKey storage_key = @@ -264,9 +276,132 @@ TEST_P(QuotaDatabaseTest, GetBucket) { EXPECT_EQ(result.error(), QuotaError::kNotFound); } +TEST_P(QuotaDatabaseTest, GetBucketsForType) { + QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); + EXPECT_TRUE(EnsureOpened(&db, EnsureOpenedMode::kCreateIfNotFound)); + + const StorageKey storage_key1 = + StorageKey::CreateFromStringForTesting("http://example-a/"); + const StorageKey storage_key2 = + StorageKey::CreateFromStringForTesting("http://example-b/"); + const StorageKey storage_key3 = + StorageKey::CreateFromStringForTesting("http://example-c/"); + + QuotaErrorOr<BucketInfo> bucket_result = + db.CreateBucketForTesting(storage_key1, "temp_bucket", kTemp); + ASSERT_TRUE(bucket_result.ok()); + BucketInfo temp_bucket1 = bucket_result.value(); + + bucket_result = db.CreateBucketForTesting(storage_key2, "temp_bucket", kTemp); + ASSERT_TRUE(bucket_result.ok()); + BucketInfo temp_bucket2 = bucket_result.value(); + + bucket_result = db.CreateBucketForTesting(storage_key1, "perm_bucket", kPerm); + ASSERT_TRUE(bucket_result.ok()); + BucketInfo perm_bucket1 = bucket_result.value(); + + bucket_result = db.CreateBucketForTesting(storage_key3, "perm_bucket", kPerm); + ASSERT_TRUE(bucket_result.ok()); + BucketInfo perm_bucket2 = bucket_result.value(); + + QuotaErrorOr<std::set<BucketLocator>> result = db.GetBucketsForType(kTemp); + ASSERT_TRUE(result.ok()); + std::set<BucketLocator> buckets = result.value(); + ASSERT_EQ(2U, buckets.size()); + EXPECT_TRUE(ContainsBucket(buckets, temp_bucket1)); + EXPECT_TRUE(ContainsBucket(buckets, temp_bucket2)); + + result = db.GetBucketsForType(kPerm); + ASSERT_TRUE(result.ok()); + buckets = result.value(); + ASSERT_EQ(2U, buckets.size()); + EXPECT_TRUE(ContainsBucket(buckets, perm_bucket1)); + EXPECT_TRUE(ContainsBucket(buckets, perm_bucket2)); +} + +TEST_P(QuotaDatabaseTest, GetBucketsForHost) { + QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); + EXPECT_TRUE(EnsureOpened(&db, EnsureOpenedMode::kCreateIfNotFound)); + + QuotaErrorOr<BucketInfo> temp_example_bucket1 = db.CreateBucketForTesting( + StorageKey::CreateFromStringForTesting("https://example.com/"), "default", + kTemp); + QuotaErrorOr<BucketInfo> temp_example_bucket2 = db.CreateBucketForTesting( + StorageKey::CreateFromStringForTesting("http://example.com:123/"), + "default", kTemp); + QuotaErrorOr<BucketInfo> perm_google_bucket1 = db.CreateBucketForTesting( + StorageKey::CreateFromStringForTesting("http://google.com/"), "default", + kPerm); + QuotaErrorOr<BucketInfo> temp_google_bucket2 = db.CreateBucketForTesting( + StorageKey::CreateFromStringForTesting("http://google.com:123/"), + "default", kTemp); + + QuotaErrorOr<std::set<BucketLocator>> result = + db.GetBucketsForHost("example.com", kTemp); + ASSERT_TRUE(result.ok()); + ASSERT_EQ(result->size(), 2U); + EXPECT_TRUE(ContainsBucket(result.value(), temp_example_bucket1.value())); + EXPECT_TRUE(ContainsBucket(result.value(), temp_example_bucket2.value())); + + result = db.GetBucketsForHost("example.com", kPerm); + ASSERT_TRUE(result.ok()); + ASSERT_EQ(result->size(), 0U); + + result = db.GetBucketsForHost("google.com", kPerm); + ASSERT_TRUE(result.ok()); + ASSERT_EQ(result->size(), 1U); + EXPECT_TRUE(ContainsBucket(result.value(), perm_google_bucket1.value())); + + result = db.GetBucketsForHost("google.com", kTemp); + ASSERT_TRUE(result.ok()); + ASSERT_EQ(result->size(), 1U); + EXPECT_TRUE(ContainsBucket(result.value(), temp_google_bucket2.value())); +} + +TEST_P(QuotaDatabaseTest, GetBucketsForStorageKey) { + QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); + EXPECT_TRUE(EnsureOpened(&db, EnsureOpenedMode::kCreateIfNotFound)); + + const StorageKey storage_key1 = + StorageKey::CreateFromStringForTesting("http://example-a/"); + const StorageKey storage_key2 = + StorageKey::CreateFromStringForTesting("http://example-b/"); + + QuotaErrorOr<BucketInfo> bucket_result = + db.CreateBucketForTesting(storage_key1, "temp_test1", kTemp); + ASSERT_TRUE(bucket_result.ok()); + BucketInfo temp_bucket1 = bucket_result.value(); + + bucket_result = db.CreateBucketForTesting(storage_key1, "temp_test2", kTemp); + ASSERT_TRUE(bucket_result.ok()); + BucketInfo temp_bucket2 = bucket_result.value(); + + bucket_result = db.CreateBucketForTesting(storage_key1, "perm_test", kPerm); + ASSERT_TRUE(bucket_result.ok()); + BucketInfo perm_bucket1 = bucket_result.value(); + + bucket_result = db.CreateBucketForTesting(storage_key2, "perm_test", kPerm); + ASSERT_TRUE(bucket_result.ok()); + BucketInfo perm_bucket2 = bucket_result.value(); + + QuotaErrorOr<std::set<BucketLocator>> result = + db.GetBucketsForStorageKey(storage_key1, kTemp); + ASSERT_TRUE(result.ok()); + std::set<BucketLocator> buckets = result.value(); + ASSERT_EQ(2U, buckets.size()); + EXPECT_TRUE(ContainsBucket(buckets, temp_bucket1)); + EXPECT_TRUE(ContainsBucket(buckets, temp_bucket2)); + + result = db.GetBucketsForStorageKey(storage_key2, kPerm); + ASSERT_TRUE(result.ok()); + buckets = result.value(); + ASSERT_EQ(1U, buckets.size()); + EXPECT_TRUE(ContainsBucket(buckets, perm_bucket2)); +} + TEST_P(QuotaDatabaseTest, GetBucketWithNoDb) { QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); - EXPECT_FALSE(LazyOpen(&db, LazyOpenMode::kFailIfNotFound)); + EXPECT_FALSE(EnsureOpened(&db, EnsureOpenedMode::kFailIfNotFound)); StorageKey storage_key = StorageKey::CreateFromStringForTesting("http://google/"); @@ -306,7 +441,7 @@ TEST_F(QuotaDatabaseTest, GetBucketWithOpenDatabaseError) { TEST_P(QuotaDatabaseTest, DeleteStorageKeyInfo) { QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); - EXPECT_TRUE(LazyOpen(&db, LazyOpenMode::kCreateIfNotFound)); + EXPECT_TRUE(EnsureOpened(&db, EnsureOpenedMode::kCreateIfNotFound)); const StorageKey storage_key = StorageKey::CreateFromStringForTesting("http://example-a/"); @@ -338,9 +473,34 @@ TEST_P(QuotaDatabaseTest, DeleteStorageKeyInfo) { ASSERT_EQ(result.error(), QuotaError::kNotFound); } +TEST_P(QuotaDatabaseTest, SetStorageKeyLastModifiedTime) { + QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); + EXPECT_TRUE(EnsureOpened(&db, EnsureOpenedMode::kCreateIfNotFound)); + + const StorageKey storage_key = + StorageKey::CreateFromStringForTesting("http://example/"); + base::Time now = base::Time::Now(); + + // Should create a bucket if one doesn't exist. + EXPECT_EQ(db.SetStorageKeyLastModifiedTime(storage_key, kTemp, now), + QuotaError::kNone); + + QuotaErrorOr<BucketInfo> bucket = + db.GetBucket(storage_key, kDefaultBucketName, kTemp); + EXPECT_TRUE(bucket.ok()); + + EXPECT_EQ(db.SetStorageKeyLastModifiedTime(storage_key, kTemp, now), + QuotaError::kNone); + + QuotaDatabase::BucketTableEntry info; + EXPECT_TRUE(db.GetBucketInfo(bucket->id, &info)); + EXPECT_EQ(now, info.last_modified); + EXPECT_EQ(0, info.use_count); +} + TEST_P(QuotaDatabaseTest, BucketLastAccessTimeLRU) { QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); - EXPECT_TRUE(LazyOpen(&db, LazyOpenMode::kCreateIfNotFound)); + EXPECT_TRUE(EnsureOpened(&db, EnsureOpenedMode::kCreateIfNotFound)); std::set<BucketId> bucket_exceptions; QuotaErrorOr<BucketInfo> result = @@ -367,16 +527,20 @@ TEST_P(QuotaDatabaseTest, BucketLastAccessTimeLRU) { 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))); + EXPECT_EQ(db.SetBucketLastAccessTime(bucket1.bucket_id, + base::Time::FromJavaTime(10)), + QuotaError::kNone); + EXPECT_EQ(db.SetBucketLastAccessTime(bucket2.bucket_id, + base::Time::FromJavaTime(20)), + QuotaError::kNone); + EXPECT_EQ(db.SetBucketLastAccessTime(bucket3.bucket_id, + base::Time::FromJavaTime(30)), + QuotaError::kNone); // one persistent. - EXPECT_TRUE(db.SetBucketLastAccessTime(bucket4.bucket_id, - base::Time::FromJavaTime(40))); + EXPECT_EQ(db.SetBucketLastAccessTime(bucket4.bucket_id, + base::Time::FromJavaTime(40)), + QuotaError::kNone); result = db.GetLRUBucket(kTemp, bucket_exceptions, nullptr); EXPECT_TRUE(result.ok()); @@ -384,7 +548,7 @@ TEST_P(QuotaDatabaseTest, BucketLastAccessTimeLRU) { // Test that unlimited origins are excluded from eviction, but // protected origins are not excluded. - scoped_refptr<MockSpecialStoragePolicy> policy(new MockSpecialStoragePolicy); + auto policy = base::MakeRefCounted<MockSpecialStoragePolicy>(); policy->AddUnlimited(bucket1.storage_key.origin().GetURL()); policy->AddProtected(bucket2.storage_key.origin().GetURL()); result = db.GetLRUBucket(kTemp, bucket_exceptions, policy.get()); @@ -413,7 +577,8 @@ TEST_P(QuotaDatabaseTest, BucketLastAccessTimeLRU) { EXPECT_FALSE(result.ok()); EXPECT_EQ(result.error(), QuotaError::kNotFound); - EXPECT_TRUE(db.SetBucketLastAccessTime(bucket1.bucket_id, base::Time::Now())); + EXPECT_EQ(db.SetBucketLastAccessTime(bucket1.bucket_id, base::Time::Now()), + QuotaError::kNone); // Delete storage_key/type last access time information. EXPECT_TRUE(db.DeleteBucketInfo(bucket3.bucket_id)); @@ -431,9 +596,34 @@ TEST_P(QuotaDatabaseTest, BucketLastAccessTimeLRU) { EXPECT_EQ(result.error(), QuotaError::kNotFound); } +TEST_P(QuotaDatabaseTest, SetStorageKeyLastAccessTime) { + QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); + EXPECT_TRUE(EnsureOpened(&db, EnsureOpenedMode::kCreateIfNotFound)); + + const StorageKey storage_key = + StorageKey::CreateFromStringForTesting("http://example/"); + base::Time now = base::Time::Now(); + + // Should create a bucket if one doesn't exist. + EXPECT_EQ(db.SetStorageKeyLastAccessTime(storage_key, kTemp, now), + QuotaError::kNone); + + QuotaErrorOr<BucketInfo> bucket = + db.GetBucket(storage_key, kDefaultBucketName, kTemp); + EXPECT_TRUE(bucket.ok()); + + EXPECT_EQ(db.SetStorageKeyLastAccessTime(storage_key, kTemp, now), + QuotaError::kNone); + + QuotaDatabase::BucketTableEntry info; + EXPECT_TRUE(db.GetBucketInfo(bucket->id, &info)); + EXPECT_EQ(now, info.last_accessed); + EXPECT_EQ(2, info.use_count); +} + TEST_P(QuotaDatabaseTest, GetStorageKeysForType) { QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); - EXPECT_TRUE(LazyOpen(&db, LazyOpenMode::kCreateIfNotFound)); + EXPECT_TRUE(EnsureOpened(&db, EnsureOpenedMode::kCreateIfNotFound)); const StorageKey storage_key1 = StorageKey::CreateFromStringForTesting("http://example-a/"); @@ -442,14 +632,10 @@ TEST_P(QuotaDatabaseTest, GetStorageKeysForType) { const StorageKey storage_key3 = StorageKey::CreateFromStringForTesting("http://example-c/"); - QuotaErrorOr<BucketInfo> temp_bucket1 = - db.CreateBucketForTesting(storage_key1, "bucket_a", kTemp); - QuotaErrorOr<BucketInfo> temp_bucket2 = - db.CreateBucketForTesting(storage_key2, "bucket_b", kTemp); - QuotaErrorOr<BucketInfo> perm_bucket1 = - db.CreateBucketForTesting(storage_key2, "bucket_b", kPerm); - QuotaErrorOr<BucketInfo> perm_bucket2 = - db.CreateBucketForTesting(storage_key3, "bucket_b", kPerm); + db.CreateBucketForTesting(storage_key1, "bucket_a", kTemp); + db.CreateBucketForTesting(storage_key2, "bucket_b", kTemp); + db.CreateBucketForTesting(storage_key2, "bucket_b", kPerm); + db.CreateBucketForTesting(storage_key3, "bucket_c", kPerm); QuotaErrorOr<std::set<StorageKey>> result = db.GetStorageKeysForType(kTemp); ASSERT_TRUE(result.ok()); @@ -466,7 +652,7 @@ TEST_P(QuotaDatabaseTest, GetStorageKeysForType) { TEST_P(QuotaDatabaseTest, BucketLastModifiedBetween) { QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); - EXPECT_TRUE(LazyOpen(&db, LazyOpenMode::kCreateIfNotFound)); + EXPECT_TRUE(EnsureOpened(&db, EnsureOpenedMode::kCreateIfNotFound)); QuotaErrorOr<std::set<BucketInfo>> result = db.GetBucketsModifiedBetween(kTemp, base::Time(), base::Time::Max()); @@ -496,14 +682,18 @@ TEST_P(QuotaDatabaseTest, BucketLastModifiedBetween) { BucketInfo bucket4 = result4.value(); // Report last modified time for the buckets. - EXPECT_TRUE( - db.SetBucketLastModifiedTime(bucket1.id, base::Time::FromJavaTime(0))); - EXPECT_TRUE( - db.SetBucketLastModifiedTime(bucket2.id, base::Time::FromJavaTime(10))); - EXPECT_TRUE( - db.SetBucketLastModifiedTime(bucket3.id, base::Time::FromJavaTime(20))); - EXPECT_TRUE( - db.SetBucketLastModifiedTime(bucket4.id, base::Time::FromJavaTime(30))); + EXPECT_EQ( + db.SetBucketLastModifiedTime(bucket1.id, base::Time::FromJavaTime(0)), + QuotaError::kNone); + EXPECT_EQ( + db.SetBucketLastModifiedTime(bucket2.id, base::Time::FromJavaTime(10)), + QuotaError::kNone); + EXPECT_EQ( + db.SetBucketLastModifiedTime(bucket3.id, base::Time::FromJavaTime(20)), + QuotaError::kNone); + EXPECT_EQ( + db.SetBucketLastModifiedTime(bucket4.id, base::Time::FromJavaTime(30)), + QuotaError::kNone); result = db.GetBucketsModifiedBetween(kTemp, base::Time(), base::Time::Max()); EXPECT_TRUE(result.ok()); @@ -582,25 +772,28 @@ TEST_P(QuotaDatabaseTest, RegisterInitialStorageKeyInfo) { EXPECT_TRUE(db.RegisterInitialStorageKeyInfo(storage_keys, kTemp)); + QuotaErrorOr<BucketInfo> bucket_result = + db.GetBucket(StorageKey::CreateFromStringForTesting("http://a/"), + kDefaultBucketName, kTemp); + ASSERT_TRUE(bucket_result.ok()); + QuotaDatabase::BucketTableEntry info; info.use_count = -1; - EXPECT_TRUE(db.GetStorageKeyInfo( - StorageKey::CreateFromStringForTesting("http://a/"), kTemp, &info)); + EXPECT_TRUE(db.GetBucketInfo(bucket_result->id, &info)); EXPECT_EQ(0, info.use_count); - EXPECT_TRUE(db.SetStorageKeyLastAccessTime( - StorageKey::CreateFromStringForTesting("http://a/"), kTemp, - base::Time::FromDoubleT(1.0))); + EXPECT_EQ(db.SetStorageKeyLastAccessTime( + StorageKey::CreateFromStringForTesting("http://a/"), kTemp, + base::Time::FromDoubleT(1.0)), + QuotaError::kNone); info.use_count = -1; - EXPECT_TRUE(db.GetStorageKeyInfo( - StorageKey::CreateFromStringForTesting("http://a/"), kTemp, &info)); + EXPECT_TRUE(db.GetBucketInfo(bucket_result->id, &info)); EXPECT_EQ(1, info.use_count); EXPECT_TRUE(db.RegisterInitialStorageKeyInfo(storage_keys, kTemp)); info.use_count = -1; - EXPECT_TRUE(db.GetStorageKeyInfo( - StorageKey::CreateFromStringForTesting("http://a/"), kTemp, &info)); + EXPECT_TRUE(db.GetBucketInfo(bucket_result->id, &info)); EXPECT_EQ(1, info.use_count); } @@ -611,7 +804,7 @@ TEST_P(QuotaDatabaseTest, DumpQuotaTable) { {.host = "http://gle/", .type = kPerm, .quota = 3}}; QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); - EXPECT_TRUE(LazyOpen(&db, LazyOpenMode::kCreateIfNotFound)); + EXPECT_TRUE(EnsureOpened(&db, EnsureOpenedMode::kCreateIfNotFound)); AssignQuotaTable(&db, kTableEntries); using Verifier = EntryVerifier<QuotaTableEntry>; @@ -634,7 +827,7 @@ TEST_P(QuotaDatabaseTest, DumpBucketTable) { }; QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); - EXPECT_TRUE(LazyOpen(&db, LazyOpenMode::kCreateIfNotFound)); + EXPECT_TRUE(EnsureOpened(&db, EnsureOpenedMode::kCreateIfNotFound)); AssignBucketTable(&db, kTableEntries); using Verifier = EntryVerifier<Entry>; @@ -644,37 +837,6 @@ TEST_P(QuotaDatabaseTest, DumpBucketTable) { EXPECT_TRUE(verifier.table.empty()); } -TEST_P(QuotaDatabaseTest, GetStorageKeyInfo) { - const StorageKey kStorageKey = - StorageKey::CreateFromStringForTesting("http://go/"); - using Entry = QuotaDatabase::BucketTableEntry; - Entry kTableEntries[] = {Entry(BucketId(1), kStorageKey, kTemp, - kDefaultBucketName, 100, base::Time(), - base::Time())}; - - QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); - EXPECT_TRUE(LazyOpen(&db, LazyOpenMode::kCreateIfNotFound)); - AssignBucketTable(&db, kTableEntries); - - { - Entry entry; - EXPECT_TRUE(db.GetStorageKeyInfo(kStorageKey, kTemp, &entry)); - EXPECT_EQ(kTableEntries[0].type, entry.type); - EXPECT_EQ(kTableEntries[0].storage_key, entry.storage_key); - 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.GetStorageKeyInfo( - StorageKey::CreateFromStringForTesting("http://notpresent.org/"), kTemp, - &entry)); - } -} - TEST_P(QuotaDatabaseTest, GetBucketInfo) { using Entry = QuotaDatabase::BucketTableEntry; Entry kTableEntries[] = { @@ -682,7 +844,7 @@ TEST_P(QuotaDatabaseTest, GetBucketInfo) { kTemp, "test_bucket", 100, base::Time(), base::Time())}; QuotaDatabase db(use_in_memory_db() ? base::FilePath() : DbPath()); - EXPECT_TRUE(LazyOpen(&db, LazyOpenMode::kCreateIfNotFound)); + EXPECT_TRUE(EnsureOpened(&db, EnsureOpenedMode::kCreateIfNotFound)); AssignBucketTable(&db, kTableEntries); { @@ -720,7 +882,7 @@ TEST_F(QuotaDatabaseTest, OpenCorruptedDatabase) { // Create database, force corruption and close db by leaving scope. { QuotaDatabase db(DbPath()); - ASSERT_TRUE(LazyOpen(&db, LazyOpenMode::kCreateIfNotFound)); + ASSERT_TRUE(EnsureOpened(&db, EnsureOpenedMode::kCreateIfNotFound)); ASSERT_TRUE(sql::test::CorruptSizeInHeader(DbPath())); } // Reopen database and verify schema reset on reopen. @@ -728,7 +890,7 @@ TEST_F(QuotaDatabaseTest, OpenCorruptedDatabase) { sql::test::ScopedErrorExpecter expecter; expecter.ExpectError(SQLITE_CORRUPT); QuotaDatabase db(DbPath()); - ASSERT_TRUE(LazyOpen(&db, LazyOpenMode::kFailIfNotFound)); + ASSERT_TRUE(EnsureOpened(&db, EnsureOpenedMode::kFailIfNotFound)); EXPECT_TRUE(expecter.SawExpectedErrors()); } diff --git a/chromium/storage/browser/quota/quota_device_info_helper.h b/chromium/storage/browser/quota/quota_device_info_helper.h index c55220f790c..bedb8344133 100644 --- a/chromium/storage/browser/quota/quota_device_info_helper.h +++ b/chromium/storage/browser/quota/quota_device_info_helper.h @@ -18,14 +18,15 @@ namespace storage { class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaDeviceInfoHelper { public: QuotaDeviceInfoHelper() = default; + + QuotaDeviceInfoHelper(const QuotaDeviceInfoHelper&) = delete; + QuotaDeviceInfoHelper& operator=(const QuotaDeviceInfoHelper&) = delete; + virtual ~QuotaDeviceInfoHelper(); virtual int64_t AmountOfTotalDiskSpace(const base::FilePath& path) const; virtual int64_t AmountOfPhysicalMemory() const; - - private: - DISALLOW_COPY_AND_ASSIGN(QuotaDeviceInfoHelper); }; // class QuotaDeviceInfoHelper } // namespace storage diff --git a/chromium/storage/browser/quota/quota_features.cc b/chromium/storage/browser/quota/quota_features.cc index cfb874fbd0f..04985ab9fc0 100644 --- a/chromium/storage/browser/quota/quota_features.cc +++ b/chromium/storage/browser/quota/quota_features.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "storage/browser/quota/quota_features.h" +#include "base/feature_list.h" namespace storage { diff --git a/chromium/storage/browser/quota/quota_manager_impl.cc b/chromium/storage/browser/quota/quota_manager_impl.cc index 3ae98700cdb..3cd39138b22 100644 --- a/chromium/storage/browser/quota/quota_manager_impl.cc +++ b/chromium/storage/browser/quota/quota_manager_impl.cc @@ -38,6 +38,7 @@ #include "base/time/time.h" #include "base/trace_event/trace_event.h" #include "base/types/pass_key.h" +#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "components/services/storage/public/mojom/quota_client.mojom.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "storage/browser/quota/client_usage_tracker.h" @@ -68,7 +69,7 @@ constexpr double kStoragePressureThresholdRatio = 0.02; // Limit how frequently QuotaManagerImpl polls for free disk space when // only using that information to identify storage pressure. constexpr base::TimeDelta kStoragePressureCheckDiskStatsInterval = - base::TimeDelta::FromMinutes(5); + base::Minutes(5); // Modifies a given value by a uniformly random amount from // -percent to +percent. @@ -127,6 +128,29 @@ QuotaErrorOr<std::set<StorageKey>> GetStorageKeysForTypeOnDBThread( return database->GetStorageKeysForType(type); } +QuotaErrorOr<std::set<BucketLocator>> GetBucketsForTypeOnDBThread( + StorageType type, + QuotaDatabase* database) { + DCHECK(database); + return database->GetBucketsForType(type); +} + +QuotaErrorOr<std::set<BucketLocator>> GetBucketsForHostOnDBThread( + const std::string& host, + StorageType type, + QuotaDatabase* database) { + DCHECK(database); + return database->GetBucketsForHost(host, type); +} + +QuotaErrorOr<std::set<BucketLocator>> GetBucketsForStorageKeyOnDBThread( + const StorageKey& storage_key, + StorageType type, + QuotaDatabase* database) { + DCHECK(database); + return database->GetBucketsForStorageKey(storage_key, type); +} + QuotaErrorOr<std::set<BucketInfo>> GetModifiedBetweenOnDBThread( StorageType type, base::Time begin, @@ -210,15 +234,18 @@ bool UpdateAccessTimeOnDBThread(const StorageKey& storage_key, base::Time accessed_time, QuotaDatabase* database) { DCHECK(database); - return database->SetStorageKeyLastAccessTime(storage_key, type, - accessed_time); + QuotaError result = + database->SetStorageKeyLastAccessTime(storage_key, type, accessed_time); + return result != QuotaError::kDatabaseError; } bool UpdateBucketAccessTimeOnDBThread(const BucketId bucket_id, base::Time accessed_time, QuotaDatabase* database) { DCHECK(database); - return database->SetBucketLastAccessTime(bucket_id, accessed_time); + QuotaError result = + database->SetBucketLastAccessTime(bucket_id, accessed_time); + return result != QuotaError::kDatabaseError; } bool UpdateModifiedTimeOnDBThread(const StorageKey& storage_key, @@ -226,15 +253,18 @@ bool UpdateModifiedTimeOnDBThread(const StorageKey& storage_key, base::Time modified_time, QuotaDatabase* database) { DCHECK(database); - return database->SetStorageKeyLastModifiedTime(storage_key, type, - modified_time); + QuotaError result = + database->SetStorageKeyLastModifiedTime(storage_key, type, modified_time); + return result != QuotaError::kDatabaseError; } bool UpdateBucketModifiedTimeOnDBThread(const BucketId bucket_id, base::Time modified_time, QuotaDatabase* database) { DCHECK(database); - return database->SetBucketLastModifiedTime(bucket_id, modified_time); + QuotaError result = + database->SetBucketLastModifiedTime(bucket_id, modified_time); + return result != QuotaError::kDatabaseError; } void DidGetUsageAndQuotaStripBreakdown( @@ -443,46 +473,54 @@ class QuotaManagerImpl::UsageAndQuotaInfoGatherer : public QuotaTask { base::WeakPtrFactory<UsageAndQuotaInfoGatherer> weak_factory_{this}; }; -class QuotaManagerImpl::EvictionRoundInfoHelper : public QuotaTask { +class QuotaManagerImpl::EvictionRoundInfoHelper { public: + // `callback` is called when the helper successfully retrieves quota settings + // and capacity data. `completion_closure` is called after data has been + // retrieved and `callback` has been run and to clean up itself and delete + // this EvictionRoundInfoHelper instance. EvictionRoundInfoHelper(QuotaManagerImpl* manager, - EvictionRoundInfoCallback callback) - : QuotaTask(manager), callback_(std::move(callback)) {} + EvictionRoundInfoCallback callback, + base::OnceClosure completion_closure) + : manager_(manager), + callback_(std::move(callback)), + completion_closure_(std::move(completion_closure)) { + DCHECK(manager_); + DCHECK(callback_); + DCHECK(completion_closure_); + } + + void Run() { +#if DCHECK_IS_ON() + DCHECK(!run_called_) << __func__ << " already called"; + run_called_ = true; +#endif // DCHECK_IS_ON() - protected: - void Run() override { // Gather 2 pieces of info before deciding if we need to get GlobalUsage: // settings and device_storage_capacity. base::RepeatingClosure barrier = base::BarrierClosure( 2, base::BindOnce(&EvictionRoundInfoHelper::OnBarrierComplete, weak_factory_.GetWeakPtr())); - manager()->GetQuotaSettings( + manager_->GetQuotaSettings( base::BindOnce(&EvictionRoundInfoHelper::OnGotSettings, weak_factory_.GetWeakPtr(), barrier)); - manager()->GetStorageCapacity( + manager_->GetStorageCapacity( base::BindOnce(&EvictionRoundInfoHelper::OnGotCapacity, weak_factory_.GetWeakPtr(), barrier)); } - void Aborted() override { - weak_factory_.InvalidateWeakPtrs(); - std::move(callback_).Run(blink::mojom::QuotaStatusCode::kErrorAbort, - QuotaSettings(), 0, 0, 0, false); - DeleteSoon(); - } - - void Completed() override { - weak_factory_.InvalidateWeakPtrs(); + private: + void Completed() { +#if DCHECK_IS_ON() + DCHECK(!completed_called_) << __func__ << " already called"; + completed_called_ = true; +#endif // DCHECK_IS_ON() std::move(callback_).Run(blink::mojom::QuotaStatusCode::kOk, settings_, available_space_, total_space_, global_usage_, global_usage_is_complete_); - DeleteSoon(); - } - - private: - QuotaManagerImpl* manager() const { - return static_cast<QuotaManagerImpl*>(observer()); + // May delete `this`. + std::move(completion_closure_).Run(); } void OnGotSettings(base::OnceClosure barrier_closure, @@ -506,28 +544,38 @@ class QuotaManagerImpl::EvictionRoundInfoHelper : public QuotaTask { available_space_ > settings_.should_remain_available) { DCHECK(!global_usage_is_complete_); global_usage_ = - manager()->GetUsageTracker(StorageType::kTemporary)->GetCachedUsage(); - CallCompleted(); + manager_->GetUsageTracker(StorageType::kTemporary)->GetCachedUsage(); + // `this` may be deleted during this Complete() call. + Completed(); return; } - manager()->GetGlobalUsage( + manager_->GetGlobalUsage( StorageType::kTemporary, base::BindOnce(&EvictionRoundInfoHelper::OnGotGlobalUsage, weak_factory_.GetWeakPtr())); } void OnGotGlobalUsage(int64_t usage, int64_t unlimited_usage) { - global_usage_ = std::max(INT64_C(0), usage - unlimited_usage); + global_usage_ = std::max(int64_t{0}, usage - unlimited_usage); global_usage_is_complete_ = true; - CallCompleted(); + // `this` may be deleted during this Complete() call. + Completed(); } + QuotaManagerImpl* const manager_; EvictionRoundInfoCallback callback_; + base::OnceClosure completion_closure_; QuotaSettings settings_; int64_t available_space_ = 0; int64_t total_space_ = 0; int64_t global_usage_ = 0; bool global_usage_is_complete_ = false; + +#if DCHECK_IS_ON() + bool run_called_ = false; + bool completed_called_ = false; +#endif // DCHECK_IS_ON() + base::WeakPtrFactory<EvictionRoundInfoHelper> weak_factory_{this}; }; @@ -562,11 +610,6 @@ class QuotaManagerImpl::GetUsageInfoTask : public QuotaTask { DeleteSoon(); } - void Aborted() override { - std::move(callback_).Run(UsageInfoEntries()); - DeleteSoon(); - } - private: void AddEntries(StorageType type, UsageTracker* tracker) { std::map<std::string, int64_t> host_usage = tracker->GetCachedHostsUsage(); @@ -593,6 +636,11 @@ class QuotaManagerImpl::GetUsageInfoTask : public QuotaTask { base::WeakPtrFactory<GetUsageInfoTask> weak_factory_{this}; }; +// Calls each QuotaClient for `quota_client_types` to delete `storage_key` data. +// If `storage_key` is delete for all registered client types, and there are no +// deletion errors, StorageKeyDataDeleter will call to delete `storage_key` from +// QuotaDatabase. It will return QuotaStatusCode::kOk to the `callback` on +// success and will finish by making a call to delete itself. class QuotaManagerImpl::StorageKeyDataDeleter : public QuotaTask { public: StorageKeyDataDeleter(QuotaManagerImpl* manager, @@ -604,9 +652,6 @@ class QuotaManagerImpl::StorageKeyDataDeleter : public QuotaTask { storage_key_(storage_key), type_(type), quota_client_types_(std::move(quota_client_types)), - error_count_(0), - remaining_clients_(0), - skipped_clients_(0), callback_(std::move(callback)) {} protected: @@ -676,9 +721,9 @@ class QuotaManagerImpl::StorageKeyDataDeleter : public QuotaTask { const StorageKey storage_key_; const StorageType type_; const QuotaClientTypes quota_client_types_; - int error_count_; - size_t remaining_clients_; - int skipped_clients_; + int error_count_ = 0; + size_t remaining_clients_ = 0; + int skipped_clients_ = 0; StatusCallback callback_; base::WeakPtrFactory<StorageKeyDataDeleter> weak_factory_{this}; @@ -1030,8 +1075,6 @@ QuotaManagerImpl::QuotaManagerImpl( is_incognito_(is_incognito), profile_path_(profile_path), proxy_(base::MakeRefCounted<QuotaManagerProxy>(this, io_thread)), - db_disabled_(false), - eviction_disabled_(false), io_thread_(std::move(io_thread)), db_runner_(base::ThreadPool::CreateSequencedTaskRunner( {base::MayBlock(), base::TaskPriority::USER_VISIBLE, @@ -1110,6 +1153,44 @@ void QuotaManagerImpl::GetStorageKeysForType(blink::mojom::StorageType type, weak_factory_.GetWeakPtr(), std::move(callback))); } +void QuotaManagerImpl::GetBucketsForType( + blink::mojom::StorageType type, + base::OnceCallback<void(QuotaErrorOr<std::set<BucketLocator>>)> callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + EnsureDatabaseOpened(); + + PostTaskAndReplyWithResultForDBThread( + base::BindOnce(&GetBucketsForTypeOnDBThread, type), + base::BindOnce(&QuotaManagerImpl::DidGetBuckets, + weak_factory_.GetWeakPtr(), std::move(callback))); +} + +void QuotaManagerImpl::GetBucketsForHost( + const std::string& host, + blink::mojom::StorageType type, + base::OnceCallback<void(QuotaErrorOr<std::set<BucketLocator>>)> callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + EnsureDatabaseOpened(); + + PostTaskAndReplyWithResultForDBThread( + base::BindOnce(&GetBucketsForHostOnDBThread, host, type), + base::BindOnce(&QuotaManagerImpl::DidGetBuckets, + weak_factory_.GetWeakPtr(), std::move(callback))); +} + +void QuotaManagerImpl::GetBucketsForStorageKey( + const StorageKey& storage_key, + blink::mojom::StorageType type, + base::OnceCallback<void(QuotaErrorOr<std::set<BucketLocator>>)> callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + EnsureDatabaseOpened(); + + PostTaskAndReplyWithResultForDBThread( + base::BindOnce(&GetBucketsForStorageKeyOnDBThread, storage_key, type), + base::BindOnce(&QuotaManagerImpl::DidGetBuckets, + weak_factory_.GetWeakPtr(), std::move(callback))); +} + void QuotaManagerImpl::GetUsageInfo(GetUsageInfoCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); EnsureDatabaseOpened(); @@ -1236,15 +1317,6 @@ void QuotaManagerImpl::SetUsageCacheEnabled(QuotaClientType client_id, GetUsageTracker(type)->SetUsageCacheEnabled(client_id, storage_key, enabled); } -void QuotaManagerImpl::DeleteStorageKeyData(const StorageKey& storage_key, - StorageType type, - QuotaClientTypes quota_client_types, - StatusCallback callback) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DeleteStorageKeyDataInternal(storage_key, type, std::move(quota_client_types), - std::move(callback)); -} - void QuotaManagerImpl::DeleteBucketData(const BucketInfo& bucket, QuotaClientTypes quota_client_types, StatusCallback callback) { @@ -1253,6 +1325,19 @@ void QuotaManagerImpl::DeleteBucketData(const BucketInfo& bucket, std::move(callback)); } +void QuotaManagerImpl::FindAndDeleteBucketData(const StorageKey& storage_key, + const std::string& bucket_name, + StatusCallback callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + EnsureDatabaseOpened(); + + PostTaskAndReplyWithResultForDBThread( + base::BindOnce(&GetBucketOnDBThread, storage_key, bucket_name, + StorageType::kTemporary), + base::BindOnce(&QuotaManagerImpl::DidGetBucketForDeletion, + weak_factory_.GetWeakPtr(), std::move(callback))); +} + void QuotaManagerImpl::PerformStorageCleanup( StorageType type, QuotaClientTypes quota_client_types, @@ -1458,9 +1543,9 @@ void QuotaManagerImpl::EnsureDatabaseOpened() { special_storage_policy_.get()); if (!is_incognito_) { - histogram_timer_.Start( - FROM_HERE, base::TimeDelta::FromMilliseconds(kReportHistogramInterval), - this, &QuotaManagerImpl::ReportHistogram); + histogram_timer_.Start(FROM_HERE, + base::Milliseconds(kReportHistogramInterval), this, + &QuotaManagerImpl::ReportHistogram); } base::PostTaskAndReplyWithResult( @@ -1724,20 +1809,6 @@ void QuotaManagerImpl::DeleteBucketDataInternal( deleter->Start(); } -void QuotaManagerImpl::DeleteStorageKeyDataInternal( - const StorageKey& storage_key, - StorageType type, - QuotaClientTypes quota_client_types, - StatusCallback callback) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - EnsureDatabaseOpened(); - - StorageKeyDataDeleter* deleter = new StorageKeyDataDeleter( - this, storage_key, type, std::move(quota_client_types), - std::move(callback)); - deleter->Start(); -} - void QuotaManagerImpl::MaybeRunStoragePressureCallback( const StorageKey& storage_key, int64_t total_space, @@ -1918,7 +1989,7 @@ void QuotaManagerImpl::DidDumpBucketTableForHistogram( 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)); + int64_t kilobytes = std::max(it->second / int64_t{1024}, int64_t{1}); base::Histogram::FactoryGet( "Quota.AgeOfDataInDays", 1, 1000, 50, base::HistogramBase::kUmaTargetedHistogramFlag)-> @@ -2010,9 +2081,18 @@ void QuotaManagerImpl::GetEvictionRoundInfo( DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(io_thread_->BelongsToCurrentThread()); EnsureDatabaseOpened(); - EvictionRoundInfoHelper* helper = - new EvictionRoundInfoHelper(this, std::move(callback)); - helper->Start(); + + DCHECK(!eviction_helper_); + eviction_helper_ = std::make_unique<EvictionRoundInfoHelper>( + this, std::move(callback), + base::BindOnce(&QuotaManagerImpl::DidGetEvictionRoundInfo, + weak_factory_.GetWeakPtr())); + eviction_helper_->Run(); +} + +void QuotaManagerImpl::DidGetEvictionRoundInfo() { + DCHECK(eviction_helper_); + eviction_helper_.reset(); } void QuotaManagerImpl::GetLRUBucket(StorageType type, @@ -2105,7 +2185,7 @@ void QuotaManagerImpl::DidGetSettings(absl::optional<QuotaSettings> settings) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!settings) { settings = settings_; - settings->refresh_interval = base::TimeDelta::FromMinutes(1); + settings->refresh_interval = base::Minutes(1); } SetQuotaSettings(*settings); settings_callbacks_.Run(*settings); @@ -2139,7 +2219,7 @@ void QuotaManagerImpl::ContinueIncognitoGetStorageCapacity( GetUsageTracker(StorageType::kTemporary)->GetCachedUsage(); current_usage += GetUsageTracker(StorageType::kPersistent)->GetCachedUsage(); int64_t available_space = - std::max(INT64_C(0), settings.pool_size - current_usage); + std::max(int64_t{0}, settings.pool_size - current_usage); DidGetStorageCapacity(std::make_tuple(settings.pool_size, available_space)); } @@ -2167,6 +2247,25 @@ void QuotaManagerImpl::DidGetBucket( std::move(callback).Run(std::move(result)); } +void QuotaManagerImpl::DidGetBucketForDeletion( + StatusCallback callback, + QuotaErrorOr<BucketInfo> result) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DidDatabaseWork(result.ok() || result.error() != QuotaError::kDatabaseError); + + if (!result.ok()) { + // Return QuotaStatusCode::kOk if bucket not found. No work needed. + std::move(callback).Run(result.error() == QuotaError::kNotFound + ? blink::mojom::QuotaStatusCode::kOk + : blink::mojom::QuotaStatusCode::kUnknown); + return; + } + + DeleteBucketDataInternal(result.value(), AllQuotaClientTypes(), + /*is_eviction=*/false, std::move(callback)); + return; +} + void QuotaManagerImpl::DidGetStorageKeys( GetStorageKeysCallback callback, QuotaErrorOr<std::set<StorageKey>> result) { @@ -2179,6 +2278,14 @@ void QuotaManagerImpl::DidGetStorageKeys( std::move(callback).Run(std::move(result.value())); } +void QuotaManagerImpl::DidGetBuckets( + base::OnceCallback<void(QuotaErrorOr<std::set<BucketLocator>>)> callback, + QuotaErrorOr<std::set<BucketLocator>> result) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DidDatabaseWork(result.ok() || result.error() != QuotaError::kDatabaseError); + std::move(callback).Run(std::move(result)); +} + void QuotaManagerImpl::DidGetModifiedBetween( GetBucketsCallback callback, StorageType type, diff --git a/chromium/storage/browser/quota/quota_manager_impl.h b/chromium/storage/browser/quota/quota_manager_impl.h index 2dfaf62a7f4..eab17be27bc 100644 --- a/chromium/storage/browser/quota/quota_manager_impl.h +++ b/chromium/storage/browser/quota/quota_manager_impl.h @@ -28,6 +28,7 @@ #include "base/time/time.h" #include "base/timer/timer.h" #include "components/services/storage/public/cpp/buckets/bucket_info.h" +#include "components/services/storage/public/cpp/buckets/bucket_locator.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" @@ -174,9 +175,11 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl // kTemporary and returns the BucketInfo. If one doesn't exist, it creates // a new bucket with the specified policies. Returns a QuotaError if the // operation has failed. - void GetOrCreateBucket(const blink::StorageKey& storage_key, - const std::string& bucket_name, - base::OnceCallback<void(QuotaErrorOr<BucketInfo>)>); + // This method is declared as virtual to allow test code to override it. + virtual void GetOrCreateBucket( + const blink::StorageKey& storage_key, + const std::string& bucket_name, + base::OnceCallback<void(QuotaErrorOr<BucketInfo>)>); // Creates a bucket for `origin` with `bucket_name` and returns BucketInfo // to the callback. Will return a QuotaError to the callback on operation @@ -193,16 +196,37 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl // Retrieves the BucketInfo of the bucket with `bucket_name` for `storage_key` // and returns it to the callback. Will return a QuotaError if the bucket does // not exist or on operation failure. - void GetBucket(const blink::StorageKey& storage_key, - const std::string& bucket_name, - blink::mojom::StorageType type, - base::OnceCallback<void(QuotaErrorOr<BucketInfo>)>); + // This method is declared as virtual to allow test code to override it. + virtual void GetBucket(const blink::StorageKey& storage_key, + const std::string& bucket_name, + blink::mojom::StorageType type, + base::OnceCallback<void(QuotaErrorOr<BucketInfo>)>); - // Retrieves all storage keys for `type` that are in the bucket database. + // Retrieves all storage keys for `type` that are in the buckets table. // Used for listing storage keys when showing storage key quota usage. void GetStorageKeysForType(blink::mojom::StorageType type, GetStorageKeysCallback callback); + // Retrieves all buckets for `type` that are in the buckets table. + // Used for retrieving global usage data in the UsageTracker. + void GetBucketsForType( + blink::mojom::StorageType type, + base::OnceCallback<void(QuotaErrorOr<std::set<BucketLocator>>)> callback); + + // Retrieves all buckets for `host` and `type` that are in the buckets table. + // Used for retrieving host usage data in the UsageTracker. + void GetBucketsForHost( + const std::string& host, + blink::mojom::StorageType type, + base::OnceCallback<void(QuotaErrorOr<std::set<BucketLocator>>)> callback); + + // Retrieves all buckets for `storage_key` and `type` that are in the buckets + // table. Used for retrieving storage key usage data in the UsageTracker. + void GetBucketsForStorageKey( + const blink::StorageKey& storage_key, + blink::mojom::StorageType type, + base::OnceCallback<void(QuotaErrorOr<std::set<BucketLocator>>)> callback); + // Called by clients or webapps. Returns usage per host. void GetUsageInfo(GetUsageInfoCallback callback); @@ -287,17 +311,13 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl blink::mojom::StorageType type, bool enabled); - // DeleteStorageKeyData and DeleteHostData (surprisingly enough) delete data - // of a particular blink::mojom::StorageType associated with either a specific - // storage key or set of storage keys. DeleteBucketData will delete only the - // specified bucket. Each method additionally requires a |quota_client_types| - // which specifies the types of QuotaClients to delete from the storage key. + // DeleteHostData (surprisingly enough) deletes data of a particular + // blink::mojom::StorageType associated with a set of storage keys. + // DeleteBucketData will only delete the specified bucket. + // Each method additionally requires a `quota_client_types` which specifies + // the types of QuotaClients to delete from the storage key. // Pass in QuotaClientType::AllClients() to remove all clients from the // storage key, regardless of type. - virtual void DeleteStorageKeyData(const blink::StorageKey& storage_key, - blink::mojom::StorageType type, - QuotaClientTypes quota_client_types, - StatusCallback callback); virtual void DeleteBucketData(const BucketInfo& bucket, QuotaClientTypes quota_client_types, StatusCallback callback); @@ -306,6 +326,15 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl QuotaClientTypes quota_client_types, StatusCallback callback); + // Queries QuotaDatabase for the bucket with `storage_key` and `bucket_name` + // for StorageType::kTemporary and deletes bucket data for all clients for the + // bucket. Used by the Storage Bucket API for bucket deletion. If no bucket is + // found, it will return QuotaStatusCode::kOk since it has no bucket data to + // delete. + void FindAndDeleteBucketData(const blink::StorageKey& storage_key, + const std::string& bucket_name, + StatusCallback callback); + // Instructs each QuotaClient to remove possible traces of deleted // data on the disk. void PerformStorageCleanup(blink::mojom::StorageType type, @@ -375,12 +404,14 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl // the quota for syncable storage. (http://crbug.com/155488) static int64_t kSyncableStorageDefaultHostQuota; - void DisableDatabaseForTesting() { db_disabled_ = true; } - void SetGetVolumeInfoFnForTesting(GetVolumeInfoFn fn) { get_volume_info_fn_ = fn; } + void SetEvictionDisabledForTesting(bool disable) { + eviction_disabled_ = disable; + } + protected: ~QuotaManagerImpl() override; void SetQuotaChangeCallbackForTesting( @@ -479,14 +510,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl bool is_eviction, StatusCallback callback); - // Runs StorageKeyDataDeleter which calls QuotaClients to clear all data for - // the storage key. Once the task is complete, calls the QuotaDatabase to - // delete buckets for the storage key & storage type from the bucket table. - void DeleteStorageKeyDataInternal(const blink::StorageKey& storage_key, - blink::mojom::StorageType type, - QuotaClientTypes quota_client_types, - StatusCallback callback); - // Methods for eviction logic. void StartEviction(); void DeleteStorageKeyFromDatabase(const blink::StorageKey& storage_key, @@ -519,6 +542,8 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl StatusCallback callback) override; void GetEvictionRoundInfo(EvictionRoundInfoCallback callback) override; + void DidGetEvictionRoundInfo(); + void GetLRUBucket(blink::mojom::StorageType type, GetBucketCallback callback); void DidGetPersistentHostQuota(const std::string& host, @@ -540,8 +565,13 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl void DidGetBucket(base::OnceCallback<void(QuotaErrorOr<BucketInfo>)> callback, QuotaErrorOr<BucketInfo> result); + void DidGetBucketForDeletion(StatusCallback callback, + QuotaErrorOr<BucketInfo> result); void DidGetStorageKeys(GetStorageKeysCallback callback, QuotaErrorOr<std::set<blink::StorageKey>> result); + void DidGetBuckets( + base::OnceCallback<void(QuotaErrorOr<std::set<BucketLocator>>)> callback, + QuotaErrorOr<std::set<BucketLocator>> result); void DidGetModifiedBetween(GetBucketsCallback callback, blink::mojom::StorageType type, QuotaErrorOr<std::set<BucketInfo>> result); @@ -583,6 +613,8 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl const base::FilePath& path); static std::tuple<int64_t, int64_t> GetVolumeInfo(const base::FilePath& path); + bool is_db_disabled_for_testing() { return db_disabled_; } + const bool is_incognito_; const base::FilePath profile_path_; @@ -590,8 +622,8 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl // points to never changes), and the underlying object is thread-safe. const scoped_refptr<QuotaManagerProxy> proxy_; - bool db_disabled_; - bool eviction_disabled_; + bool db_disabled_ = false; + bool eviction_disabled_ = false; absl::optional<blink::StorageKey> storage_key_for_pending_storage_pressure_callback_; scoped_refptr<base::SingleThreadTaskRunner> io_thread_; @@ -671,6 +703,8 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl // QuotaManagerImpl::GetVolumeInfo. GetVolumeInfoFn get_volume_info_fn_; + std::unique_ptr<EvictionRoundInfoHelper> eviction_helper_; + SEQUENCE_CHECKER(sequence_checker_); base::WeakPtrFactory<QuotaManagerImpl> weak_factory_{this}; diff --git a/chromium/storage/browser/quota/quota_manager_proxy.cc b/chromium/storage/browser/quota/quota_manager_proxy.cc index 9e7d0886a35..5440c615199 100644 --- a/chromium/storage/browser/quota/quota_manager_proxy.cc +++ b/chromium/storage/browser/quota/quota_manager_proxy.cc @@ -43,6 +43,18 @@ void DidGetBucket(scoped_refptr<base::SequencedTaskRunner> callback_task_runner, FROM_HERE, base::BindOnce(std::move(callback), std::move(result))); } +void DidGetStatus( + scoped_refptr<base::SequencedTaskRunner> callback_task_runner, + base::OnceCallback<void(blink::mojom::QuotaStatusCode)> callback, + blink::mojom::QuotaStatusCode status) { + if (callback_task_runner->RunsTasksInCurrentSequence()) { + std::move(callback).Run(std::move(status)); + return; + } + callback_task_runner->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), std::move(status))); +} + } // namespace QuotaManagerProxy::QuotaManagerProxy( @@ -158,6 +170,33 @@ void QuotaManagerProxy::GetBucket( std::move(callback))); } +void QuotaManagerProxy::DeleteBucket( + const StorageKey& storage_key, + const std::string& bucket_name, + scoped_refptr<base::SequencedTaskRunner> callback_task_runner, + base::OnceCallback<void(blink::mojom::QuotaStatusCode)> callback) { + if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) { + quota_manager_impl_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&QuotaManagerProxy::DeleteBucket, this, storage_key, + 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_) { + DidGetStatus(std::move(callback_task_runner), std::move(callback), + blink::mojom::QuotaStatusCode::kUnknown); + return; + } + + quota_manager_impl_->FindAndDeleteBucketData( + storage_key, bucket_name, + base::BindOnce(&DidGetStatus, std::move(callback_task_runner), + std::move(callback))); +} + void QuotaManagerProxy::NotifyStorageAccessed(const StorageKey& storage_key, blink::mojom::StorageType type, base::Time access_time) { diff --git a/chromium/storage/browser/quota/quota_manager_proxy.h b/chromium/storage/browser/quota/quota_manager_proxy.h index 038a414439c..294406ac6be 100644 --- a/chromium/storage/browser/quota/quota_manager_proxy.h +++ b/chromium/storage/browser/quota/quota_manager_proxy.h @@ -99,6 +99,16 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerProxy scoped_refptr<base::SequencedTaskRunner> callback_task_runner, base::OnceCallback<void(QuotaErrorOr<BucketInfo>)> callback); + // Deletes bucket with `bucket_name` for `storage_key` for + // StorageType::kTemporary for all registered QuotaClients if a bucket exists. + // Will return QuotaStatusCode to the callback. Called by Storage Buckets API + // for deleting buckets via StorageBucketManager. + virtual void DeleteBucket( + const blink::StorageKey& storage_key, + const std::string& bucket_name, + scoped_refptr<base::SequencedTaskRunner> callback_task_runner, + base::OnceCallback<void(blink::mojom::QuotaStatusCode)> callback); + virtual void NotifyStorageAccessed(const blink::StorageKey& storage_key, blink::mojom::StorageType type, base::Time access_time); diff --git a/chromium/storage/browser/quota/quota_manager_unittest.cc b/chromium/storage/browser/quota/quota_manager_unittest.cc index 3772cfe8a15..994b07ceed5 100644 --- a/chromium/storage/browser/quota/quota_manager_unittest.cc +++ b/chromium/storage/browser/quota/quota_manager_unittest.cc @@ -13,6 +13,7 @@ #include <vector> #include "base/bind.h" +#include "base/callback_forward.h" #include "base/callback_helpers.h" #include "base/containers/contains.h" #include "base/containers/span.h" @@ -30,6 +31,8 @@ #include "base/test/task_environment.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" +#include "components/services/storage/public/cpp/buckets/bucket_locator.h" +#include "components/services/storage/public/cpp/buckets/constants.h" #include "components/services/storage/public/mojom/quota_client.mojom.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h" @@ -90,6 +93,15 @@ MATCHER_P3(MatchesBucketTableEntry, storage_key, type, use_count, "") { testing::ExplainMatchResult(use_count, arg.use_count, result_listener); } +bool ContainsBucket(const std::set<BucketLocator>& buckets, + const BucketInfo& target_bucket) { + BucketLocator target_bucket_locator( + target_bucket.id, target_bucket.storage_key, target_bucket.type, + target_bucket.name == kDefaultBucketName); + auto it = buckets.find(target_bucket_locator); + return it != buckets.end(); +} + } // namespace class QuotaManagerImplTest : public testing::Test { @@ -190,25 +202,77 @@ class QuotaManagerImplTest : public testing::Test { run_loop.Run(); } + QuotaErrorOr<std::set<BucketLocator>> GetBucketsForType( + blink::mojom::StorageType storage_type) { + base::RunLoop run_loop; + QuotaErrorOr<std::set<BucketLocator>> buckets; + quota_manager_impl_->GetBucketsForType( + storage_type, base::BindLambdaForTesting( + [&](QuotaErrorOr<std::set<BucketLocator>> result) { + buckets = std::move(result); + run_loop.Quit(); + })); + run_loop.Run(); + return buckets; + } + + QuotaErrorOr<std::set<BucketLocator>> GetBucketsForHost( + const std::string& host, + blink::mojom::StorageType storage_type) { + base::RunLoop run_loop; + QuotaErrorOr<std::set<BucketLocator>> buckets; + quota_manager_impl_->GetBucketsForHost( + host, storage_type, + base::BindLambdaForTesting( + [&](QuotaErrorOr<std::set<BucketLocator>> result) { + buckets = std::move(result); + run_loop.Quit(); + })); + run_loop.Run(); + return buckets; + } + + QuotaErrorOr<std::set<BucketLocator>> GetBucketsForStorageKey( + const StorageKey& storage_key, + blink::mojom::StorageType storage_type) { + base::RunLoop run_loop; + QuotaErrorOr<std::set<BucketLocator>> buckets; + quota_manager_impl_->GetBucketsForStorageKey( + storage_key, storage_type, + base::BindLambdaForTesting( + [&](QuotaErrorOr<std::set<BucketLocator>> result) { + buckets = std::move(result); + run_loop.Quit(); + })); + run_loop.Run(); + return buckets; + } + void GetUsageInfo() { usage_info_.clear(); - quota_manager_impl_->GetUsageInfo(base::BindOnce( - &QuotaManagerImplTest::DidGetUsageInfo, weak_factory_.GetWeakPtr())); + base::RunLoop run_loop; + quota_manager_impl_->GetUsageInfo( + base::BindOnce(&QuotaManagerImplTest::DidGetUsageInfo, + weak_factory_.GetWeakPtr(), run_loop.QuitClosure())); + run_loop.Run(); } void GetUsageAndQuotaForWebApps(const StorageKey& storage_key, StorageType type) { + base::RunLoop run_loop; quota_status_ = QuotaStatusCode::kUnknown; usage_ = -1; quota_ = -1; quota_manager_impl_->GetUsageAndQuotaForWebApps( storage_key, type, base::BindOnce(&QuotaManagerImplTest::DidGetUsageAndQuota, - weak_factory_.GetWeakPtr())); + weak_factory_.GetWeakPtr(), run_loop.QuitClosure())); + run_loop.Run(); } void GetUsageAndQuotaWithBreakdown(const StorageKey& storage_key, StorageType type) { + base::RunLoop run_loop; quota_status_ = QuotaStatusCode::kUnknown; usage_ = -1; quota_ = -1; @@ -216,18 +280,21 @@ class QuotaManagerImplTest : public testing::Test { quota_manager_impl_->GetUsageAndQuotaWithBreakdown( storage_key, type, base::BindOnce(&QuotaManagerImplTest::DidGetUsageAndQuotaWithBreakdown, - weak_factory_.GetWeakPtr())); + weak_factory_.GetWeakPtr(), run_loop.QuitClosure())); + run_loop.Run(); } void GetUsageAndQuotaForStorageClient(const StorageKey& storage_key, StorageType type) { + base::RunLoop run_loop; quota_status_ = QuotaStatusCode::kUnknown; usage_ = -1; quota_ = -1; quota_manager_impl_->GetUsageAndQuota( storage_key, type, base::BindOnce(&QuotaManagerImplTest::DidGetUsageAndQuota, - weak_factory_.GetWeakPtr())); + weak_factory_.GetWeakPtr(), run_loop.QuitClosure())); + run_loop.Run(); } void SetQuotaSettings(int64_t pool_size, @@ -270,17 +337,22 @@ class QuotaManagerImplTest : public testing::Test { void GetGlobalUsage(StorageType type) { usage_ = -1; unlimited_usage_ = -1; + base::RunLoop run_loop; quota_manager_impl_->GetGlobalUsage( - type, base::BindOnce(&QuotaManagerImplTest::DidGetGlobalUsage, - weak_factory_.GetWeakPtr())); + type, + base::BindOnce(&QuotaManagerImplTest::DidGetGlobalUsage, + weak_factory_.GetWeakPtr(), run_loop.QuitClosure())); + run_loop.Run(); } void GetHostUsageWithBreakdown(const std::string& host, StorageType type) { + base::RunLoop run_loop; usage_ = -1; quota_manager_impl_->GetHostUsageWithBreakdown( host, type, base::BindOnce(&QuotaManagerImplTest::DidGetHostUsageBreakdown, - weak_factory_.GetWeakPtr())); + weak_factory_.GetWeakPtr(), run_loop.QuitClosure())); + run_loop.Run(); } void RunAdditionalUsageAndQuotaTask(const StorageKey& storage_key, @@ -309,16 +381,6 @@ class QuotaManagerImplTest : public testing::Test { weak_factory_.GetWeakPtr())); } - void DeleteStorageKeyData(const StorageKey& storage_key, - StorageType type, - QuotaClientTypes quota_client_types) { - quota_status_ = QuotaStatusCode::kUnknown; - quota_manager_impl_->DeleteStorageKeyData( - storage_key, type, std::move(quota_client_types), - base::BindOnce(&QuotaManagerImplTest::StatusCallback, - weak_factory_.GetWeakPtr())); - } - void DeleteBucketData(const BucketInfo& bucket, QuotaClientTypes quota_client_types) { quota_status_ = QuotaStatusCode::kUnknown; @@ -338,6 +400,17 @@ class QuotaManagerImplTest : public testing::Test { weak_factory_.GetWeakPtr())); } + void FindAndDeleteBucketData(const StorageKey& storage_key, + const std::string& bucket_name) { + base::RunLoop run_loop; + quota_status_ = QuotaStatusCode::kUnknown; + quota_manager_impl_->FindAndDeleteBucketData( + storage_key, bucket_name, + base::BindOnce(&QuotaManagerImplTest::StatusCallbackSync, + weak_factory_.GetWeakPtr(), run_loop.QuitClosure())); + run_loop.Run(); + } + void GetStorageCapacity() { available_space_ = -1; total_space_ = -1; @@ -421,19 +494,24 @@ class QuotaManagerImplTest : public testing::Test { std::move(quit_closure).Run(); } - void DidGetUsageInfo(UsageInfoEntries entries) { + void DidGetUsageInfo(base::OnceClosure quit_closure, + UsageInfoEntries entries) { usage_info_ = std::move(entries); + std::move(quit_closure).Run(); } - void DidGetUsageAndQuota(QuotaStatusCode status, + void DidGetUsageAndQuota(base::OnceClosure quit_closure, + QuotaStatusCode status, int64_t usage, int64_t quota) { quota_status_ = status; usage_ = usage; quota_ = quota; + std::move(quit_closure).Run(); } void DidGetUsageAndQuotaWithBreakdown( + base::OnceClosure quit_closure, QuotaStatusCode status, int64_t usage, int64_t quota, @@ -442,6 +520,7 @@ class QuotaManagerImplTest : public testing::Test { usage_ = usage; quota_ = quota; usage_breakdown_ = std::move(usage_breakdown); + std::move(quit_closure).Run(); } void DidGetQuota(QuotaStatusCode status, int64_t quota) { @@ -459,9 +538,12 @@ class QuotaManagerImplTest : public testing::Test { quota_ = quota; } - void DidGetGlobalUsage(int64_t usage, int64_t unlimited_usage) { + void DidGetGlobalUsage(base::OnceClosure quit_closure, + int64_t usage, + int64_t unlimited_usage) { usage_ = usage; unlimited_usage_ = unlimited_usage; + std::move(quit_closure).Run(); } void DidGetHostUsage(int64_t usage) { usage_ = usage; } @@ -471,11 +553,20 @@ class QuotaManagerImplTest : public testing::Test { quota_status_ = status; } + void StatusCallbackSync(base::OnceClosure quit_closure, + QuotaStatusCode status) { + ++status_callback_count_; + quota_status_ = status; + std::move(quit_closure).Run(); + } + void DidGetHostUsageBreakdown( + base::OnceClosure quit_closure, int64_t usage, blink::mojom::UsageBreakdownPtr usage_breakdown) { usage_ = usage; usage_breakdown_ = std::move(usage_breakdown); + std::move(quit_closure).Run(); } void DidGetEvictionRoundInfo(QuotaStatusCode status, @@ -554,7 +645,9 @@ class QuotaManagerImplTest : public testing::Test { quota_manager_impl_->SetQuotaChangeCallbackForTesting(std::move(cb)); } - bool is_db_disabled() { return quota_manager_impl_->db_disabled_; } + bool is_db_disabled() { + return quota_manager_impl_->is_db_disabled_for_testing(); + } void disable_quota_database(bool disable) { quota_manager_impl_->database_->SetDisabledForTesting(disable); @@ -589,11 +682,6 @@ class QuotaManagerImplTest : public testing::Test { QuotaErrorOr<BucketInfo> bucket_; QuotaErrorOr<std::set<StorageKey>> storage_keys_; - static std::vector<QuotaClientType> AllClients() { - // TODO(pwnall): Implement using something other than an empty vector? - return {}; - } - private: base::Time IncrementMockTime() { ++mock_time_counter_; @@ -651,7 +739,6 @@ TEST_F(QuotaManagerImplTest, GetUsageInfo) { blink::mojom::StorageType::kPersistent}); GetUsageInfo(); - task_environment_.RunUntilIdle(); EXPECT_THAT(usage_info(), testing::UnorderedElementsAre( UsageInfo("foo.com", kTemp, 10 + 15 + 30 + 35), @@ -730,6 +817,111 @@ TEST_F(QuotaManagerImplTest, GetStorageKeysForTypeWithDatabaseError) { EXPECT_TRUE(storage_keys_.value().empty()); } +TEST_F(QuotaManagerImplTest, GetBucketsForType) { + StorageKey storage_key_a = ToStorageKey("http://a.com/"); + StorageKey storage_key_b = ToStorageKey("http://b.com/"); + StorageKey storage_key_c = ToStorageKey("http://c.com/"); + + CreateBucketForTesting(storage_key_a, "bucket_a", kTemp); + EXPECT_TRUE(bucket_.ok()); + BucketInfo bucket_a = bucket_.value(); + + CreateBucketForTesting(storage_key_b, "bucket_b", kTemp); + EXPECT_TRUE(bucket_.ok()); + BucketInfo bucket_b = bucket_.value(); + + CreateBucketForTesting(storage_key_c, "bucket_c", kPerm); + EXPECT_TRUE(bucket_.ok()); + BucketInfo bucket_c = bucket_.value(); + + QuotaErrorOr<std::set<BucketLocator>> result = GetBucketsForType(kTemp); + EXPECT_TRUE(result.ok()); + + std::set<BucketLocator> buckets = result.value(); + EXPECT_EQ(2U, buckets.size()); + EXPECT_TRUE(ContainsBucket(buckets, bucket_a)); + EXPECT_TRUE(ContainsBucket(buckets, bucket_b)); + + result = GetBucketsForType(kPerm); + buckets = result.value(); + EXPECT_EQ(1U, buckets.size()); + EXPECT_TRUE(ContainsBucket(buckets, bucket_c)); +} + +TEST_F(QuotaManagerImplTest, GetBucketsForHost) { + StorageKey host_a_storage_key_1 = ToStorageKey("http://a.com/"); + StorageKey host_a_storage_key_2 = ToStorageKey("https://a.com:123/"); + StorageKey host_b_storage_key = ToStorageKey("http://b.com/"); + + CreateBucketForTesting(host_a_storage_key_1, kDefaultBucketName, kTemp); + EXPECT_TRUE(bucket_.ok()); + BucketInfo host_a_bucket_1 = bucket_.value(); + + CreateBucketForTesting(host_a_storage_key_2, "test", kTemp); + EXPECT_TRUE(bucket_.ok()); + BucketInfo host_a_bucket_2 = bucket_.value(); + + CreateBucketForTesting(host_b_storage_key, kDefaultBucketName, kPerm); + EXPECT_TRUE(bucket_.ok()); + BucketInfo host_b_bucket = bucket_.value(); + + QuotaErrorOr<std::set<BucketLocator>> result = + GetBucketsForHost("a.com", kTemp); + EXPECT_TRUE(result.ok()); + + std::set<BucketLocator> buckets = result.value(); + EXPECT_EQ(2U, buckets.size()); + EXPECT_TRUE(ContainsBucket(buckets, host_a_bucket_1)); + EXPECT_TRUE(ContainsBucket(buckets, host_a_bucket_2)); + + result = GetBucketsForHost("b.com", kPerm); + buckets = result.value(); + EXPECT_EQ(1U, buckets.size()); + EXPECT_TRUE(ContainsBucket(buckets, host_b_bucket)); +} + +TEST_F(QuotaManagerImplTest, GetBucketsForStorageKey) { + StorageKey storage_key_a = ToStorageKey("http://a.com/"); + StorageKey storage_key_b = ToStorageKey("http://b.com/"); + StorageKey storage_key_c = ToStorageKey("http://c.com/"); + + CreateBucketForTesting(storage_key_a, "bucket_a1", kTemp); + EXPECT_TRUE(bucket_.ok()); + BucketInfo bucket_a1 = bucket_.value(); + + CreateBucketForTesting(storage_key_a, "bucket_a2", kTemp); + EXPECT_TRUE(bucket_.ok()); + BucketInfo bucket_a2 = bucket_.value(); + + CreateBucketForTesting(storage_key_b, "bucket_b", kTemp); + EXPECT_TRUE(bucket_.ok()); + BucketInfo bucket_b = bucket_.value(); + + CreateBucketForTesting(storage_key_c, "bucket_c", kPerm); + EXPECT_TRUE(bucket_.ok()); + BucketInfo bucket_c = bucket_.value(); + + QuotaErrorOr<std::set<BucketLocator>> result = + GetBucketsForStorageKey(storage_key_a, kTemp); + EXPECT_TRUE(result.ok()); + + std::set<BucketLocator> buckets = result.value(); + EXPECT_EQ(2U, buckets.size()); + EXPECT_TRUE(ContainsBucket(buckets, bucket_a1)); + EXPECT_TRUE(ContainsBucket(buckets, bucket_a2)); + + result = GetBucketsForStorageKey(storage_key_a, kPerm); + EXPECT_TRUE(result.ok()); + EXPECT_TRUE(result.value().empty()); + + result = GetBucketsForStorageKey(storage_key_c, kPerm); + EXPECT_TRUE(result.ok()); + + buckets = result.value(); + EXPECT_EQ(1U, buckets.size()); + EXPECT_TRUE(ContainsBucket(buckets, bucket_c)); +} + TEST_F(QuotaManagerImplTest, GetUsageAndQuota_Simple) { static const MockStorageKeyData kData[] = { {"http://foo.com/", kTemp, 10}, @@ -740,20 +932,17 @@ TEST_F(QuotaManagerImplTest, GetUsageAndQuota_Simple) { blink::mojom::StorageType::kPersistent}); GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"), kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(80, usage()); EXPECT_EQ(0, quota()); GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(10, usage()); EXPECT_LE(0, quota()); int64_t quota_returned_for_foo = quota(); GetUsageAndQuotaForWebApps(ToStorageKey("http://bar.com/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(0, usage()); EXPECT_EQ(quota_returned_for_foo, quota()); @@ -761,30 +950,24 @@ TEST_F(QuotaManagerImplTest, GetUsageAndQuota_Simple) { TEST_F(QuotaManagerImplTest, GetUsage_NoClient) { GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(0, usage()); GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"), kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(0, usage()); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(0, usage()); GetHostUsageWithBreakdown("foo.com", kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(0, usage()); GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(0, usage()); EXPECT_EQ(0, unlimited_usage()); GetGlobalUsage(kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(0, usage()); EXPECT_EQ(0, unlimited_usage()); } @@ -796,30 +979,24 @@ TEST_F(QuotaManagerImplTest, GetUsage_EmptyClient) { blink::mojom::StorageType::kPersistent}); GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(0, usage()); GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"), kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(0, usage()); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(0, usage()); GetHostUsageWithBreakdown("foo.com", kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(0, usage()); GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(0, usage()); EXPECT_EQ(0, unlimited_usage()); GetGlobalUsage(kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(0, usage()); EXPECT_EQ(0, unlimited_usage()); } @@ -840,7 +1017,6 @@ TEST_F(QuotaManagerImplTest, GetTemporaryUsageAndQuota_MultiStorageKeys) { SetQuotaSettings(kPoolSize, kPerHostQuota, kMustRemainAvailableForSystem); GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(10 + 20, usage()); @@ -849,7 +1025,6 @@ TEST_F(QuotaManagerImplTest, GetTemporaryUsageAndQuota_MultiStorageKeys) { EXPECT_EQ(kPerHostQuota, quota()); GetUsageAndQuotaForWebApps(ToStorageKey("http://bar.com/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(5 + 7, usage()); EXPECT_EQ(kPerHostQuota, quota()); @@ -881,37 +1056,31 @@ TEST_F(QuotaManagerImplTest, GetUsage_MultipleClients) { SetQuotaSettings(kPoolSize, kPerHostQuota, kMustRemainAvailableForSystem); GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(1 + 128, usage()); EXPECT_EQ(kPerHostQuota, quota()); GetUsageAndQuotaForWebApps(ToStorageKey("http://bar.com/"), kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(4, usage()); EXPECT_EQ(0, quota()); GetUsageAndQuotaForWebApps(ToStorageKey("http://unlimited/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(512, usage()); EXPECT_EQ(available_space() + usage(), quota()); GetUsageAndQuotaForWebApps(ToStorageKey("http://unlimited/"), kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(8, usage()); EXPECT_EQ(available_space() + usage(), quota()); GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(1 + 2 + 128 + 512, usage()); EXPECT_EQ(512, unlimited_usage()); GetGlobalUsage(kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(4 + 8 + 256, usage()); EXPECT_EQ(8, unlimited_usage()); @@ -935,34 +1104,31 @@ TEST_F(QuotaManagerImplTest, GetUsageWithBreakdown_Simple) { blink::mojom::StorageType::kPersistent}); CreateAndRegisterClient(kData2, QuotaClientType::kDatabase, {blink::mojom::StorageType::kTemporary}); - CreateAndRegisterClient(kData3, QuotaClientType::kAppcache, + CreateAndRegisterClient(kData3, QuotaClientType::kServiceWorkerCache, {blink::mojom::StorageType::kTemporary}); GetUsageAndQuotaWithBreakdown(ToStorageKey("http://foo.com/"), kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(80, usage()); usage_breakdown_expected.fileSystem = 80; usage_breakdown_expected.webSql = 0; - usage_breakdown_expected.appcache = 0; + usage_breakdown_expected.serviceWorkerCache = 0; EXPECT_TRUE(usage_breakdown_expected.Equals(usage_breakdown())); GetUsageAndQuotaWithBreakdown(ToStorageKey("http://foo.com/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(1 + 4 + 8, usage()); usage_breakdown_expected.fileSystem = 1; usage_breakdown_expected.webSql = 4; - usage_breakdown_expected.appcache = 8; + usage_breakdown_expected.serviceWorkerCache = 8; EXPECT_TRUE(usage_breakdown_expected.Equals(usage_breakdown())); GetUsageAndQuotaWithBreakdown(ToStorageKey("http://bar.com/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(0, usage()); usage_breakdown_expected.fileSystem = 0; usage_breakdown_expected.webSql = 0; - usage_breakdown_expected.appcache = 0; + usage_breakdown_expected.serviceWorkerCache = 0; EXPECT_TRUE(usage_breakdown_expected.Equals(usage_breakdown())); } @@ -971,24 +1137,20 @@ TEST_F(QuotaManagerImplTest, GetUsageWithBreakdown_NoClient) { blink::mojom::UsageBreakdown(); GetUsageAndQuotaWithBreakdown(ToStorageKey("http://foo.com/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(0, usage()); EXPECT_TRUE(usage_breakdown_expected.Equals(usage_breakdown())); GetUsageAndQuotaWithBreakdown(ToStorageKey("http://foo.com/"), kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(0, usage()); EXPECT_TRUE(usage_breakdown_expected.Equals(usage_breakdown())); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(0, usage()); EXPECT_TRUE(usage_breakdown_expected.Equals(usage_breakdown())); GetHostUsageWithBreakdown("foo.com", kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(0, usage()); EXPECT_TRUE(usage_breakdown_expected.Equals(usage_breakdown())); } @@ -1006,14 +1168,12 @@ TEST_F(QuotaManagerImplTest, GetUsageWithBreakdown_MultiStorageKeys) { blink::mojom::StorageType::kPersistent}); GetUsageAndQuotaWithBreakdown(ToStorageKey("http://foo.com/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(10 + 20, usage()); usage_breakdown_expected.fileSystem = 10 + 20; EXPECT_TRUE(usage_breakdown_expected.Equals(usage_breakdown())); GetUsageAndQuotaWithBreakdown(ToStorageKey("http://bar.com/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(5 + 7, usage()); usage_breakdown_expected.fileSystem = 5 + 7; @@ -1043,7 +1203,6 @@ TEST_F(QuotaManagerImplTest, GetUsageWithBreakdown_MultipleClients) { blink::mojom::StorageType::kPersistent}); GetUsageAndQuotaWithBreakdown(ToStorageKey("http://foo.com/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(1 + 128, usage()); usage_breakdown_expected.fileSystem = 1; @@ -1051,7 +1210,6 @@ TEST_F(QuotaManagerImplTest, GetUsageWithBreakdown_MultipleClients) { EXPECT_TRUE(usage_breakdown_expected.Equals(usage_breakdown())); GetUsageAndQuotaWithBreakdown(ToStorageKey("http://bar.com/"), kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(4, usage()); usage_breakdown_expected.fileSystem = 4; @@ -1059,7 +1217,6 @@ TEST_F(QuotaManagerImplTest, GetUsageWithBreakdown_MultipleClients) { EXPECT_TRUE(usage_breakdown_expected.Equals(usage_breakdown())); GetUsageAndQuotaWithBreakdown(ToStorageKey("http://unlimited/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(512, usage()); usage_breakdown_expected.fileSystem = 0; @@ -1067,7 +1224,6 @@ TEST_F(QuotaManagerImplTest, GetUsageWithBreakdown_MultipleClients) { EXPECT_TRUE(usage_breakdown_expected.Equals(usage_breakdown())); GetUsageAndQuotaWithBreakdown(ToStorageKey("http://unlimited/"), kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(8, usage()); usage_breakdown_expected.fileSystem = 8; @@ -1084,7 +1240,6 @@ void QuotaManagerImplTest::GetUsage_WithModifyTestBody(const StorageType type) { CreateAndRegisterClient(data, QuotaClientType::kFileSystem, {type}); GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"), type); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(10 + 20, usage()); @@ -1094,19 +1249,16 @@ void QuotaManagerImplTest::GetUsage_WithModifyTestBody(const StorageType type) { client->AddStorageKeyAndNotify(ToStorageKey("https://foo.com/"), type, 1); GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"), type); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(10 + 20 + 30 - 5 + 1, usage()); int foo_usage = usage(); client->AddStorageKeyAndNotify(ToStorageKey("http://bar.com/"), type, 40); GetUsageAndQuotaForWebApps(ToStorageKey("http://bar.com/"), type); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(40, usage()); GetGlobalUsage(type); - task_environment_.RunUntilIdle(); EXPECT_EQ(foo_usage + 40, usage()); EXPECT_EQ(0, unlimited_usage()); } @@ -1133,7 +1285,6 @@ TEST_F(QuotaManagerImplTest, GetTemporaryUsageAndQuota_WithAdditionalTasks) { GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"), kTemp); GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"), kTemp); GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(10 + 20, usage()); EXPECT_EQ(kPerHostQuota, quota()); @@ -1164,14 +1315,13 @@ TEST_F(QuotaManagerImplTest, GetTemporaryUsageAndQuota_NukeManager) { SetQuotaSettings(kPoolSize, kPerHostQuota, kMustRemainAvailableForSystem); set_additional_callback_count(0); + GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"), kTemp); RunAdditionalUsageAndQuotaTask(ToStorageKey("http://foo.com/"), kTemp); RunAdditionalUsageAndQuotaTask(ToStorageKey("http://bar.com/"), kTemp); - DeleteStorageKeyData(ToStorageKey("http://foo.com/"), kTemp, - AllQuotaClientTypes()); - DeleteStorageKeyData(ToStorageKey("http://bar.com/"), kTemp, - AllQuotaClientTypes()); + DeleteHostData("foo.com", kTemp, AllQuotaClientTypes()); + DeleteHostData("bar.com", kTemp, AllQuotaClientTypes()); // Nuke before waiting for callbacks. set_quota_manager_impl(nullptr); @@ -1199,19 +1349,16 @@ TEST_F(QuotaManagerImplTest, GetTemporaryUsageAndQuota_Overbudget) { EXPECT_LE(kMustRemainAvailableForSystem, available_space()); GetUsageAndQuotaForWebApps(ToStorageKey("http://usage1/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(1, usage()); EXPECT_EQ(kPerHostQuota, quota()); GetUsageAndQuotaForWebApps(ToStorageKey("http://usage10/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(10, usage()); EXPECT_EQ(kPerHostQuota, quota()); GetUsageAndQuotaForWebApps(ToStorageKey("http://usage200/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(200, usage()); EXPECT_EQ(kPerHostQuota, quota()); // should be clamped to the nominal quota @@ -1232,30 +1379,25 @@ TEST_F(QuotaManagerImplTest, GetTemporaryUsageAndQuota_Unlimited) { const int kPerHostQuotaFor1000 = 200; SetQuotaSettings(1000, kPerHostQuotaFor1000, kMustRemainAvailableForSystem); GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(10 + 50 + 4000, usage()); EXPECT_EQ(4000, unlimited_usage()); GetUsageAndQuotaForWebApps(ToStorageKey("http://usage10/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(10, usage()); EXPECT_EQ(kPerHostQuotaFor1000, quota()); GetUsageAndQuotaForWebApps(ToStorageKey("http://usage50/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(50, usage()); EXPECT_EQ(kPerHostQuotaFor1000, quota()); GetUsageAndQuotaForWebApps(ToStorageKey("http://unlimited/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(4000, usage()); EXPECT_EQ(available_space() + usage(), quota()); GetUsageAndQuotaForStorageClient(ToStorageKey("http://unlimited/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(0, usage()); EXPECT_EQ(QuotaManagerImpl::kNoLimit, quota()); @@ -1265,25 +1407,21 @@ TEST_F(QuotaManagerImplTest, GetTemporaryUsageAndQuota_Unlimited) { SetQuotaSettings(100, kPerHostQuotaFor100, kMustRemainAvailableForSystem); GetUsageAndQuotaForWebApps(ToStorageKey("http://usage10/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(10, usage()); EXPECT_EQ(kPerHostQuotaFor100, quota()); GetUsageAndQuotaForWebApps(ToStorageKey("http://usage50/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(50, usage()); EXPECT_EQ(kPerHostQuotaFor100, quota()); GetUsageAndQuotaForWebApps(ToStorageKey("http://unlimited/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(4000, usage()); EXPECT_EQ(available_space() + usage(), quota()); GetUsageAndQuotaForStorageClient(ToStorageKey("http://unlimited/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(0, usage()); EXPECT_EQ(QuotaManagerImpl::kNoLimit, quota()); @@ -1293,30 +1431,25 @@ TEST_F(QuotaManagerImplTest, GetTemporaryUsageAndQuota_Unlimited) { mock_special_storage_policy()->NotifyCleared(); GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(10 + 50 + 4000, usage()); EXPECT_EQ(0, unlimited_usage()); GetUsageAndQuotaForWebApps(ToStorageKey("http://usage10/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(10, usage()); EXPECT_EQ(kPerHostQuotaFor100, quota()); GetUsageAndQuotaForWebApps(ToStorageKey("http://usage50/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(50, usage()); EXPECT_EQ(kPerHostQuotaFor100, quota()); GetUsageAndQuotaForWebApps(ToStorageKey("http://unlimited/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(4000, usage()); EXPECT_EQ(kPerHostQuotaFor100, quota()); GetUsageAndQuotaForStorageClient(ToStorageKey("http://unlimited/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(4000, usage()); EXPECT_EQ(kPerHostQuotaFor100, quota()); @@ -1361,14 +1494,12 @@ TEST_F(QuotaManagerImplTest, GetAndSetPersistentUsageAndQuota) { blink::mojom::StorageType::kPersistent}); GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"), kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(0, usage()); EXPECT_EQ(0, quota()); SetPersistentHostQuota("foo.com", 100); GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"), kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(0, usage()); EXPECT_EQ(100, quota()); @@ -1377,13 +1508,11 @@ TEST_F(QuotaManagerImplTest, GetAndSetPersistentUsageAndQuota) { // quota. mock_special_storage_policy()->AddUnlimited(GURL("http://unlimited/")); GetUsageAndQuotaForWebApps(ToStorageKey("http://unlimited/"), kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(available_space() + usage(), quota()); // GetUsageAndQuotaForStorageClient should just return 0 usage and // kNoLimit quota. GetUsageAndQuotaForStorageClient(ToStorageKey("http://unlimited/"), kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(0, usage()); EXPECT_EQ(QuotaManagerImpl::kNoLimit, quota()); } @@ -1409,7 +1538,6 @@ TEST_F(QuotaManagerImplTest, GetQuotaLowAvailableDiskSpace) { SetQuotaSettings(kPoolSize, kPerHostQuota, kMustRemainAvailable); GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(100000, usage()); EXPECT_EQ(kPerHostQuota, quota()); @@ -1434,7 +1562,6 @@ TEST_F(QuotaManagerImplTest, GetSyncableQuota) { // available disk space. mock_special_storage_policy()->AddUnlimited(GURL("http://unlimited/")); GetUsageAndQuotaForWebApps(ToStorageKey("http://unlimited/"), kSync); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(0, usage()); EXPECT_EQ(QuotaManagerImpl::kSyncableStorageDefaultHostQuota, quota()); @@ -1453,7 +1580,6 @@ TEST_F(QuotaManagerImplTest, GetPersistentUsageAndQuota_MultiStorageKeys) { SetPersistentHostQuota("foo.com", 100); GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"), kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(10 + 20 + 13 + 19, usage()); EXPECT_EQ(100, quota()); @@ -1478,7 +1604,6 @@ TEST_F(QuotaManagerImplTest, GetPersistentUsageAndQuota_WithAdditionalTasks) { GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"), kPerm); GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"), kPerm); GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"), kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(10 + 20, usage()); EXPECT_EQ(100, quota()); @@ -1506,14 +1631,22 @@ TEST_F(QuotaManagerImplTest, GetPersistentUsageAndQuota_NukeManager) { SetPersistentHostQuota("foo.com", 100); set_additional_callback_count(0); - GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"), kPerm); + + // Async GetUsageAndQuota call to test manager reset during call. + blink::mojom::QuotaStatusCode result_status; + quota_manager_impl()->GetUsageAndQuotaForWebApps( + ToStorageKey("http://foo.com/"), kPerm, + base::BindLambdaForTesting( + [&](QuotaStatusCode status, int64_t usage, int64_t quota) { + result_status = status; + })); RunAdditionalUsageAndQuotaTask(ToStorageKey("http://foo.com/"), kPerm); RunAdditionalUsageAndQuotaTask(ToStorageKey("http://bar.com/"), kPerm); // Nuke before waiting for callbacks. set_quota_manager_impl(nullptr); task_environment_.RunUntilIdle(); - EXPECT_EQ(QuotaStatusCode::kErrorAbort, status()); + EXPECT_EQ(QuotaStatusCode::kErrorAbort, result_status); } TEST_F(QuotaManagerImplTest, GetUsage_Simple) { @@ -1528,21 +1661,17 @@ TEST_F(QuotaManagerImplTest, GetUsage_Simple) { blink::mojom::StorageType::kPersistent}); GetGlobalUsage(kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(usage(), 1 + 20 + 600000); EXPECT_EQ(0, unlimited_usage()); GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(usage(), 300 + 4000 + 50000 + 7000000); EXPECT_EQ(0, unlimited_usage()); GetHostUsageWithBreakdown("foo.com", kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(usage(), 1 + 20); GetHostUsageWithBreakdown("buz.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(usage(), 4000 + 50000); } @@ -1560,7 +1689,6 @@ TEST_F(QuotaManagerImplTest, GetUsage_WithModification) { blink::mojom::StorageType::kPersistent}); GetGlobalUsage(kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(usage(), 1 + 20 + 600000); EXPECT_EQ(0, unlimited_usage()); @@ -1568,31 +1696,26 @@ TEST_F(QuotaManagerImplTest, GetUsage_WithModification) { 80000000); GetGlobalUsage(kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(usage(), 1 + 20 + 600000 + 80000000); EXPECT_EQ(0, unlimited_usage()); GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(usage(), 300 + 4000 + 50000 + 7000000); EXPECT_EQ(0, unlimited_usage()); client->ModifyStorageKeyAndNotify(ToStorageKey("http://foo.com/"), kTemp, 1); GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(usage(), 300 + 4000 + 50000 + 7000000 + 1); EXPECT_EQ(0, unlimited_usage()); GetHostUsageWithBreakdown("buz.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(usage(), 4000 + 50000); client->ModifyStorageKeyAndNotify(ToStorageKey("http://buz.com/"), kTemp, 900000000); GetHostUsageWithBreakdown("buz.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(usage(), 4000 + 50000 + 900000000); } @@ -1609,15 +1732,12 @@ TEST_F(QuotaManagerImplTest, GetUsage_WithDeleteStorageKey) { blink::mojom::StorageType::kPersistent}); GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); int64_t predelete_global_tmp = usage(); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); int64_t predelete_host_tmp = usage(); GetHostUsageWithBreakdown("foo.com", kPerm); - task_environment_.RunUntilIdle(); int64_t predelete_host_pers = usage(); DeleteClientStorageKeyData(client, ToStorageKey("http://foo.com/"), kTemp); @@ -1625,15 +1745,12 @@ TEST_F(QuotaManagerImplTest, GetUsage_WithDeleteStorageKey) { EXPECT_EQ(QuotaStatusCode::kOk, status()); GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_global_tmp - 1, usage()); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_host_tmp - 1, usage()); GetHostUsageWithBreakdown("foo.com", kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_host_pers, usage()); } @@ -1664,15 +1781,12 @@ TEST_F(QuotaManagerImplTest, EvictBucketData) { blink::mojom::StorageType::kPersistent}); GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); int64_t predelete_global_tmp = usage(); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); int64_t predelete_host_tmp = usage(); GetHostUsageWithBreakdown("foo.com", kPerm); - task_environment_.RunUntilIdle(); int64_t predelete_host_pers = usage(); for (const MockStorageKeyData& data : kData1) { @@ -1702,15 +1816,12 @@ TEST_F(QuotaManagerImplTest, EvictBucketData) { } GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_global_tmp - (1 + 50000), usage()); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_host_tmp - (1 + 50000), usage()); GetHostUsageWithBreakdown("foo.com", kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_host_pers, usage()); } @@ -1719,11 +1830,9 @@ TEST_F(QuotaManagerImplTest, EvictNonDefaultBucketData) { CreateAndRegisterClient(kData, QuotaClientType::kFileSystem, {kTemp}); GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); int64_t predelete_global_tmp = usage(); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); int64_t predelete_host_tmp = usage(); StorageKey storage_key = ToStorageKey("http://foo.com/"); @@ -1750,11 +1859,9 @@ TEST_F(QuotaManagerImplTest, EvictNonDefaultBucketData) { // Evicting non-default bucket should not change usage. GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_global_tmp, usage()); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_host_tmp, usage()); GetBucket(storage_key, kDefaultBucketName, kTemp); @@ -1768,11 +1875,9 @@ TEST_F(QuotaManagerImplTest, EvictNonDefaultBucketData) { // Evicting default bucket should remove usage. GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(usage(), 0); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(usage(), 0); } @@ -1788,7 +1893,6 @@ TEST_F(QuotaManagerImplTest, EvictBucketDataHistogram) { {blink::mojom::StorageType::kTemporary}); GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); CreateBucketForTesting(kStorageKey, kDefaultBucketName, kTemp); ASSERT_TRUE(bucket_.ok()); @@ -1812,7 +1916,6 @@ TEST_F(QuotaManagerImplTest, EvictBucketDataHistogram) { task_environment_.RunUntilIdle(); GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); EvictBucketData(bucket_.value()); task_environment_.RunUntilIdle(); @@ -1840,15 +1943,12 @@ TEST_F(QuotaManagerImplTest, EvictBucketDataWithDeletionError) { blink::mojom::StorageType::kPersistent}); GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); int64_t predelete_global_tmp = usage(); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); int64_t predelete_host_tmp = usage(); GetHostUsageWithBreakdown("foo.com", kPerm); - task_environment_.RunUntilIdle(); int64_t predelete_host_pers = usage(); for (const MockStorageKeyData& data : kData) @@ -1900,15 +2000,12 @@ TEST_F(QuotaManagerImplTest, EvictBucketDataWithDeletionError) { // Deleting buckets from the database should not affect the results of the // following checks. GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_global_tmp, usage()); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_host_tmp, usage()); GetHostUsageWithBreakdown("foo.com", kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_host_pers, usage()); } @@ -1952,15 +2049,12 @@ TEST_F(QuotaManagerImplTest, DeleteHostDataSimple) { blink::mojom::StorageType::kPersistent}); GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); const int64_t predelete_global_tmp = usage(); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); int64_t predelete_host_tmp = usage(); GetHostUsageWithBreakdown("foo.com", kPerm); - task_environment_.RunUntilIdle(); int64_t predelete_host_pers = usage(); DeleteHostData(std::string(), kTemp, AllQuotaClientTypes()); @@ -1968,15 +2062,12 @@ TEST_F(QuotaManagerImplTest, DeleteHostDataSimple) { EXPECT_EQ(QuotaStatusCode::kOk, status()); GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_global_tmp, usage()); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_host_tmp, usage()); GetHostUsageWithBreakdown("foo.com", kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_host_pers, usage()); DeleteHostData("foo.com", kTemp, AllQuotaClientTypes()); @@ -1984,15 +2075,12 @@ TEST_F(QuotaManagerImplTest, DeleteHostDataSimple) { EXPECT_EQ(QuotaStatusCode::kOk, status()); GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_global_tmp - 1, usage()); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_host_tmp - 1, usage()); GetHostUsageWithBreakdown("foo.com", kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_host_pers, usage()); } @@ -2016,23 +2104,18 @@ TEST_F(QuotaManagerImplTest, DeleteHostDataMultiple) { blink::mojom::StorageType::kPersistent}); GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); const int64_t predelete_global_tmp = usage(); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); const int64_t predelete_foo_tmp = usage(); GetHostUsageWithBreakdown("bar.com", kTemp); - task_environment_.RunUntilIdle(); const int64_t predelete_bar_tmp = usage(); GetHostUsageWithBreakdown("foo.com", kPerm); - task_environment_.RunUntilIdle(); const int64_t predelete_foo_pers = usage(); GetHostUsageWithBreakdown("bar.com", kPerm); - task_environment_.RunUntilIdle(); const int64_t predelete_bar_pers = usage(); reset_status_callback_count(); @@ -2061,24 +2144,19 @@ TEST_F(QuotaManagerImplTest, DeleteHostDataMultiple) { } GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_global_tmp - (1 + 20 + 4000 + 50000 + 6000 + 80 + 9), usage()); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_foo_tmp - (1 + 20 + 50000 + 6000 + 80), usage()); GetHostUsageWithBreakdown("bar.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_bar_tmp - (4000 + 9), usage()); GetHostUsageWithBreakdown("foo.com", kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_foo_pers, usage()); GetHostUsageWithBreakdown("bar.com", kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_bar_pers, usage()); } @@ -2102,27 +2180,21 @@ TEST_F(QuotaManagerImplTest, DeleteHostDataMultipleClientsDifferentTypes) { {blink::mojom::StorageType::kTemporary}); GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); const int64_t predelete_global_tmp = usage(); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); const int64_t predelete_foo_tmp = usage(); GetHostUsageWithBreakdown("bar.com", kTemp); - task_environment_.RunUntilIdle(); const int64_t predelete_bar_tmp = usage(); GetGlobalUsage(kPerm); - task_environment_.RunUntilIdle(); const int64_t predelete_global_pers = usage(); GetHostUsageWithBreakdown("foo.com", kPerm); - task_environment_.RunUntilIdle(); const int64_t predelete_foo_pers = usage(); GetHostUsageWithBreakdown("bar.com", kPerm); - task_environment_.RunUntilIdle(); const int64_t predelete_bar_pers = usage(); reset_status_callback_count(); @@ -2150,38 +2222,35 @@ TEST_F(QuotaManagerImplTest, DeleteHostDataMultipleClientsDifferentTypes) { } GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_global_tmp, usage()); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_foo_tmp, usage()); GetHostUsageWithBreakdown("bar.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_bar_tmp, usage()); GetGlobalUsage(kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_global_pers - (1 + 10 + 1000), usage()); GetHostUsageWithBreakdown("foo.com", kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_foo_pers - (1 + 10), usage()); GetHostUsageWithBreakdown("bar.com", kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_bar_pers - 1000, usage()); } -TEST_F(QuotaManagerImplTest, DeleteStorageKeyDataNoClients) { - DeleteStorageKeyData(ToStorageKey("http://foo.com/"), kTemp, - AllQuotaClientTypes()); +TEST_F(QuotaManagerImplTest, DeleteBucketNoClients) { + CreateBucketForTesting(ToStorageKey("http://foo.com"), kDefaultBucketName, + kTemp); + ASSERT_TRUE(bucket_.ok()); + + DeleteBucketData(bucket_.value(), AllQuotaClientTypes()); task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); } -TEST_F(QuotaManagerImplTest, DeleteStorageKeyDataMultiple) { +TEST_F(QuotaManagerImplTest, DeleteBucketDataMultiple) { static const MockStorageKeyData kData1[] = { {"http://foo.com/", kTemp, 1}, {"http://foo.com:1/", kTemp, 20}, @@ -2200,24 +2269,29 @@ TEST_F(QuotaManagerImplTest, DeleteStorageKeyDataMultiple) { {blink::mojom::StorageType::kTemporary, blink::mojom::StorageType::kPersistent}); + CreateBucketForTesting(ToStorageKey("http://foo.com"), kDefaultBucketName, + kTemp); + ASSERT_TRUE(bucket_.ok()); + BucketInfo foo_temp_bucket = bucket_.value(); + + CreateBucketForTesting(ToStorageKey("http://bar.com"), kDefaultBucketName, + kTemp); + ASSERT_TRUE(bucket_.ok()); + BucketInfo bar_temp_bucket = bucket_.value(); + GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); const int64_t predelete_global_tmp = usage(); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); const int64_t predelete_foo_tmp = usage(); GetHostUsageWithBreakdown("bar.com", kTemp); - task_environment_.RunUntilIdle(); const int64_t predelete_bar_tmp = usage(); GetHostUsageWithBreakdown("foo.com", kPerm); - task_environment_.RunUntilIdle(); const int64_t predelete_foo_pers = usage(); GetHostUsageWithBreakdown("bar.com", kPerm); - task_environment_.RunUntilIdle(); const int64_t predelete_bar_pers = usage(); for (const MockStorageKeyData& data : kData1) { @@ -2231,12 +2305,9 @@ TEST_F(QuotaManagerImplTest, DeleteStorageKeyDataMultiple) { task_environment_.RunUntilIdle(); reset_status_callback_count(); - DeleteStorageKeyData(ToStorageKey("http://foo.com/"), kTemp, - AllQuotaClientTypes()); - DeleteStorageKeyData(ToStorageKey("http://bar.com/"), kTemp, - AllQuotaClientTypes()); - DeleteStorageKeyData(ToStorageKey("http://foo.com/"), kTemp, - AllQuotaClientTypes()); + DeleteBucketData(foo_temp_bucket, AllQuotaClientTypes()); + DeleteBucketData(bar_temp_bucket, AllQuotaClientTypes()); + DeleteBucketData(foo_temp_bucket, AllQuotaClientTypes()); task_environment_.RunUntilIdle(); EXPECT_EQ(3, status_callback_count()); @@ -2255,28 +2326,22 @@ TEST_F(QuotaManagerImplTest, DeleteStorageKeyDataMultiple) { } GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_global_tmp - (1 + 4000 + 50000 + 9), usage()); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_foo_tmp - (1 + 50000), usage()); GetHostUsageWithBreakdown("bar.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_bar_tmp - (4000 + 9), usage()); GetHostUsageWithBreakdown("foo.com", kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_foo_pers, usage()); GetHostUsageWithBreakdown("bar.com", kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_bar_pers, usage()); } -TEST_F(QuotaManagerImplTest, - DeleteStorageKeyDataMultipleClientsDifferentTypes) { +TEST_F(QuotaManagerImplTest, DeleteBucketDataMultipleClientsDifferentTypes) { static const MockStorageKeyData kData1[] = { {"http://foo.com/", kPerm, 1}, {"http://foo.com:1/", kPerm, 10}, @@ -2295,28 +2360,32 @@ TEST_F(QuotaManagerImplTest, CreateAndRegisterClient(kData2, QuotaClientType::kDatabase, {blink::mojom::StorageType::kTemporary}); + CreateBucketForTesting(ToStorageKey("http://foo.com/"), kDefaultBucketName, + kPerm); + ASSERT_TRUE(bucket_.ok()); + BucketInfo foo_perm_bucket = bucket_.value(); + + CreateBucketForTesting(ToStorageKey("http://bar.com/"), kDefaultBucketName, + kPerm); + ASSERT_TRUE(bucket_.ok()); + BucketInfo bar_perm_bucket = bucket_.value(); + GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); const int64_t predelete_global_tmp = usage(); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); const int64_t predelete_foo_tmp = usage(); GetHostUsageWithBreakdown("bar.com", kTemp); - task_environment_.RunUntilIdle(); const int64_t predelete_bar_tmp = usage(); GetGlobalUsage(kPerm); - task_environment_.RunUntilIdle(); const int64_t predelete_global_pers = usage(); GetHostUsageWithBreakdown("foo.com", kPerm); - task_environment_.RunUntilIdle(); const int64_t predelete_foo_pers = usage(); GetHostUsageWithBreakdown("bar.com", kPerm); - task_environment_.RunUntilIdle(); const int64_t predelete_bar_pers = usage(); for (const MockStorageKeyData& data : kData1) { @@ -2330,10 +2399,8 @@ TEST_F(QuotaManagerImplTest, task_environment_.RunUntilIdle(); reset_status_callback_count(); - DeleteStorageKeyData(ToStorageKey("http://foo.com/"), kPerm, - AllQuotaClientTypes()); - DeleteStorageKeyData(ToStorageKey("http://bar.com/"), kPerm, - AllQuotaClientTypes()); + DeleteBucketData(foo_perm_bucket, AllQuotaClientTypes()); + DeleteBucketData(bar_perm_bucket, AllQuotaClientTypes()); task_environment_.RunUntilIdle(); EXPECT_EQ(2, status_callback_count()); @@ -2352,50 +2419,31 @@ TEST_F(QuotaManagerImplTest, } GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_global_tmp, usage()); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_foo_tmp, usage()); GetHostUsageWithBreakdown("bar.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_bar_tmp, usage()); GetGlobalUsage(kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_global_pers - (1 + 1000), usage()); GetHostUsageWithBreakdown("foo.com", kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_foo_pers - 1, usage()); GetHostUsageWithBreakdown("bar.com", kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_bar_pers - 1000, usage()); } -TEST_F(QuotaManagerImplTest, DeleteBucketNoClients) { - CreateBucketForTesting(ToStorageKey("http://foo.com"), kDefaultBucketName, - kTemp); - ASSERT_TRUE(bucket_.ok()); - - DeleteBucketData(bucket_.value(), AllQuotaClientTypes()); - task_environment_.RunUntilIdle(); - EXPECT_EQ(QuotaStatusCode::kOk, status()); -} - -TEST_F(QuotaManagerImplTest, DeleteBucketDataMultiple) { +TEST_F(QuotaManagerImplTest, FindAndDeleteBucketData) { static const MockStorageKeyData kData1[] = { {"http://foo.com/", kTemp, 1}, - {"http://foo.com:1/", kTemp, 20}, - {"http://foo.com/", kPerm, 300}, {"http://bar.com/", kTemp, 4000}, }; static const MockStorageKeyData kData2[] = { - {"http://foo.com/", kTemp, 50000}, {"http://foo.com:1/", kTemp, 6000}, - {"http://foo.com/", kPerm, 700}, {"https://foo.com/", kTemp, 80}, + {"http://foo.com/", kTemp, 50000}, {"http://bar.com/", kTemp, 9}, }; CreateAndRegisterClient(kData1, QuotaClientType::kFileSystem, @@ -2408,191 +2456,53 @@ TEST_F(QuotaManagerImplTest, DeleteBucketDataMultiple) { CreateBucketForTesting(ToStorageKey("http://foo.com"), kDefaultBucketName, kTemp); ASSERT_TRUE(bucket_.ok()); - BucketInfo foo_temp_bucket = bucket_.value(); + BucketInfo foo_bucket = bucket_.value(); CreateBucketForTesting(ToStorageKey("http://bar.com"), kDefaultBucketName, kTemp); ASSERT_TRUE(bucket_.ok()); - BucketInfo bar_temp_bucket = bucket_.value(); + BucketInfo bar_bucket = bucket_.value(); + // Check usage data before deletion. GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); const int64_t predelete_global_tmp = usage(); + ASSERT_EQ((1 + 9 + 4000 + 50000), usage()); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); - const int64_t predelete_foo_tmp = usage(); + ASSERT_EQ((1 + 50000), usage()); GetHostUsageWithBreakdown("bar.com", kTemp); - task_environment_.RunUntilIdle(); - const int64_t predelete_bar_tmp = usage(); - - GetHostUsageWithBreakdown("foo.com", kPerm); - task_environment_.RunUntilIdle(); - const int64_t predelete_foo_pers = usage(); - - GetHostUsageWithBreakdown("bar.com", kPerm); - task_environment_.RunUntilIdle(); - const int64_t predelete_bar_pers = usage(); - - for (const MockStorageKeyData& data : kData1) { - quota_manager_impl()->NotifyStorageAccessed(ToStorageKey(data.origin), - data.type, base::Time::Now()); - } - for (const MockStorageKeyData& data : kData2) { - quota_manager_impl()->NotifyStorageAccessed(ToStorageKey(data.origin), - data.type, base::Time::Now()); - } - task_environment_.RunUntilIdle(); + ASSERT_EQ((9 + 4000), usage()); + // Delete bucket for "http://foo.com/". reset_status_callback_count(); - DeleteBucketData(foo_temp_bucket, AllQuotaClientTypes()); - DeleteBucketData(bar_temp_bucket, AllQuotaClientTypes()); - DeleteBucketData(foo_temp_bucket, AllQuotaClientTypes()); - task_environment_.RunUntilIdle(); - - EXPECT_EQ(3, status_callback_count()); - - DumpBucketTable(); - task_environment_.RunUntilIdle(); - - for (const auto& entry : bucket_entries()) { - if (entry.type != kTemp) - continue; + FindAndDeleteBucketData(foo_bucket.storage_key, foo_bucket.name); + EXPECT_EQ(1, status_callback_count()); - EXPECT_NE(std::string("http://foo.com/"), - entry.storage_key.origin().GetURL().spec()); - EXPECT_NE(std::string("http://bar.com/"), - entry.storage_key.origin().GetURL().spec()); - } - - GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); - EXPECT_EQ(predelete_global_tmp - (1 + 4000 + 50000 + 9), usage()); - - GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); - EXPECT_EQ(predelete_foo_tmp - (1 + 50000), usage()); - - GetHostUsageWithBreakdown("bar.com", kTemp); - task_environment_.RunUntilIdle(); - EXPECT_EQ(predelete_bar_tmp - (4000 + 9), usage()); - - GetHostUsageWithBreakdown("foo.com", kPerm); - task_environment_.RunUntilIdle(); - EXPECT_EQ(predelete_foo_pers, usage()); - - GetHostUsageWithBreakdown("bar.com", kPerm); - task_environment_.RunUntilIdle(); - EXPECT_EQ(predelete_bar_pers, usage()); -} - -TEST_F(QuotaManagerImplTest, DeleteBucketDataMultipleClientsDifferentTypes) { - static const MockStorageKeyData kData1[] = { - {"http://foo.com/", kPerm, 1}, - {"http://foo.com:1/", kPerm, 10}, - {"http://foo.com/", kTemp, 100}, - {"http://bar.com/", kPerm, 1000}, - }; - static const MockStorageKeyData kData2[] = { - {"http://foo.com/", kTemp, 10000}, - {"http://foo.com:1/", kTemp, 100000}, - {"https://foo.com/", kTemp, 1000000}, - {"http://bar.com/", kTemp, 10000000}, - }; - CreateAndRegisterClient(kData1, QuotaClientType::kFileSystem, - {blink::mojom::StorageType::kTemporary, - blink::mojom::StorageType::kPersistent}); - CreateAndRegisterClient(kData2, QuotaClientType::kDatabase, - {blink::mojom::StorageType::kTemporary}); - - CreateBucketForTesting(ToStorageKey("http://foo.com/"), kDefaultBucketName, - kPerm); - ASSERT_TRUE(bucket_.ok()); - BucketInfo foo_perm_bucket = bucket_.value(); - - CreateBucketForTesting(ToStorageKey("http://bar.com/"), kDefaultBucketName, - kPerm); - ASSERT_TRUE(bucket_.ok()); - BucketInfo bar_perm_bucket = bucket_.value(); + GetBucket(foo_bucket.storage_key, foo_bucket.name, foo_bucket.type); + ASSERT_FALSE(bucket_.ok()); + EXPECT_EQ(bucket_.error(), QuotaError::kNotFound); GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); - const int64_t predelete_global_tmp = usage(); + EXPECT_EQ(predelete_global_tmp - (1 + 50000), usage()); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); - const int64_t predelete_foo_tmp = usage(); - - GetHostUsageWithBreakdown("bar.com", kTemp); - task_environment_.RunUntilIdle(); - const int64_t predelete_bar_tmp = usage(); - - GetGlobalUsage(kPerm); - task_environment_.RunUntilIdle(); - const int64_t predelete_global_pers = usage(); - - GetHostUsageWithBreakdown("foo.com", kPerm); - task_environment_.RunUntilIdle(); - const int64_t predelete_foo_pers = usage(); - - GetHostUsageWithBreakdown("bar.com", kPerm); - task_environment_.RunUntilIdle(); - const int64_t predelete_bar_pers = usage(); - - for (const MockStorageKeyData& data : kData1) { - quota_manager_impl()->NotifyStorageAccessed(ToStorageKey(data.origin), - data.type, base::Time::Now()); - } - for (const MockStorageKeyData& data : kData2) { - quota_manager_impl()->NotifyStorageAccessed(ToStorageKey(data.origin), - data.type, base::Time::Now()); - } - task_environment_.RunUntilIdle(); + EXPECT_EQ(0, usage()); + // Delete bucket for "http://bar.com/". reset_status_callback_count(); - DeleteBucketData(foo_perm_bucket, AllQuotaClientTypes()); - DeleteBucketData(bar_perm_bucket, AllQuotaClientTypes()); - task_environment_.RunUntilIdle(); - - EXPECT_EQ(2, status_callback_count()); + FindAndDeleteBucketData(bar_bucket.storage_key, bar_bucket.name); + EXPECT_EQ(1, status_callback_count()); - DumpBucketTable(); - task_environment_.RunUntilIdle(); - - for (const auto& entry : bucket_entries()) { - if (entry.type != kPerm) - continue; - - EXPECT_NE(std::string("http://foo.com/"), - entry.storage_key.origin().GetURL().spec()); - EXPECT_NE(std::string("http://bar.com/"), - entry.storage_key.origin().GetURL().spec()); - } + GetBucket(bar_bucket.storage_key, bar_bucket.name, bar_bucket.type); + ASSERT_FALSE(bucket_.ok()); + EXPECT_EQ(bucket_.error(), QuotaError::kNotFound); GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); - EXPECT_EQ(predelete_global_tmp, usage()); - - GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); - EXPECT_EQ(predelete_foo_tmp, usage()); + EXPECT_EQ(0, usage()); GetHostUsageWithBreakdown("bar.com", kTemp); - task_environment_.RunUntilIdle(); - EXPECT_EQ(predelete_bar_tmp, usage()); - - GetGlobalUsage(kPerm); - task_environment_.RunUntilIdle(); - EXPECT_EQ(predelete_global_pers - (1 + 1000), usage()); - - GetHostUsageWithBreakdown("foo.com", kPerm); - task_environment_.RunUntilIdle(); - EXPECT_EQ(predelete_foo_pers - 1, usage()); - - GetHostUsageWithBreakdown("bar.com", kPerm); - task_environment_.RunUntilIdle(); - EXPECT_EQ(predelete_bar_pers - 1000, usage()); + EXPECT_EQ(0, usage()); } TEST_F(QuotaManagerImplTest, GetCachedStorageKeys) { @@ -2612,17 +2522,14 @@ TEST_F(QuotaManagerImplTest, GetCachedStorageKeys) { EXPECT_TRUE(storage_keys.empty()); GetHostUsageWithBreakdown("a.com", kTemp); - task_environment_.RunUntilIdle(); storage_keys = GetCachedStorageKeys(kTemp); EXPECT_EQ(2U, storage_keys.size()); GetHostUsageWithBreakdown("b.com", kTemp); - task_environment_.RunUntilIdle(); storage_keys = GetCachedStorageKeys(kTemp); EXPECT_EQ(2U, storage_keys.size()); GetHostUsageWithBreakdown("c.com", kTemp); - task_environment_.RunUntilIdle(); storage_keys = GetCachedStorageKeys(kTemp); EXPECT_EQ(3U, storage_keys.size()); @@ -2630,7 +2537,6 @@ TEST_F(QuotaManagerImplTest, GetCachedStorageKeys) { EXPECT_TRUE(storage_keys.empty()); GetGlobalUsage(kTemp); - task_environment_.RunUntilIdle(); storage_keys = GetCachedStorageKeys(kTemp); EXPECT_THAT(storage_keys, testing::UnorderedElementsAre(ToStorageKey("http://a.com"), @@ -2841,61 +2747,6 @@ TEST_F(QuotaManagerImplTest, QuotaForEmptyHost) { EXPECT_EQ(QuotaStatusCode::kErrorNotSupported, status()); } -TEST_F(QuotaManagerImplTest, DeleteSpecificClientTypeSingleStorageKey) { - static const MockStorageKeyData kData1[] = { - {"http://foo.com/", kTemp, 1}, - }; - static const MockStorageKeyData kData2[] = { - {"http://foo.com/", kTemp, 2}, - }; - static const MockStorageKeyData kData3[] = { - {"http://foo.com/", kTemp, 4}, - }; - static const MockStorageKeyData kData4[] = { - {"http://foo.com/", kTemp, 8}, - }; - CreateAndRegisterClient(kData1, QuotaClientType::kFileSystem, - {blink::mojom::StorageType::kTemporary}); - CreateAndRegisterClient(kData2, QuotaClientType::kAppcache, - {blink::mojom::StorageType::kTemporary}); - CreateAndRegisterClient(kData3, QuotaClientType::kDatabase, - {blink::mojom::StorageType::kTemporary}); - CreateAndRegisterClient(kData4, QuotaClientType::kIndexedDatabase, - {blink::mojom::StorageType::kTemporary}); - - GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); - const int64_t predelete_foo_tmp = usage(); - - DeleteStorageKeyData(ToStorageKey("http://foo.com/"), kTemp, - {QuotaClientType::kFileSystem}); - task_environment_.RunUntilIdle(); - GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); - EXPECT_EQ(predelete_foo_tmp - 1, usage()); - - DeleteStorageKeyData(ToStorageKey("http://foo.com/"), kTemp, - {QuotaClientType::kAppcache}); - task_environment_.RunUntilIdle(); - GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); - EXPECT_EQ(predelete_foo_tmp - 2 - 1, usage()); - - DeleteStorageKeyData(ToStorageKey("http://foo.com/"), kTemp, - {QuotaClientType::kDatabase}); - task_environment_.RunUntilIdle(); - GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); - EXPECT_EQ(predelete_foo_tmp - 4 - 2 - 1, usage()); - - DeleteStorageKeyData(ToStorageKey("http://foo.com/"), kTemp, - {QuotaClientType::kIndexedDatabase}); - task_environment_.RunUntilIdle(); - GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); - EXPECT_EQ(predelete_foo_tmp - 8 - 4 - 2 - 1, usage()); -} - TEST_F(QuotaManagerImplTest, DeleteSpecificClientTypeSingleBucket) { static const MockStorageKeyData kData1[] = { {"http://foo.com/", kTemp, 1}, @@ -2911,7 +2762,7 @@ TEST_F(QuotaManagerImplTest, DeleteSpecificClientTypeSingleBucket) { }; CreateAndRegisterClient(kData1, QuotaClientType::kFileSystem, {blink::mojom::StorageType::kTemporary}); - CreateAndRegisterClient(kData2, QuotaClientType::kAppcache, + CreateAndRegisterClient(kData2, QuotaClientType::kServiceWorkerCache, {blink::mojom::StorageType::kTemporary}); CreateAndRegisterClient(kData3, QuotaClientType::kDatabase, {blink::mojom::StorageType::kTemporary}); @@ -2924,31 +2775,26 @@ TEST_F(QuotaManagerImplTest, DeleteSpecificClientTypeSingleBucket) { BucketInfo foo_bucket = bucket_.value(); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); const int64_t predelete_foo_tmp = usage(); DeleteBucketData(foo_bucket, {QuotaClientType::kFileSystem}); task_environment_.RunUntilIdle(); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_foo_tmp - 1, usage()); - DeleteBucketData(foo_bucket, {QuotaClientType::kAppcache}); + DeleteBucketData(foo_bucket, {QuotaClientType::kServiceWorkerCache}); task_environment_.RunUntilIdle(); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_foo_tmp - 2 - 1, usage()); DeleteBucketData(foo_bucket, {QuotaClientType::kDatabase}); task_environment_.RunUntilIdle(); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_foo_tmp - 4 - 2 - 1, usage()); DeleteBucketData(foo_bucket, {QuotaClientType::kIndexedDatabase}); task_environment_.RunUntilIdle(); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_foo_tmp - 8 - 4 - 2 - 1, usage()); } @@ -2967,7 +2813,7 @@ TEST_F(QuotaManagerImplTest, DeleteSpecificClientTypeSingleHost) { }; CreateAndRegisterClient(kData1, QuotaClientType::kFileSystem, {blink::mojom::StorageType::kTemporary}); - CreateAndRegisterClient(kData2, QuotaClientType::kAppcache, + CreateAndRegisterClient(kData2, QuotaClientType::kServiceWorkerCache, {blink::mojom::StorageType::kTemporary}); CreateAndRegisterClient(kData3, QuotaClientType::kDatabase, {blink::mojom::StorageType::kTemporary}); @@ -2975,74 +2821,26 @@ TEST_F(QuotaManagerImplTest, DeleteSpecificClientTypeSingleHost) { {blink::mojom::StorageType::kTemporary}); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); const int64_t predelete_foo_tmp = usage(); DeleteHostData("foo.com", kTemp, {QuotaClientType::kFileSystem}); task_environment_.RunUntilIdle(); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_foo_tmp - 1, usage()); - DeleteHostData("foo.com", kTemp, {QuotaClientType::kAppcache}); + DeleteHostData("foo.com", kTemp, {QuotaClientType::kServiceWorkerCache}); task_environment_.RunUntilIdle(); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_foo_tmp - 2 - 1, usage()); DeleteHostData("foo.com", kTemp, {QuotaClientType::kDatabase}); task_environment_.RunUntilIdle(); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_foo_tmp - 4 - 2 - 1, usage()); DeleteHostData("foo.com", kTemp, {QuotaClientType::kIndexedDatabase}); task_environment_.RunUntilIdle(); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); - EXPECT_EQ(predelete_foo_tmp - 8 - 4 - 2 - 1, usage()); -} - -TEST_F(QuotaManagerImplTest, DeleteMultipleClientTypesSingleStorageKey) { - static const MockStorageKeyData kData1[] = { - {"http://foo.com/", kTemp, 1}, - }; - static const MockStorageKeyData kData2[] = { - {"http://foo.com/", kTemp, 2}, - }; - static const MockStorageKeyData kData3[] = { - {"http://foo.com/", kTemp, 4}, - }; - static const MockStorageKeyData kData4[] = { - {"http://foo.com/", kTemp, 8}, - }; - CreateAndRegisterClient(kData1, QuotaClientType::kFileSystem, - {blink::mojom::StorageType::kTemporary}); - CreateAndRegisterClient(kData2, QuotaClientType::kAppcache, - {blink::mojom::StorageType::kTemporary}); - CreateAndRegisterClient(kData3, QuotaClientType::kDatabase, - {blink::mojom::StorageType::kTemporary}); - CreateAndRegisterClient(kData4, QuotaClientType::kIndexedDatabase, - {blink::mojom::StorageType::kTemporary}); - - GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); - const int64_t predelete_foo_tmp = usage(); - - DeleteStorageKeyData( - ToStorageKey("http://foo.com/"), kTemp, - {QuotaClientType::kFileSystem, QuotaClientType::kDatabase}); - task_environment_.RunUntilIdle(); - GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); - EXPECT_EQ(predelete_foo_tmp - 4 - 1, usage()); - - DeleteStorageKeyData( - ToStorageKey("http://foo.com/"), kTemp, - {QuotaClientType::kAppcache, QuotaClientType::kIndexedDatabase}); - task_environment_.RunUntilIdle(); - GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_foo_tmp - 8 - 4 - 2 - 1, usage()); } @@ -3061,7 +2859,7 @@ TEST_F(QuotaManagerImplTest, DeleteMultipleClientTypesSingleBucket) { }; CreateAndRegisterClient(kData1, QuotaClientType::kFileSystem, {blink::mojom::StorageType::kTemporary}); - CreateAndRegisterClient(kData2, QuotaClientType::kAppcache, + CreateAndRegisterClient(kData2, QuotaClientType::kServiceWorkerCache, {blink::mojom::StorageType::kTemporary}); CreateAndRegisterClient(kData3, QuotaClientType::kDatabase, {blink::mojom::StorageType::kTemporary}); @@ -3074,21 +2872,18 @@ TEST_F(QuotaManagerImplTest, DeleteMultipleClientTypesSingleBucket) { BucketInfo foo_bucket = bucket_.value(); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); const int64_t predelete_foo_tmp = usage(); DeleteBucketData(foo_bucket, {QuotaClientType::kFileSystem, QuotaClientType::kDatabase}); task_environment_.RunUntilIdle(); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_foo_tmp - 4 - 1, usage()); - DeleteBucketData(foo_bucket, {QuotaClientType::kAppcache, + DeleteBucketData(foo_bucket, {QuotaClientType::kServiceWorkerCache, QuotaClientType::kIndexedDatabase}); task_environment_.RunUntilIdle(); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_foo_tmp - 8 - 4 - 2 - 1, usage()); } @@ -3107,7 +2902,7 @@ TEST_F(QuotaManagerImplTest, DeleteMultipleClientTypesSingleHost) { }; CreateAndRegisterClient(kData1, QuotaClientType::kFileSystem, {blink::mojom::StorageType::kTemporary}); - CreateAndRegisterClient(kData2, QuotaClientType::kAppcache, + CreateAndRegisterClient(kData2, QuotaClientType::kServiceWorkerCache, {blink::mojom::StorageType::kTemporary}); CreateAndRegisterClient(kData3, QuotaClientType::kDatabase, {blink::mojom::StorageType::kTemporary}); @@ -3115,14 +2910,13 @@ TEST_F(QuotaManagerImplTest, DeleteMultipleClientTypesSingleHost) { {blink::mojom::StorageType::kTemporary}); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); const int64_t predelete_foo_tmp = usage(); - DeleteHostData("foo.com", kTemp, - {QuotaClientType::kFileSystem, QuotaClientType::kAppcache}); + DeleteHostData( + "foo.com", kTemp, + {QuotaClientType::kFileSystem, QuotaClientType::kServiceWorkerCache}); task_environment_.RunUntilIdle(); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_foo_tmp - 2 - 1, usage()); DeleteHostData( @@ -3130,7 +2924,6 @@ TEST_F(QuotaManagerImplTest, DeleteMultipleClientTypesSingleHost) { {QuotaClientType::kDatabase, QuotaClientType::kIndexedDatabase}); task_environment_.RunUntilIdle(); GetHostUsageWithBreakdown("foo.com", kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(predelete_foo_tmp - 8 - 4 - 2 - 1, usage()); } @@ -3148,10 +2941,8 @@ TEST_F(QuotaManagerImplTest, GetUsageAndQuota_Incognito) { // Query global usage to warmup the usage tracker caching. GetGlobalUsage(kTemp); GetGlobalUsage(kPerm); - task_environment_.RunUntilIdle(); GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"), kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(80, usage()); EXPECT_EQ(0, quota()); @@ -3166,20 +2957,17 @@ TEST_F(QuotaManagerImplTest, GetUsageAndQuota_Incognito) { EXPECT_EQ(kPoolSize - 80 - 10, available_space()); GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(10, usage()); EXPECT_LE(kPerHostQuota, quota()); mock_special_storage_policy()->AddUnlimited(GURL("http://foo.com/")); GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"), kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(80, usage()); EXPECT_EQ(available_space() + usage(), quota()); GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"), kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(10, usage()); EXPECT_EQ(available_space() + usage(), quota()); @@ -3191,12 +2979,10 @@ TEST_F(QuotaManagerImplTest, GetUsageAndQuota_SessionOnly) { kEpheremalStorageKey.origin().GetURL()); GetUsageAndQuotaForWebApps(kEpheremalStorageKey, kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(quota_manager_impl()->settings().session_only_per_host_quota, quota()); GetUsageAndQuotaForWebApps(kEpheremalStorageKey, kPerm); - task_environment_.RunUntilIdle(); EXPECT_EQ(0, quota()); } @@ -3229,7 +3015,6 @@ TEST_F(QuotaManagerImplTest, OverrideQuotaForStorageKey) { run_loop.Run(); GetUsageAndQuotaForWebApps(storage_key, kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(0, usage()); EXPECT_EQ(5000, quota()); @@ -3247,7 +3032,6 @@ TEST_F(QuotaManagerImplTest, OverrideQuotaForStorageKey_Disable) { run_loop1.Run(); GetUsageAndQuotaForWebApps(storage_key, kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(5000, quota()); @@ -3258,7 +3042,6 @@ TEST_F(QuotaManagerImplTest, OverrideQuotaForStorageKey_Disable) { run_loop2.Run(); GetUsageAndQuotaForWebApps(storage_key, kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(9000, quota()); @@ -3269,7 +3052,6 @@ TEST_F(QuotaManagerImplTest, OverrideQuotaForStorageKey_Disable) { run_loop3.Run(); GetUsageAndQuotaForWebApps(storage_key, kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(kDefaultPerHostQuota, quota()); } @@ -3286,7 +3068,6 @@ TEST_F(QuotaManagerImplTest, WithdrawQuotaOverride) { run_loop1.Run(); GetUsageAndQuotaForWebApps(storage_key, kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(5000, quota()); @@ -3297,7 +3078,6 @@ TEST_F(QuotaManagerImplTest, WithdrawQuotaOverride) { run_loop2.Run(); GetUsageAndQuotaForWebApps(storage_key, kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(8000, quota()); @@ -3305,14 +3085,12 @@ TEST_F(QuotaManagerImplTest, WithdrawQuotaOverride) { // it's overrides handle2.reset(); GetUsageAndQuotaForWebApps(storage_key, kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(8000, quota()); handle1.reset(); task_environment_.RunUntilIdle(); GetUsageAndQuotaForWebApps(storage_key, kTemp); - task_environment_.RunUntilIdle(); EXPECT_EQ(QuotaStatusCode::kOk, status()); EXPECT_EQ(kDefaultPerHostQuota, quota()); } diff --git a/chromium/storage/browser/quota/quota_settings.cc b/chromium/storage/browser/quota/quota_settings.cc index 4830c83de5b..3a55be13bfe 100644 --- a/chromium/storage/browser/quota/quota_settings.cc +++ b/chromium/storage/browser/quota/quota_settings.cc @@ -147,7 +147,7 @@ absl::optional<QuotaSettings> CalculateNominalDynamicSettings( RandomizeByPercent(kMaxSessionOnlyHostQuota, kRandomizedPercentage), static_cast<int64_t>(settings.per_host_quota * kSessionOnlyHostQuotaRatio)); - settings.refresh_interval = base::TimeDelta::FromSeconds(60); + settings.refresh_interval = base::Seconds(60); return settings; } diff --git a/chromium/storage/browser/quota/quota_temporary_storage_evictor.cc b/chromium/storage/browser/quota/quota_temporary_storage_evictor.cc index 9aa65c076ea..d6e4b90f10a 100644 --- a/chromium/storage/browser/quota/quota_temporary_storage_evictor.cc +++ b/chromium/storage/browser/quota/quota_temporary_storage_evictor.cc @@ -67,9 +67,9 @@ void QuotaTemporaryStorageEvictor::ReportPerRoundHistogram() { base::UmaHistogramTimes("Quota.TimeSpentToAEvictionRound", now - round_statistics_.start_time); if (!time_of_end_of_last_round_.is_null()) { - base::UmaHistogramCustomTimes( - "Quota.TimeDeltaOfEvictionRounds", now - time_of_end_of_last_round_, - base::TimeDelta::FromMinutes(1), base::TimeDelta::FromDays(1), 50); + base::UmaHistogramCustomTimes("Quota.TimeDeltaOfEvictionRounds", + now - time_of_end_of_last_round_, + base::Minutes(1), base::Days(1), 50); } time_of_end_of_last_round_ = now; @@ -128,9 +128,9 @@ void QuotaTemporaryStorageEvictor::Start() { if (histogram_timer_.IsRunning()) return; - histogram_timer_.Start( - FROM_HERE, base::TimeDelta::FromMinutes(kHistogramReportIntervalMinutes), - this, &QuotaTemporaryStorageEvictor::ReportPerHourHistogram); + histogram_timer_.Start(FROM_HERE, + base::Minutes(kHistogramReportIntervalMinutes), this, + &QuotaTemporaryStorageEvictor::ReportPerHourHistogram); } void QuotaTemporaryStorageEvictor::StartEvictionTimerWithDelay( @@ -138,8 +138,8 @@ void QuotaTemporaryStorageEvictor::StartEvictionTimerWithDelay( DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (eviction_timer_.IsRunning() || timer_disabled_for_testing_) return; - eviction_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(delay_ms), - this, &QuotaTemporaryStorageEvictor::ConsiderEviction); + eviction_timer_.Start(FROM_HERE, base::Milliseconds(delay_ms), this, + &QuotaTemporaryStorageEvictor::ConsiderEviction); } void QuotaTemporaryStorageEvictor::ConsiderEviction() { diff --git a/chromium/storage/browser/quota/quota_temporary_storage_evictor.h b/chromium/storage/browser/quota/quota_temporary_storage_evictor.h index 7eecc08f6f6..fb536df79e3 100644 --- a/chromium/storage/browser/quota/quota_temporary_storage_evictor.h +++ b/chromium/storage/browser/quota/quota_temporary_storage_evictor.h @@ -56,6 +56,11 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaTemporaryStorageEvictor { QuotaTemporaryStorageEvictor(QuotaEvictionHandler* quota_eviction_handler, int64_t interval_ms); + + QuotaTemporaryStorageEvictor(const QuotaTemporaryStorageEvictor&) = delete; + QuotaTemporaryStorageEvictor& operator=(const QuotaTemporaryStorageEvictor&) = + delete; + ~QuotaTemporaryStorageEvictor(); void GetStatistics(std::map<std::string, int64_t>* statistics); @@ -98,8 +103,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaTemporaryStorageEvictor { SEQUENCE_CHECKER(sequence_checker_); base::WeakPtrFactory<QuotaTemporaryStorageEvictor> weak_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(QuotaTemporaryStorageEvictor); }; } // namespace storage diff --git a/chromium/storage/browser/quota/special_storage_policy.h b/chromium/storage/browser/quota/special_storage_policy.h index bb81e51c990..f59e384cdbc 100644 --- a/chromium/storage/browser/quota/special_storage_policy.h +++ b/chromium/storage/browser/quota/special_storage_policy.h @@ -28,6 +28,8 @@ namespace storage { class COMPONENT_EXPORT(STORAGE_BROWSER) SpecialStoragePolicy : public base::RefCountedThreadSafe<SpecialStoragePolicy> { public: + REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE(); + using StoragePolicy = int; enum ChangeFlags { STORAGE_PROTECTED = 1 << 0, diff --git a/chromium/storage/browser/quota/usage_tracker_unittest.cc b/chromium/storage/browser/quota/usage_tracker_unittest.cc index 92bd1711213..b71773be0e8 100644 --- a/chromium/storage/browser/quota/usage_tracker_unittest.cc +++ b/chromium/storage/browser/quota/usage_tracker_unittest.cc @@ -125,6 +125,9 @@ class UsageTrackerTest : public testing::Test { StorageType::kTemporary, storage_policy_.get()) {} + UsageTrackerTest(const UsageTrackerTest&) = delete; + UsageTrackerTest& operator=(const UsageTrackerTest&) = delete; + ~UsageTrackerTest() override = default; UsageTracker* usage_tracker() { @@ -212,8 +215,6 @@ class UsageTrackerTest : public testing::Test { scoped_refptr<MockSpecialStoragePolicy> storage_policy_; std::unique_ptr<UsageTrackerTestQuotaClient> quota_client_; UsageTracker usage_tracker_; - - DISALLOW_COPY_AND_ASSIGN(UsageTrackerTest); }; TEST_F(UsageTrackerTest, GrantAndRevokeUnlimitedStorage) { |