summaryrefslogtreecommitdiff
path: root/chromium/storage
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2022-09-29 16:16:15 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2022-11-09 10:04:06 +0000
commita95a7417ad456115a1ef2da4bb8320531c0821f1 (patch)
treeedcd59279e486d2fd4a8f88a7ed025bcf925c6e6 /chromium/storage
parent33fc33aa94d4add0878ec30dc818e34e1dd3cc2a (diff)
downloadqtwebengine-chromium-a95a7417ad456115a1ef2da4bb8320531c0821f1.tar.gz
BASELINE: Update Chromium to 106.0.5249.126
Change-Id: Ib0bb21c437a7d1686e21c33f2d329f2ac425b7ab Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/438936 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/storage')
-rw-r--r--chromium/storage/browser/BUILD.gn3
-rw-r--r--chromium/storage/browser/blob/README.md2
-rw-r--r--chromium/storage/browser/blob/blob_memory_controller.cc12
-rw-r--r--chromium/storage/browser/blob/blob_memory_controller.h4
-rw-r--r--chromium/storage/browser/blob/blob_registry_impl.cc31
-rw-r--r--chromium/storage/browser/blob/blob_registry_impl.h11
-rw-r--r--chromium/storage/browser/blob/blob_registry_impl_unittest.cc89
-rw-r--r--chromium/storage/browser/blob/blob_transport_strategy.h2
-rw-r--r--chromium/storage/browser/file_system/README.md6
-rw-r--r--chromium/storage/browser/file_system/copy_or_move_file_validator_unittest.cc15
-rw-r--r--chromium/storage/browser/file_system/copy_or_move_operation_delegate.cc5
-rw-r--r--chromium/storage/browser/file_system/copy_or_move_operation_delegate_unittest.cc88
-rw-r--r--chromium/storage/browser/file_system/dragged_file_util_unittest.cc21
-rw-r--r--chromium/storage/browser/file_system/file_system_context.cc23
-rw-r--r--chromium/storage/browser/file_system/file_system_context.h26
-rw-r--r--chromium/storage/browser/file_system/file_system_operation_impl_unittest.cc3
-rw-r--r--chromium/storage/browser/file_system/file_system_operation_impl_write_unittest.cc15
-rw-r--r--chromium/storage/browser/file_system/file_system_quota_client.cc45
-rw-r--r--chromium/storage/browser/file_system/file_system_quota_client_unittest.cc19
-rw-r--r--chromium/storage/browser/file_system/file_system_quota_util.h18
-rw-r--r--chromium/storage/browser/file_system/file_system_usage_cache.cc2
-rw-r--r--chromium/storage/browser/file_system/file_system_usage_cache.h2
-rw-r--r--chromium/storage/browser/file_system/file_system_util.cc6
-rw-r--r--chromium/storage/browser/file_system/obfuscated_file_util.cc413
-rw-r--r--chromium/storage/browser/file_system/obfuscated_file_util.h212
-rw-r--r--chromium/storage/browser/file_system/obfuscated_file_util_memory_delegate.cc16
-rw-r--r--chromium/storage/browser/file_system/obfuscated_file_util_unittest.cc587
-rw-r--r--chromium/storage/browser/file_system/plugin_private_file_system_backend.cc466
-rw-r--r--chromium/storage/browser/file_system/plugin_private_file_system_backend.h184
-rw-r--r--chromium/storage/browser/file_system/plugin_private_file_system_backend_unittest.cc268
-rw-r--r--chromium/storage/browser/file_system/quota/quota_backend_impl.cc34
-rw-r--r--chromium/storage/browser/file_system/quota/quota_backend_impl.h6
-rw-r--r--chromium/storage/browser/file_system/quota/quota_backend_impl_unittest.cc21
-rw-r--r--chromium/storage/browser/file_system/recursive_operation_delegate.cc2
-rw-r--r--chromium/storage/browser/file_system/recursive_operation_delegate.h2
-rw-r--r--chromium/storage/browser/file_system/recursive_operation_delegate_unittest.cc13
-rw-r--r--chromium/storage/browser/file_system/sandbox_file_stream_reader.cc14
-rw-r--r--chromium/storage/browser/file_system/sandbox_file_stream_reader.h2
-rw-r--r--chromium/storage/browser/file_system/sandbox_file_stream_writer.cc14
-rw-r--r--chromium/storage/browser/file_system/sandbox_file_stream_writer_unittest.cc18
-rw-r--r--chromium/storage/browser/file_system/sandbox_file_system_backend.cc2
-rw-r--r--chromium/storage/browser/file_system/sandbox_file_system_backend_delegate.cc189
-rw-r--r--chromium/storage/browser/file_system/sandbox_file_system_backend_delegate.h30
-rw-r--r--chromium/storage/browser/file_system/sandbox_file_system_backend_delegate_unittest.cc8
-rw-r--r--chromium/storage/browser/file_system/sandbox_file_system_backend_unittest.cc4
-rw-r--r--chromium/storage/browser/file_system/sandbox_quota_observer.cc33
-rw-r--r--chromium/storage/browser/file_system/sandbox_quota_observer.h3
-rw-r--r--chromium/storage/browser/quota/OWNERS1
-rw-r--r--chromium/storage/browser/quota/README.md2
-rw-r--r--chromium/storage/browser/quota/quota_database.cc164
-rw-r--r--chromium/storage/browser/quota/quota_database.h47
-rw-r--r--chromium/storage/browser/quota/quota_database_unittest.cc282
-rw-r--r--chromium/storage/browser/quota/quota_device_info_helper.cc2
-rw-r--r--chromium/storage/browser/quota/quota_device_info_helper.h2
-rw-r--r--chromium/storage/browser/quota/quota_internals.mojom9
-rw-r--r--chromium/storage/browser/quota/quota_manager_impl.cc252
-rw-r--r--chromium/storage/browser/quota/quota_manager_impl.h49
-rw-r--r--chromium/storage/browser/quota/quota_manager_proxy.cc31
-rw-r--r--chromium/storage/browser/quota/quota_manager_proxy.h16
-rw-r--r--chromium/storage/browser/quota/quota_manager_proxy_unittest.cc7
-rw-r--r--chromium/storage/browser/quota/quota_manager_unittest.cc196
-rw-r--r--chromium/storage/browser/quota/quota_settings.cc2
-rw-r--r--chromium/storage/browser/quota/quota_settings_unittest.cc17
-rw-r--r--chromium/storage/browser/quota/special_storage_policy.h11
-rw-r--r--chromium/storage/browser/quota/storage_directory_util.cc1
-rw-r--r--chromium/storage/browser/quota/usage_tracker.cc93
-rw-r--r--chromium/storage/browser/quota/usage_tracker.h26
-rw-r--r--chromium/storage/browser/quota/usage_tracker_unittest.cc97
-rw-r--r--chromium/storage/common/file_system/file_system_types.h5
-rw-r--r--chromium/storage/common/file_system/file_system_util.cc2
70 files changed, 1856 insertions, 2447 deletions
diff --git a/chromium/storage/browser/BUILD.gn b/chromium/storage/browser/BUILD.gn
index f6fabb8c1f3..9c1badd60e5 100644
--- a/chromium/storage/browser/BUILD.gn
+++ b/chromium/storage/browser/BUILD.gn
@@ -145,8 +145,6 @@ component("browser") {
"file_system/obfuscated_file_util_memory_delegate.cc",
"file_system/obfuscated_file_util_memory_delegate.h",
"file_system/open_file_system_mode.h",
- "file_system/plugin_private_file_system_backend.cc",
- "file_system/plugin_private_file_system_backend.h",
"file_system/quota/open_file_handle.cc",
"file_system/quota/open_file_handle.h",
"file_system/quota/open_file_handle_context.cc",
@@ -320,7 +318,6 @@ source_set("unittests") {
"file_system/native_file_util_unittest.cc",
"file_system/obfuscated_file_util_memory_delegate_unittest.cc",
"file_system/obfuscated_file_util_unittest.cc",
- "file_system/plugin_private_file_system_backend_unittest.cc",
"file_system/quota/quota_backend_impl_unittest.cc",
"file_system/quota/quota_reservation_manager_unittest.cc",
"file_system/recursive_operation_delegate_unittest.cc",
diff --git a/chromium/storage/browser/blob/README.md b/chromium/storage/browser/blob/README.md
index 3543ed45e10..2e346f0a4a9 100644
--- a/chromium/storage/browser/blob/README.md
+++ b/chromium/storage/browser/blob/README.md
@@ -97,7 +97,7 @@ system partition.
**Minimum Disk Availability**
-We limit our disk limit to accomidate a minimum disk availability. The equation
+We limit our disk limit to accommodate a minimum disk availability. The equation
we use is:
`min_disk_availability = in_memory_limit * 2`
diff --git a/chromium/storage/browser/blob/blob_memory_controller.cc b/chromium/storage/browser/blob/blob_memory_controller.cc
index f5d1e16a3b5..87c87f83d83 100644
--- a/chromium/storage/browser/blob/blob_memory_controller.cc
+++ b/chromium/storage/browser/blob/blob_memory_controller.cc
@@ -82,11 +82,11 @@ File::Error CreateBlobDirectory(const FilePath& blob_storage_dir) {
BlobStorageLimits CalculateBlobStorageLimitsImpl(
const FilePath& storage_dir,
bool disk_enabled,
- absl::optional<int64_t> optional_memory_size_for_testing) {
+ absl::optional<uint64_t> optional_memory_size_for_testing) {
int64_t disk_size = 0ull;
- int64_t memory_size = optional_memory_size_for_testing
- ? optional_memory_size_for_testing.value()
- : base::SysInfo::AmountOfPhysicalMemory();
+ uint64_t memory_size = optional_memory_size_for_testing
+ ? optional_memory_size_for_testing.value()
+ : base::SysInfo::AmountOfPhysicalMemory();
if (disk_enabled && CreateBlobDirectory(storage_dir) == base::File::FILE_OK)
disk_size = base::SysInfo::AmountOfTotalDiskSpace(storage_dir);
@@ -99,9 +99,9 @@ BlobStorageLimits CalculateBlobStorageLimitsImpl(
constexpr size_t kTwoGigabytes = 2ull * 1024 * 1024 * 1024;
limits.max_blob_in_memory_space = kTwoGigabytes;
#elif BUILDFLAG(IS_ANDROID)
- limits.max_blob_in_memory_space = static_cast<size_t>(memory_size / 100ll);
+ limits.max_blob_in_memory_space = static_cast<size_t>(memory_size / 100);
#else
- limits.max_blob_in_memory_space = static_cast<size_t>(memory_size / 5ll);
+ limits.max_blob_in_memory_space = static_cast<size_t>(memory_size / 5);
#endif
}
// Devices just on the edge (RAM == 256MB) should not fail because
diff --git a/chromium/storage/browser/blob/blob_memory_controller.h b/chromium/storage/browser/blob/blob_memory_controller.h
index ecb449b88b7..168c100e2ef 100644
--- a/chromium/storage/browser/blob/blob_memory_controller.h
+++ b/chromium/storage/browser/blob/blob_memory_controller.h
@@ -204,7 +204,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobMemoryController {
// synchronously.
void CallWhenStorageLimitsAreKnown(base::OnceClosure callback);
- void set_amount_of_physical_memory_for_testing(int64_t amount_of_memory) {
+ void set_amount_of_physical_memory_for_testing(uint64_t amount_of_memory) {
amount_of_memory_for_testing_ = amount_of_memory;
}
@@ -283,7 +283,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobMemoryController {
bool did_calculate_storage_limits_ = false;
std::vector<base::OnceClosure> on_calculate_limits_callbacks_;
- absl::optional<int64_t> amount_of_memory_for_testing_;
+ absl::optional<uint64_t> amount_of_memory_for_testing_;
// Memory bookkeeping. These numbers are all disjoint.
// This is the amount of memory we're using for blobs in RAM, including the
diff --git a/chromium/storage/browser/blob/blob_registry_impl.cc b/chromium/storage/browser/blob/blob_registry_impl.cc
index 5285bab2d36..9388dc90a66 100644
--- a/chromium/storage/browser/blob/blob_registry_impl.cc
+++ b/chromium/storage/browser/blob/blob_registry_impl.cc
@@ -51,7 +51,6 @@ class BlobRegistryImpl::BlobUnderConstruction {
ElementEntry& operator=(ElementEntry&& other) = default;
blink::mojom::DataElementPtr element;
- FileSystemURL filesystem_url;
mojo::Remote<blink::mojom::BytesProvider> bytes_provider;
mojo::Remote<blink::mojom::Blob> blob;
};
@@ -385,13 +384,6 @@ void BlobRegistryImpl::BlobUnderConstruction::ResolvedAllBlobDependencies() {
builder_->AppendFile(
f->path, f->offset, f->length,
f->expected_modification_time.value_or(base::Time()));
- } else if (element->is_file_filesystem()) {
- DCHECK(entry.filesystem_url.is_valid());
- const auto& f = element->get_file_filesystem();
- builder_->AppendFileSystemFile(
- entry.filesystem_url, f->offset, f->length,
- f->expected_modification_time.value_or(base::Time()),
- blob_registry_->file_system_context_);
} else if (element->is_blob()) {
DCHECK(blob_uuid_it != referenced_blob_uuids_.end());
const std::string& blob_uuid = *blob_uuid_it++;
@@ -501,10 +493,8 @@ bool BlobRegistryImpl::BlobUnderConstruction::ContainsCycles(
BlobRegistryImpl::BlobRegistryImpl(
base::WeakPtr<BlobStorageContext> context,
base::WeakPtr<BlobUrlRegistry> url_registry,
- scoped_refptr<base::TaskRunner> url_registry_runner,
- scoped_refptr<FileSystemContext> file_system_context)
+ scoped_refptr<base::TaskRunner> url_registry_runner)
: context_(std::move(context)),
- file_system_context_(std::move(file_system_context)),
url_registry_(std::move(url_registry)),
url_registry_runner_(std::move(url_registry_runner)) {}
@@ -558,25 +548,6 @@ void BlobRegistryImpl::Register(
std::move(callback).Run();
return;
}
- } else if (entry.element->is_file_filesystem()) {
- const GURL crack_url = entry.element->get_file_filesystem()->url;
- // TODO(https://crbug.com/1221308): determine whether StorageKey should be
- // replaced with a more meaningful value
- const blink::StorageKey crack_storage_key =
- blink::StorageKey(url::Origin::Create(crack_url));
- entry.filesystem_url =
- file_system_context_->CrackURL(crack_url, crack_storage_key);
- if (!entry.filesystem_url.is_valid() ||
- !file_system_context_->GetFileSystemBackend(
- entry.filesystem_url.type()) ||
- !delegate->CanReadFileSystemFile(entry.filesystem_url)) {
- std::unique_ptr<BlobDataHandle> handle = context_->AddBrokenBlob(
- uuid, content_type, content_disposition,
- BlobStatus::ERR_REFERENCED_FILE_UNAVAILABLE);
- BlobImpl::Create(std::move(handle), std::move(blob));
- std::move(callback).Run();
- return;
- }
}
element_entries.push_back(std::move(entry));
}
diff --git a/chromium/storage/browser/blob/blob_registry_impl.h b/chromium/storage/browser/blob/blob_registry_impl.h
index 866dac0921d..1ce62bd0e62 100644
--- a/chromium/storage/browser/blob/blob_registry_impl.h
+++ b/chromium/storage/browser/blob/blob_registry_impl.h
@@ -12,16 +12,18 @@
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "mojo/public/cpp/bindings/self_owned_associated_receiver.h"
#include "storage/browser/blob/blob_url_registry.h"
-#include "storage/browser/file_system/file_system_context.h"
#include "third_party/blink/public/mojom/blob/blob_registry.mojom.h"
#include "url/origin.h"
+namespace base {
+class FilePath;
+}
+
namespace storage {
class BlobBuilderFromStream;
class BlobDataHandle;
class BlobStorageContext;
-class FileSystemURL;
class COMPONENT_EXPORT(STORAGE_BROWSER) BlobRegistryImpl
: public blink::mojom::BlobRegistry {
@@ -32,14 +34,12 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobRegistryImpl
public:
virtual ~Delegate() {}
virtual bool CanReadFile(const base::FilePath& file) = 0;
- virtual bool CanReadFileSystemFile(const FileSystemURL& url) = 0;
virtual bool CanAccessDataForOrigin(const url::Origin& origin) = 0;
};
BlobRegistryImpl(base::WeakPtr<BlobStorageContext> context,
base::WeakPtr<BlobUrlRegistry> url_registry,
- scoped_refptr<base::TaskRunner> url_registry_runner,
- scoped_refptr<FileSystemContext> file_system_context);
+ scoped_refptr<base::TaskRunner> url_registry_runner);
BlobRegistryImpl(const BlobRegistryImpl&) = delete;
BlobRegistryImpl& operator=(const BlobRegistryImpl&) = delete;
@@ -96,7 +96,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobRegistryImpl
std::unique_ptr<BlobDataHandle> result);
base::WeakPtr<BlobStorageContext> context_;
- scoped_refptr<FileSystemContext> file_system_context_;
// `url_registry_` should only be accessed on `url_registry_runner_`.
base::WeakPtr<BlobUrlRegistry> url_registry_;
diff --git a/chromium/storage/browser/blob/blob_registry_impl_unittest.cc b/chromium/storage/browser/blob/blob_registry_impl_unittest.cc
index 112ef4099b3..30d8db2563e 100644
--- a/chromium/storage/browser/blob/blob_registry_impl_unittest.cc
+++ b/chromium/storage/browser/blob/blob_registry_impl_unittest.cc
@@ -74,19 +74,9 @@ class BlobRegistryImplTest : public testing::Test {
data_dir_.GetPath(), data_dir_.GetPath(),
base::ThreadPool::CreateTaskRunner({base::MayBlock()}));
auto storage_policy = base::MakeRefCounted<MockSpecialStoragePolicy>();
- file_system_context_ = FileSystemContext::Create(
- base::ThreadTaskRunnerHandle::Get(),
- base::ThreadTaskRunnerHandle::Get(),
- /*external_mount_points=*/nullptr, std::move(storage_policy),
- /*quota_manager_proxy=*/nullptr,
- std::vector<std::unique_ptr<FileSystemBackend>>(),
- std::vector<URLRequestAutoMountHandler>(), data_dir_.GetPath(),
- FileSystemOptions(FileSystemOptions::PROFILE_MODE_INCOGNITO,
- /*force_in_memory=*/false,
- std::vector<std::string>()));
registry_impl_ = std::make_unique<BlobRegistryImpl>(
context_->AsWeakPtr(), url_registry_.AsWeakPtr(),
- base::SequencedTaskRunnerHandle::Get(), file_system_context_);
+ base::SequencedTaskRunnerHandle::Get());
auto delegate = std::make_unique<MockBlobRegistryDelegate>();
delegate_ptr_ = delegate.get();
registry_impl_->Bind(registry_.BindNewPipeAndPassReceiver(),
@@ -194,7 +184,6 @@ class BlobRegistryImplTest : public testing::Test {
base::test::TaskEnvironment task_environment_;
absl::optional<base::ScopedDisallowBlocking> disallow_blocking_;
std::unique_ptr<BlobStorageContext> context_;
- scoped_refptr<FileSystemContext> file_system_context_;
BlobUrlRegistry url_registry_;
std::unique_ptr<BlobRegistryImpl> registry_impl_;
mojo::Remote<blink::mojom::BlobRegistry> registry_;
@@ -630,82 +619,6 @@ TEST_F(BlobRegistryImplTest, Register_ValidFile) {
EXPECT_EQ(0u, BlobsUnderConstruction());
}
-TEST_F(BlobRegistryImplTest, Register_FileSystemFile_InvalidScheme) {
- const std::string kId = "id";
-
- std::vector<blink::mojom::DataElementPtr> elements;
- elements.push_back(blink::mojom::DataElement::NewFileFilesystem(
- blink::mojom::DataElementFilesystemURL::New(GURL("http://foobar.com/"), 0,
- 16, absl::nullopt)));
-
- mojo::PendingRemote<blink::mojom::Blob> blob;
- EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId,
- "", "", std::move(elements)));
- EXPECT_TRUE(bad_messages_.empty());
-
- std::unique_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId);
- WaitForBlobCompletion(handle.get());
-
- EXPECT_TRUE(handle->IsBroken());
- EXPECT_EQ(BlobStatus::ERR_REFERENCED_FILE_UNAVAILABLE,
- handle->GetBlobStatus());
- EXPECT_EQ(0u, BlobsUnderConstruction());
-}
-
-TEST_F(BlobRegistryImplTest, Register_FileSystemFile_UnreadableFile) {
- delegate_ptr_->can_read_file_system_file_result = false;
-
- const std::string kId = "id";
- const GURL url("filesystem:http://example.com/temporary/myfile.png");
-
- std::vector<blink::mojom::DataElementPtr> elements;
- elements.push_back(blink::mojom::DataElement::NewFileFilesystem(
- blink::mojom::DataElementFilesystemURL::New(url, 0, 16, absl::nullopt)));
-
- mojo::PendingRemote<blink::mojom::Blob> blob;
- EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId,
- "", "", std::move(elements)));
- EXPECT_TRUE(bad_messages_.empty());
-
- std::unique_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId);
- WaitForBlobCompletion(handle.get());
-
- EXPECT_TRUE(handle->IsBroken());
- EXPECT_EQ(BlobStatus::ERR_REFERENCED_FILE_UNAVAILABLE,
- handle->GetBlobStatus());
- EXPECT_EQ(0u, BlobsUnderConstruction());
-}
-
-TEST_F(BlobRegistryImplTest, Register_FileSystemFile_Valid) {
- delegate_ptr_->can_read_file_system_file_result = true;
-
- const std::string kId = "id";
- const GURL url("filesystem:http://example.com/temporary/myfile.png");
-
- std::vector<blink::mojom::DataElementPtr> elements;
- elements.push_back(blink::mojom::DataElement::NewFileFilesystem(
- blink::mojom::DataElementFilesystemURL::New(url, 0, 16, absl::nullopt)));
-
- mojo::PendingRemote<blink::mojom::Blob> blob;
- EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId,
- "", "", std::move(elements)));
- EXPECT_TRUE(bad_messages_.empty());
-
- std::unique_ptr<BlobDataHandle> handle = context_->GetBlobDataFromUUID(kId);
- WaitForBlobCompletion(handle.get());
-
- EXPECT_FALSE(handle->IsBroken());
- ASSERT_EQ(BlobStatus::DONE, handle->GetBlobStatus());
-
- BlobDataBuilder expected_blob_data(kId);
- expected_blob_data.AppendFileSystemFile(
- file_system_context_->CrackURLInFirstPartyContext(url), 0, 16,
- base::Time(), file_system_context_);
-
- EXPECT_EQ(expected_blob_data, *handle->CreateSnapshot());
- EXPECT_EQ(0u, BlobsUnderConstruction());
-}
-
TEST_F(BlobRegistryImplTest, Register_BytesInvalidEmbeddedData) {
const std::string kId = "id";
diff --git a/chromium/storage/browser/blob/blob_transport_strategy.h b/chromium/storage/browser/blob/blob_transport_strategy.h
index 1985be83ce3..ee3b4216a43 100644
--- a/chromium/storage/browser/blob/blob_transport_strategy.h
+++ b/chromium/storage/browser/blob/blob_transport_strategy.h
@@ -51,7 +51,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobTransportStrategy {
BlobTransportStrategy(BlobDataBuilder* builder,
ResultCallback result_callback);
- raw_ptr<BlobDataBuilder> builder_;
+ raw_ptr<BlobDataBuilder, DanglingUntriaged> builder_;
ResultCallback result_callback_;
};
diff --git a/chromium/storage/browser/file_system/README.md b/chromium/storage/browser/file_system/README.md
index ed65fa5bb4e..f09da8339db 100644
--- a/chromium/storage/browser/file_system/README.md
+++ b/chromium/storage/browser/file_system/README.md
@@ -78,9 +78,9 @@ It owns:
specific "sync" file system.
- Via `scoped_refptr` a bunch of `FileSystemBackend` instances. These
- are either created by the `FileSystemContext` itself (for sandbox, plugin
- private, and isolated file systems) or passed in to constructor after
- requesting the additional backends from the content embedder via
+ are either created by the `FileSystemContext` itself (for sandbox and
+ isolated file systems) or passed in to constructor after requesting the
+ additional backends from the content embedder via
`ContentBrowserClient::GetAdditionalFileSystemBackends`.
And further more it references:
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 b09f6497a44..33965975dc8 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
@@ -24,8 +24,9 @@
#include "storage/browser/file_system/file_system_context.h"
#include "storage/browser/file_system/file_system_url.h"
#include "storage/browser/file_system/isolated_context.h"
-#include "storage/browser/quota/quota_manager_proxy.h"
#include "storage/browser/test/async_file_test_helper.h"
+#include "storage/browser/test/mock_quota_manager.h"
+#include "storage/browser/test/mock_quota_manager_proxy.h"
#include "storage/browser/test/mock_special_storage_policy.h"
#include "storage/browser/test/test_file_system_backend.h"
#include "storage/browser/test/test_file_system_context.h"
@@ -71,8 +72,14 @@ class CopyOrMoveFileValidatorTestHelper {
ASSERT_TRUE(base_.CreateUniqueTempDir());
base::FilePath base_dir = base_.GetPath();
- file_system_context_ = CreateFileSystemContextForTesting(
- /*quota_manager_proxy=*/nullptr, base_dir);
+ quota_manager_ = base::MakeRefCounted<storage::MockQuotaManager>(
+ /*is_incognito=*/false, base_dir, base::ThreadTaskRunnerHandle::Get(),
+ base::MakeRefCounted<storage::MockSpecialStoragePolicy>());
+ quota_manager_proxy_ = base::MakeRefCounted<storage::MockQuotaManagerProxy>(
+ quota_manager_.get(), base::ThreadTaskRunnerHandle::Get());
+ // Prepare file system.
+ file_system_context_ = storage::CreateFileSystemContextForTesting(
+ quota_manager_proxy_.get(), base_dir);
// Set up TestFileSystemBackend to require CopyOrMoveFileValidator.
FileSystemBackend* test_file_system_backend =
@@ -187,6 +194,8 @@ class CopyOrMoveFileValidatorTestHelper {
std::string dest_fsid_;
base::test::TaskEnvironment task_environment_;
+ scoped_refptr<storage::MockQuotaManager> quota_manager_;
+ scoped_refptr<storage::MockQuotaManagerProxy> quota_manager_proxy_;
scoped_refptr<FileSystemContext> file_system_context_;
FileSystemURL copy_src_;
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 b7d0cbd0649..eb8f73fa1dd 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
@@ -1204,8 +1204,11 @@ FileSystemURL CopyOrMoveOperationDelegate::CreateDestURL(
base::FilePath relative = dest_root_.virtual_path();
src_root_.virtual_path().AppendRelativePath(src_url.virtual_path(),
&relative);
- return file_system_context()->CreateCrackedFileSystemURL(
+ FileSystemURL dest_url = file_system_context()->CreateCrackedFileSystemURL(
dest_root_.storage_key(), dest_root_.mount_type(), relative);
+ if (dest_root_.bucket().has_value())
+ dest_url.SetBucket(dest_root_.bucket().value());
+ return dest_url;
}
} // namespace storage
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 cfb4b552cb2..d351e279b99 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
@@ -629,8 +629,9 @@ class CopyOrMoveOperationTestHelper {
private:
void GetUsageAndQuota(FileSystemType type, int64_t* usage, int64_t* quota) {
blink::mojom::QuotaStatusCode status =
- AsyncFileTestHelper::GetUsageAndQuota(quota_manager_->proxy(), origin_,
- type, usage, quota);
+ AsyncFileTestHelper::GetUsageAndQuota(quota_manager_->proxy(),
+ blink::StorageKey(origin_), type,
+ usage, quota);
ASSERT_EQ(blink::mojom::QuotaStatusCode::kOk, status);
}
@@ -684,7 +685,6 @@ TEST_P(LocalFileSystemCopyOrMoveOperationTest, SingleFile) {
FileSystemURL src = helper.SourceURL("a");
FileSystemURL dest = helper.DestURL("b");
int64_t src_initial_usage = helper.GetSourceUsage();
- int64_t dest_initial_usage = helper.GetDestUsage();
// Set up a source file.
ASSERT_EQ(base::File::FILE_OK, helper.CreateFile(src, 10));
@@ -716,20 +716,11 @@ TEST_P(LocalFileSystemCopyOrMoveOperationTest, SingleFile) {
ASSERT_EQ(src_should_exist, helper.FileExists(src, 10));
ASSERT_EQ(dest_should_exist, helper.FileExists(dest, 10));
- if (IsLocal()) {
- int64_t src_new_usage = helper.GetSourceUsage();
- if (IsMove() || BlockingEnabled()) {
- EXPECT_EQ(src_new_usage, src_initial_usage + src_increase);
- } else {
- EXPECT_EQ(src_new_usage, src_initial_usage + 2 * src_increase);
- }
+ int64_t src_new_usage = helper.GetSourceUsage();
+ if (IsMove() || BlockingEnabled()) {
+ EXPECT_EQ(src_new_usage, src_initial_usage + src_increase);
} else {
- int64_t src_new_usage = helper.GetSourceUsage();
- ASSERT_EQ(src_new_usage,
- src_initial_usage + (src_should_exist ? src_increase : 0));
- int64_t dest_new_usage = helper.GetDestUsage();
- ASSERT_EQ(dest_new_usage,
- dest_initial_usage + (dest_should_exist ? src_increase : 0));
+ EXPECT_EQ(src_new_usage, src_initial_usage + 2 * src_increase);
}
}
@@ -742,7 +733,6 @@ TEST_P(LocalFileSystemCopyOrMoveOperationTest, EmptyDirectory) {
FileSystemURL src = helper.SourceURL("a");
FileSystemURL dest = helper.DestURL("b");
int64_t src_initial_usage = helper.GetSourceUsage();
- int64_t dest_initial_usage = helper.GetDestUsage();
// Set up a source directory.
ASSERT_EQ(base::File::FILE_OK, helper.CreateDirectory(src));
@@ -774,20 +764,11 @@ TEST_P(LocalFileSystemCopyOrMoveOperationTest, EmptyDirectory) {
ASSERT_EQ(src_should_exist, helper.DirectoryExists(src));
ASSERT_EQ(dest_should_exist, helper.DirectoryExists(dest));
- if (IsLocal()) {
- int64_t src_new_usage = helper.GetSourceUsage();
- if (IsMove() || BlockingEnabled()) {
- EXPECT_EQ(src_new_usage, src_initial_usage + src_increase);
- } else {
- EXPECT_EQ(src_new_usage, src_initial_usage + 2 * src_increase);
- }
+ int64_t src_new_usage = helper.GetSourceUsage();
+ if (IsMove() || BlockingEnabled()) {
+ EXPECT_EQ(src_new_usage, src_initial_usage + src_increase);
} else {
- int64_t src_new_usage = helper.GetSourceUsage();
- int64_t dest_new_usage = helper.GetDestUsage();
- ASSERT_EQ(src_new_usage,
- src_initial_usage + (src_should_exist ? src_increase : 0));
- ASSERT_EQ(dest_new_usage,
- dest_initial_usage + (dest_should_exist ? src_increase : 0));
+ EXPECT_EQ(src_new_usage, src_initial_usage + 2 * src_increase);
}
}
@@ -800,7 +781,6 @@ TEST_P(LocalFileSystemCopyOrMoveOperationTest, FilesAndDirectories) {
FileSystemURL src = helper.SourceURL("a");
FileSystemURL dest = helper.DestURL("b");
int64_t src_initial_usage = helper.GetSourceUsage();
- int64_t dest_initial_usage = helper.GetDestUsage();
// Set up a source directory.
ASSERT_EQ(base::File::FILE_OK, helper.CreateDirectory(src));
@@ -873,37 +853,15 @@ TEST_P(LocalFileSystemCopyOrMoveOperationTest, FilesAndDirectories) {
CopyOrMoveOperationTestHelper::VerifyDirectoryState::ALL_FILES_EXIST);
}
- if (IsLocal()) {
- // For local operations we can only check the size if there is no blocking
- // involved.
- if (!BlockingEnabled()) {
- int64_t src_new_usage = helper.GetSourceUsage();
- if (IsMove()) {
- ASSERT_EQ(src_initial_usage + src_increase, src_new_usage);
- } else {
- // Copies duplicate used size on common file system.
- ASSERT_EQ(src_initial_usage + 2 * src_increase, src_new_usage);
- }
- }
- } else {
+ // For local operations we can only check the size if there is no blocking
+ // involved.
+ if (!BlockingEnabled()) {
int64_t src_new_usage = helper.GetSourceUsage();
- if (!IsMove()) {
- // For copies, all source files should remain.
+ if (IsMove()) {
ASSERT_EQ(src_initial_usage + src_increase, src_new_usage);
- } else if (!BlockingEnabled()) {
- // For moves without blocking, additional source size should be zero.
- ASSERT_EQ(src_initial_usage, src_new_usage);
} else {
- // For moves with blocking, some files should be blocked and remain on the
- // source file system.
- ASSERT_LT(src_initial_usage, src_new_usage);
- }
-
- int64_t dest_increase = helper.GetDestUsage() - dest_initial_usage;
- if (!BlockingEnabled()) {
- ASSERT_EQ(src_increase, dest_increase);
- } else {
- ASSERT_GT(src_increase, dest_increase);
+ // Copies duplicate used size on common file system.
+ ASSERT_EQ(src_initial_usage + 2 * src_increase, src_new_usage);
}
}
}
@@ -1348,8 +1306,14 @@ class CopyOrMoveOperationDelegateTestHelper {
void SetUp() {
ASSERT_TRUE(base_.CreateUniqueTempDir());
base::FilePath base_dir = base_.GetPath();
- file_system_context_ =
- storage::CreateFileSystemContextForTesting(nullptr, base_dir);
+ quota_manager_ = base::MakeRefCounted<storage::MockQuotaManager>(
+ /*is_incognito=*/false, base_dir, base::ThreadTaskRunnerHandle::Get(),
+ base::MakeRefCounted<storage::MockSpecialStoragePolicy>());
+ quota_manager_proxy_ = base::MakeRefCounted<storage::MockQuotaManagerProxy>(
+ quota_manager_.get(), base::ThreadTaskRunnerHandle::Get());
+ // Prepare file system.
+ file_system_context_ = storage::CreateFileSystemContextForTesting(
+ quota_manager_proxy_.get(), base_dir);
// Prepare the origin's root directory.
FileSystemBackend* backend =
@@ -1452,6 +1416,8 @@ class CopyOrMoveOperationDelegateTestHelper {
FileSystemURL error_url_;
base::test::TaskEnvironment task_environment_;
+ scoped_refptr<storage::MockQuotaManager> quota_manager_;
+ scoped_refptr<storage::MockQuotaManagerProxy> quota_manager_proxy_;
scoped_refptr<FileSystemContext> file_system_context_;
};
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 e1020fed841..b40a59149ca 100644
--- a/chromium/storage/browser/file_system/dragged_file_util_unittest.cc
+++ b/chromium/storage/browser/file_system/dragged_file_util_unittest.cc
@@ -29,6 +29,9 @@
#include "storage/browser/quota/quota_manager_proxy.h"
#include "storage/browser/test/async_file_test_helper.h"
#include "storage/browser/test/file_system_test_file_set.h"
+#include "storage/browser/test/mock_quota_manager.h"
+#include "storage/browser/test/mock_quota_manager_proxy.h"
+#include "storage/browser/test/mock_special_storage_policy.h"
#include "storage/browser/test/test_file_system_context.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -107,8 +110,16 @@ class DraggedFileUtilTest : public testing::Test {
// root paths) as dropped files.
SimulateDropFiles();
- file_system_context_ = CreateFileSystemContextForTesting(
- /*quota_manager_proxy=*/nullptr, partition_dir_.GetPath());
+ base::FilePath partition_path = partition_dir_.GetPath();
+ quota_manager_ = base::MakeRefCounted<storage::MockQuotaManager>(
+ /*is_incognito=*/false, partition_path,
+ base::ThreadTaskRunnerHandle::Get(),
+ base::MakeRefCounted<storage::MockSpecialStoragePolicy>());
+ quota_manager_proxy_ = base::MakeRefCounted<storage::MockQuotaManagerProxy>(
+ quota_manager_.get(), base::ThreadTaskRunnerHandle::Get());
+ // Prepare file system.
+ file_system_context_ = storage::CreateFileSystemContextForTesting(
+ quota_manager_proxy_.get(), partition_path);
isolated_context()->AddReference(filesystem_id_);
}
@@ -274,9 +285,11 @@ class DraggedFileUtilTest : public testing::Test {
base::ScopedTempDir data_dir_;
base::ScopedTempDir partition_dir_;
- base::test::SingleThreadTaskEnvironment task_environment_{
- base::test::SingleThreadTaskEnvironment::MainThreadType::IO};
+ base::test::TaskEnvironment task_environment_{
+ base::test::TaskEnvironment::MainThreadType::IO};
std::string filesystem_id_;
+ scoped_refptr<storage::MockQuotaManager> quota_manager_;
+ scoped_refptr<storage::MockQuotaManagerProxy> quota_manager_proxy_;
scoped_refptr<FileSystemContext> file_system_context_;
std::map<base::FilePath, base::FilePath> toplevel_root_map_;
std::unique_ptr<DraggedFileUtil> file_util_;
diff --git a/chromium/storage/browser/file_system/file_system_context.cc b/chromium/storage/browser/file_system/file_system_context.cc
index 7ec5dc2f0e9..ed0dedf339d 100644
--- a/chromium/storage/browser/file_system/file_system_context.cc
+++ b/chromium/storage/browser/file_system/file_system_context.cc
@@ -125,7 +125,6 @@ int FileSystemContext::GetPermissionPolicy(FileSystemType type) {
// don't have their own permission policies.
case kFileSystemTypeDragged:
case kFileSystemTypeForTransientFile:
- case kFileSystemTypePluginPrivate:
return FILE_PERMISSION_ALWAYS_DENY;
// Following types only appear as mount_type, and will not be
@@ -205,12 +204,6 @@ FileSystemContext::FileSystemContext(
env_override_.get())),
sandbox_backend_(
std::make_unique<SandboxFileSystemBackend>(sandbox_delegate_.get())),
- plugin_private_backend_(std::make_unique<PluginPrivateFileSystemBackend>(
- default_file_task_runner_,
- partition_path,
- std::move(special_storage_policy),
- options,
- env_override_.get())),
additional_backends_(std::move(additional_backends)),
auto_mount_handlers_(auto_mount_handlers),
external_mount_points_(std::move(external_mount_points)),
@@ -223,7 +216,6 @@ FileSystemContext::FileSystemContext(
std::make_unique<mojo::Receiver<mojom::QuotaClient>>(
quota_client_wrapper_.get())) {
RegisterBackend(sandbox_backend_.get());
- RegisterBackend(plugin_private_backend_.get());
for (const auto& backend : additional_backends_)
RegisterBackend(backend.get());
@@ -242,7 +234,6 @@ FileSystemContext::FileSystemContext(
void FileSystemContext::Initialize() {
sandbox_backend_->Initialize(this);
isolated_backend_->Initialize(this);
- plugin_private_backend_->Initialize(this);
for (const auto& backend : additional_backends_)
backend->Initialize(this);
@@ -646,18 +637,6 @@ bool FileSystemContext::CanServeURLRequest(const FileSystemURL& url) const {
return !is_incognito_ || !FileSystemContext::IsSandboxFileSystem(url.type());
}
-void FileSystemContext::OpenPluginPrivateFileSystem(
- const url::Origin& origin,
- FileSystemType type,
- const std::string& filesystem_id,
- const std::string& plugin_id,
- OpenFileSystemMode mode,
- StatusCallback callback) {
- DCHECK(plugin_private_backend_);
- plugin_private_backend_->OpenPrivateFileSystem(
- origin, type, filesystem_id, plugin_id, mode, std::move(callback));
-}
-
FileSystemContext::~FileSystemContext() {
// TODO(crbug.com/823854) This is a leak. Delete env after the backends have
// been deleted.
@@ -676,7 +655,7 @@ FileSystemContext::QuotaManagedStorageTypes() {
// to call GetQuotaUtil() on backends. Unfortunately, the method assumes the
// backends are initialized.
if (storage_type == blink::mojom::StorageType::kUnknown ||
- storage_type == blink::mojom::StorageType::kQuotaNotManaged) {
+ storage_type == blink::mojom::StorageType::kDeprecatedQuotaNotManaged) {
continue;
}
diff --git a/chromium/storage/browser/file_system/file_system_context.h b/chromium/storage/browser/file_system/file_system_context.h
index cf2d5325392..cc80a12b0a1 100644
--- a/chromium/storage/browser/file_system/file_system_context.h
+++ b/chromium/storage/browser/file_system/file_system_context.h
@@ -28,7 +28,6 @@
#include "storage/browser/file_system/file_system_request_info.h"
#include "storage/browser/file_system/file_system_url.h"
#include "storage/browser/file_system/open_file_system_mode.h"
-#include "storage/browser/file_system/plugin_private_file_system_backend.h"
#include "storage/browser/file_system/sandbox_file_system_backend_delegate.h"
#include "storage/browser/file_system/task_runner_bound_observer_list.h"
#include "storage/common/file_system/file_system_types.h"
@@ -230,7 +229,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemContext
const base::FilePath& file_path,
ResolvedEntryType type)>;
- // Used for DeleteFileSystem and OpenPluginPrivateFileSystem.
+ // Used for DeleteFileSystem.
using StatusCallback = base::OnceCallback<void(base::File::Error result)>;
// Opens the filesystem for the given `storage_key` and `type`, and dispatches
@@ -334,27 +333,8 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemContext
// (E.g. this returns false if the context is created for incognito mode)
bool CanServeURLRequest(const FileSystemURL& url) const;
- // 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,
- const std::string& plugin_id,
- OpenFileSystemMode mode,
- StatusCallback callback);
-
bool is_incognito() { return is_incognito_; }
- // TODO(com/1231162): Remove this. Used only by test code and to migrate media
- // license data to the new backend.
- PluginPrivateFileSystemBackend* plugin_private_backend() const {
- return plugin_private_backend_.get();
- }
-
void ResolveURLOnOpenFileSystemForTesting(
const blink::StorageKey& storage_key,
const absl::optional<storage::BucketLocator>& bucket,
@@ -372,9 +352,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemContext
// For sandbox_backend().
friend class SandboxFileSystemTestHelper;
- // For plugin_private_backend().
- friend class PluginPrivateFileSystemBackendTest;
-
// Deleters.
friend class base::DeleteHelper<FileSystemContext>;
friend class base::RefCountedDeleteOnSequence<FileSystemContext>;
@@ -464,7 +441,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemContext
std::unique_ptr<IsolatedFileSystemBackend> isolated_backend_;
// Additional file system backends.
- const std::unique_ptr<PluginPrivateFileSystemBackend> plugin_private_backend_;
const std::vector<std::unique_ptr<FileSystemBackend>> additional_backends_;
std::vector<URLRequestAutoMountHandler> auto_mount_handlers_;
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 ed25bd361ad..ea97c810220 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
@@ -239,8 +239,7 @@ class FileSystemOperationImplTest : public testing::Test {
void GetUsageAndQuota(int64_t* usage, int64_t* quota) {
blink::mojom::QuotaStatusCode status =
AsyncFileTestHelper::GetUsageAndQuota(
- quota_manager_->proxy(),
- sandbox_file_system_.storage_key().origin(),
+ quota_manager_->proxy(), sandbox_file_system_.storage_key(),
sandbox_file_system_.type(), usage, quota);
task_environment_.RunUntilIdle();
ASSERT_EQ(blink::mojom::QuotaStatusCode::kOk, status);
diff --git a/chromium/storage/browser/file_system/file_system_operation_impl_write_unittest.cc b/chromium/storage/browser/file_system/file_system_operation_impl_write_unittest.cc
index 4bff94324f5..bf75e8b9cf6 100644
--- a/chromium/storage/browser/file_system/file_system_operation_impl_write_unittest.cc
+++ b/chromium/storage/browser/file_system/file_system_operation_impl_write_unittest.cc
@@ -14,6 +14,7 @@
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "base/test/task_environment.h"
+#include "base/test/test_future.h"
#include "base/threading/thread_task_runner_handle.h"
#include "net/url_request/url_request.h"
#include "storage/browser/blob/blob_storage_context.h"
@@ -43,10 +44,6 @@ namespace {
const char kOrigin[] = "http://example.com";
const FileSystemType kFileSystemType = kFileSystemTypeTest;
-void AssertStatusEq(base::File::Error expected, base::File::Error actual) {
- ASSERT_EQ(expected, actual);
-}
-
} // namespace
class FileSystemOperationImplWriteTest : public testing::Test {
@@ -79,9 +76,10 @@ class FileSystemOperationImplWriteTest : public testing::Test {
quota_manager_->proxy(), data_dir_.GetPath());
blob_storage_context_ = std::make_unique<BlobStorageContext>();
+ base::test::TestFuture<base::File::Error> future;
file_system_context_->operation_runner()->CreateFile(
- URLForPath(virtual_path_), true /* exclusive */,
- base::BindOnce(&AssertStatusEq, base::File::FILE_OK));
+ URLForPath(virtual_path_), true /* exclusive */, future.GetCallback());
+ ASSERT_EQ(base::File::FILE_OK, future.Get());
static_cast<TestFileSystemBackend*>(
file_system_context_->GetFileSystemBackend(kFileSystemType))
@@ -233,9 +231,12 @@ TEST_F(FileSystemOperationImplWriteTest, TestWriteInvalidFile) {
TEST_F(FileSystemOperationImplWriteTest, TestWriteDir) {
base::FilePath virtual_dir_path(FILE_PATH_LITERAL("d"));
+
+ base::test::TestFuture<base::File::Error> future;
file_system_context_->operation_runner()->CreateDirectory(
URLForPath(virtual_dir_path), true /* exclusive */, false /* recursive */,
- base::BindOnce(&AssertStatusEq, base::File::FILE_OK));
+ future.GetCallback());
+ ASSERT_EQ(base::File::FILE_OK, future.Get());
ScopedTextBlob blob(blob_storage_context(), "blob:writedir",
"It\'ll not be written, too.");
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 fa2ad05238f..95da4364f7a 100644
--- a/chromium/storage/browser/file_system/file_system_quota_client.cc
+++ b/chromium/storage/browser/file_system/file_system_quota_client.cc
@@ -14,7 +14,6 @@
#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"
@@ -64,8 +63,7 @@ base::span<const FileSystemType> QuotaStorageTypeToFileSystemTypes(
blink::mojom::StorageType storage_type) {
using StorageType = blink::mojom::StorageType;
- if (base::FeatureList::IsEnabled(
- blink::features::kPersistentQuotaIsTemporaryQuota)) {
+ if (blink::features::IsPersistentQuotaIsTemporaryQuota()) {
DCHECK_NE(storage_type, StorageType::kPersistent);
if (storage_type == StorageType::kTemporary)
return kTemporaryAndPersistent;
@@ -77,7 +75,7 @@ base::span<const FileSystemType> QuotaStorageTypeToFileSystemTypes(
return kPersistent;
case StorageType::kSyncable:
return kSyncable;
- case StorageType::kQuotaNotManaged:
+ case StorageType::kDeprecatedQuotaNotManaged:
case StorageType::kUnknown:
NOTREACHED();
return {};
@@ -93,16 +91,16 @@ std::vector<blink::StorageKey> GetStorageKeysForTypeOnFileTaskRunner(
return quota_util->GetStorageKeysForTypeOnFileTaskRunner(type);
}
-blink::mojom::QuotaStatusCode DeleteStorageKeyOnFileTaskRunner(
+blink::mojom::QuotaStatusCode DeleteBucketOnFileTaskRunner(
FileSystemContext* context,
- const blink::StorageKey& storage_key,
+ const BucketLocator& bucket_locator,
FileSystemType type) {
FileSystemBackend* provider = context->GetFileSystemBackend(type);
if (!provider || !provider->GetQuotaUtil())
return blink::mojom::QuotaStatusCode::kErrorNotSupported;
base::File::Error result =
- provider->GetQuotaUtil()->DeleteStorageKeyDataOnFileTaskRunner(
- context, context->quota_manager_proxy().get(), storage_key, type);
+ provider->GetQuotaUtil()->DeleteBucketDataOnFileTaskRunner(
+ context, context->quota_manager_proxy().get(), bucket_locator, type);
if (result == base::File::FILE_OK)
return blink::mojom::QuotaStatusCode::kOk;
return blink::mojom::QuotaStatusCode::kErrorInvalidModification;
@@ -135,14 +133,6 @@ void FileSystemQuotaClient::GetBucketUsage(const BucketLocator& bucket,
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!callback.is_null());
- // Skip non-default buckets until Storage Buckets are supported for
- // FileSystem.
- // TODO(crbug.com/1218100): Integrate with StorageBuckets.
- if (!bucket.is_default) {
- std::move(callback).Run(0);
- return;
- }
-
base::span<const FileSystemType> types =
QuotaStorageTypeToFileSystemTypes(bucket.type);
@@ -159,11 +149,10 @@ void FileSystemQuotaClient::GetBucketUsage(const BucketLocator& bucket,
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_.get()), bucket.storage_key,
- type),
+ base::BindOnce(&FileSystemQuotaUtil::GetBucketUsageOnFileTaskRunner,
+ base::Unretained(quota_util),
+ base::RetainedRef(file_system_context_.get()), bucket,
+ type),
barrier);
} else {
barrier.Run(0);
@@ -201,14 +190,6 @@ void FileSystemQuotaClient::DeleteBucketData(
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!callback.is_null());
- // Skip non-default buckets until Storage Buckets are supported for
- // FileSystem.
- // TODO(crbug.com/1218100): Integrate with StorageBuckets.
- if (!bucket.is_default) {
- std::move(callback).Run(blink::mojom::QuotaStatusCode::kOk);
- return;
- }
-
base::span<const FileSystemType> fs_types =
QuotaStorageTypeToFileSystemTypes(bucket.type);
@@ -227,9 +208,9 @@ void FileSystemQuotaClient::DeleteBucketData(
for (const auto fs_type : fs_types) {
file_task_runner()->PostTaskAndReplyWithResult(
FROM_HERE,
- base::BindOnce(&DeleteStorageKeyOnFileTaskRunner,
- base::RetainedRef(file_system_context_.get()),
- bucket.storage_key, fs_type),
+ base::BindOnce(&DeleteBucketOnFileTaskRunner,
+ base::RetainedRef(file_system_context_.get()), bucket,
+ fs_type),
barrier);
}
}
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 407f5daef9a..f29c9f5ebde 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
@@ -550,9 +550,6 @@ TEST_P(FileSystemQuotaClientTest, DeleteOriginTest) {
const int64_t file_paths_cost_temporary_foo_https =
ComputeFilePathsCostForOriginAndType(kFiles, "https://foo.com/",
kFileSystemTypeTemporary);
- const int64_t file_paths_cost_persistent_foo =
- ComputeFilePathsCostForOriginAndType(kFiles, "http://foo.com/",
- kFileSystemTypePersistent);
const int64_t file_paths_cost_temporary_bar =
ComputeFilePathsCostForOriginAndType(kFiles, "http://bar.com/",
kFileSystemTypeTemporary);
@@ -603,22 +600,6 @@ TEST_P(FileSystemQuotaClientTest, DeleteOriginTest) {
? 32 + file_paths_cost_persistent_bar_https
: 0),
GetBucketUsage(quota_client, bar_https_temp_bucket));
-
- if (!persistent_quota_is_temporary_quota()) {
- auto bar_perm_bucket =
- GetBucket("http://bar.com/", kDefaultBucketName, kPersistent);
- EXPECT_EQ(0, GetBucketUsage(quota_client, bar_perm_bucket));
-
- auto foo_perm_bucket =
- GetBucket("http://foo.com/", kDefaultBucketName, kPersistent);
- EXPECT_EQ(4 + file_paths_cost_persistent_foo,
- GetBucketUsage(quota_client, foo_perm_bucket));
-
- auto bar_https_perm_bucket =
- GetBucket("https://bar.com/", kDefaultBucketName, kPersistent);
- EXPECT_EQ(32 + file_paths_cost_persistent_bar_https,
- GetBucketUsage(quota_client, bar_https_perm_bucket));
- }
}
INSTANTIATE_TEST_SUITE_P(FileSystemQuotaClientTests,
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 dd34c1e1ee0..89d8f31843c 100644
--- a/chromium/storage/browser/file_system/file_system_quota_util.h
+++ b/chromium/storage/browser/file_system/file_system_quota_util.h
@@ -20,6 +20,7 @@ class StorageKey;
namespace storage {
+struct BucketLocator;
class FileSystemContext;
class QuotaManagerProxy;
class QuotaReservation;
@@ -32,7 +33,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemQuotaUtil {
public:
virtual ~FileSystemQuotaUtil() = default;
- // Deletes the data on the origin and reports the amount of deleted data
+ // Deletes the data on the StorageKey and reports the amount of deleted data
// to the quota manager via |proxy|.
virtual base::File::Error DeleteStorageKeyDataOnFileTaskRunner(
FileSystemContext* context,
@@ -40,6 +41,14 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemQuotaUtil {
const blink::StorageKey& storage_key,
FileSystemType type) = 0;
+ // Deletes the data on the bucket and reports the amount of deleted data
+ // to the quota manager via |proxy|.
+ virtual base::File::Error DeleteBucketDataOnFileTaskRunner(
+ FileSystemContext* context,
+ QuotaManagerProxy* proxy,
+ const BucketLocator& bucket_locator,
+ FileSystemType type) = 0;
+
virtual void PerformStorageCleanupOnFileTaskRunner(FileSystemContext* context,
QuotaManagerProxy* proxy,
FileSystemType type) = 0;
@@ -53,6 +62,13 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemQuotaUtil {
const blink::StorageKey& storage_key,
FileSystemType type) = 0;
+ // Returns the amount of data used for the `bucket_locator` for usage
+ // tracking.
+ virtual int64_t GetBucketUsageOnFileTaskRunner(
+ FileSystemContext* file_system_context,
+ const BucketLocator& bucket_locator,
+ FileSystemType type) = 0;
+
// Creates new reservation object for the `storage_key` and the `type`.
virtual scoped_refptr<QuotaReservation>
CreateQuotaReservationOnFileTaskRunner(const blink::StorageKey& storage_key,
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 5b165353f01..515b1a2ad7f 100644
--- a/chromium/storage/browser/file_system/file_system_usage_cache.cc
+++ b/chromium/storage/browser/file_system/file_system_usage_cache.cc
@@ -36,7 +36,7 @@ FileSystemUsageCache::~FileSystemUsageCache() {
const base::FilePath::CharType FileSystemUsageCache::kUsageFileName[] =
FILE_PATH_LITERAL(".usage");
const char FileSystemUsageCache::kUsageFileHeader[] = "FSU5";
-const int FileSystemUsageCache::kUsageFileHeaderSize = 4;
+const size_t FileSystemUsageCache::kUsageFileHeaderSize = 4;
// Pickle::{Read,Write}Bool treat bool as int
const int FileSystemUsageCache::kUsageFileSize =
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 ef048677824..75bdd0f740b 100644
--- a/chromium/storage/browser/file_system/file_system_usage_cache.h
+++ b/chromium/storage/browser/file_system/file_system_usage_cache.h
@@ -61,7 +61,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemUsageCache {
static const base::FilePath::CharType kUsageFileName[];
static const char kUsageFileHeader[];
static const int kUsageFileSize;
- static const int kUsageFileHeaderSize;
+ static const size_t kUsageFileHeaderSize;
private:
// Read the size, validity and the "dirty" entry described in the .usage file.
diff --git a/chromium/storage/browser/file_system/file_system_util.cc b/chromium/storage/browser/file_system/file_system_util.cc
index a32a53f2676..450fbf32115 100644
--- a/chromium/storage/browser/file_system/file_system_util.cc
+++ b/chromium/storage/browser/file_system/file_system_util.cc
@@ -4,7 +4,6 @@
#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"
@@ -13,8 +12,7 @@ namespace storage {
blink::mojom::StorageType FileSystemTypeToQuotaStorageType(
FileSystemType type) {
- if (base::FeatureList::IsEnabled(
- blink::features::kPersistentQuotaIsTemporaryQuota) &&
+ if (blink::features::IsPersistentQuotaIsTemporaryQuota() &&
(type == kFileSystemTypeTemporary || type == kFileSystemTypePersistent)) {
return blink::mojom::StorageType::kTemporary;
}
@@ -26,8 +24,6 @@ blink::mojom::StorageType FileSystemTypeToQuotaStorageType(
case kFileSystemTypeSyncable:
case kFileSystemTypeSyncableForInternalSync:
return blink::mojom::StorageType::kSyncable;
- case kFileSystemTypePluginPrivate:
- return blink::mojom::StorageType::kQuotaNotManaged;
default:
return blink::mojom::StorageType::kUnknown;
}
diff --git a/chromium/storage/browser/file_system/obfuscated_file_util.cc b/chromium/storage/browser/file_system/obfuscated_file_util.cc
index f3463199d34..b238431f5fa 100644
--- a/chromium/storage/browser/file_system/obfuscated_file_util.cc
+++ b/chromium/storage/browser/file_system/obfuscated_file_util.cc
@@ -29,6 +29,7 @@
#include "storage/browser/file_system/file_observers.h"
#include "storage/browser/file_system/file_system_context.h"
#include "storage/browser/file_system/file_system_operation_context.h"
+#include "storage/browser/file_system/file_system_util.h"
#include "storage/browser/file_system/obfuscated_file_util_disk_delegate.h"
#include "storage/browser/file_system/obfuscated_file_util_memory_delegate.h"
#include "storage/browser/file_system/quota/quota_limit_type.h"
@@ -74,8 +75,6 @@ const int64_t kPathCreationQuotaCost = 146; // Bytes per inode, basically.
const int64_t kPathByteQuotaCost =
2; // Bytes per byte of path length in UTF-8.
-const char kDirectoryDatabaseKeySeparator = ' ';
-
int64_t UsageForPath(size_t length) {
return kPathCreationQuotaCost +
static_cast<int64_t>(length) * kPathByteQuotaCost;
@@ -113,15 +112,41 @@ 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.
+// Implementing the DatabaseKey for the directories_ map.
+DatabaseKey::DatabaseKey() = default;
+DatabaseKey::~DatabaseKey() = default;
+
+// Copyable and moveable
+DatabaseKey::DatabaseKey(const DatabaseKey& other) = default;
+DatabaseKey& DatabaseKey::operator=(const DatabaseKey& other) = default;
+DatabaseKey::DatabaseKey(DatabaseKey&& other) = default;
+DatabaseKey& DatabaseKey::operator=(DatabaseKey&& other) = default;
+
+DatabaseKey::DatabaseKey(const blink::StorageKey& storage_key,
+ const absl::optional<BucketLocator>& bucket,
+ const std::string& type) {
+ storage_key_ = storage_key;
+ bucket_ = bucket;
+ type_ = type;
+}
+
+bool DatabaseKey::operator==(const DatabaseKey& other) const {
+ return std::tie(storage_key_, bucket_, type_) ==
+ std::tie(other.storage_key_, other.bucket_, other.type_);
+}
+
+bool DatabaseKey::operator!=(const DatabaseKey& other) const {
+ return std::tie(storage_key_, bucket_, type_) !=
+ std::tie(other.storage_key_, other.bucket_, other.type_);
+}
+
+bool DatabaseKey::operator<(const DatabaseKey& other) const {
+ return std::tie(storage_key_, bucket_, type_) <
+ std::tie(other.storage_key_, other.bucket_, other.type_);
+}
+
+// end DatabaseKey implementation.
+
class ObfuscatedFileEnumerator final
: public FileSystemFileUtil::AbstractFileEnumerator {
public:
@@ -206,7 +231,8 @@ class ObfuscatedFileEnumerator final
}
raw_ptr<SandboxDirectoryDatabase> db_;
- raw_ptr<FileSystemOperationContext> context_;
+ // TODO(crbug.com/1298696): Breaks storage_unittests.
+ raw_ptr<FileSystemOperationContext, DegradeToNoOpWhenMTE> context_;
raw_ptr<ObfuscatedFileUtil> obfuscated_file_util_;
FileSystemURL root_url_;
bool recursive_;
@@ -219,6 +245,14 @@ class ObfuscatedFileEnumerator final
base::File::Info current_platform_file_info_;
};
+// NOTE: currently, ObfuscatedFileUtil still relies on SandboxOriginDatabases
+// for first-party StorageKeys/default buckets. The AbstractStorageKeyEnumerator
+// class is only used in these cases. While this class stores and iterates
+// through StorageKeys types, it works by retrieving OriginRecords from the
+// SandboxOriginDatabase and converting those origins into first-party
+// StorageKey values (e.g. blink::StorageKey(origin)). The goal is to eventually
+// deprecate SandboxOriginDatabases and AbstractStorageKeyEnumerators and rely
+// entirely on Storage Buckets.
class ObfuscatedStorageKeyEnumerator
: public ObfuscatedFileUtil::AbstractStorageKeyEnumerator {
public:
@@ -272,30 +306,34 @@ class ObfuscatedStorageKeyEnumerator
base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util_;
};
+const base::FilePath::CharType ObfuscatedFileUtil::kFileSystemDirectory[] =
+ FILE_PATH_LITERAL("File System");
+
ObfuscatedFileUtil::ObfuscatedFileUtil(
scoped_refptr<SpecialStoragePolicy> special_storage_policy,
- const base::FilePath& file_system_directory,
+ const base::FilePath& profile_path,
leveldb::Env* env_override,
- GetTypeStringForURLCallback get_type_string_for_url,
const std::set<std::string>& known_type_strings,
SandboxFileSystemBackendDelegate* sandbox_delegate,
bool is_incognito)
: special_storage_policy_(std::move(special_storage_policy)),
- file_system_directory_(file_system_directory),
env_override_(env_override),
is_incognito_(is_incognito),
db_flush_delay_seconds_(10 * 60), // 10 mins.
- get_type_string_for_url_(std::move(get_type_string_for_url)),
known_type_strings_(known_type_strings),
sandbox_delegate_(sandbox_delegate) {
- DCHECK(!get_type_string_for_url_.is_null());
DETACH_FROM_SEQUENCE(sequence_checker_);
DCHECK(!is_incognito_ ||
(env_override && leveldb_chrome::IsMemEnv(env_override)));
+ file_system_directory_ = profile_path.Append(kFileSystemDirectory);
if (is_incognito_) {
- delegate_ = std::make_unique<ObfuscatedFileUtilMemoryDelegate>(
- file_system_directory_);
+ // profile_path is passed here, so that the delegate is able to accommodate
+ // both codepaths of {{profile_path}}/File System (first-party) and
+ // {{profile_path}}/WebStorage (buckets-based).
+ // See https://crrev.com/c/3817542 for more context.
+ delegate_ =
+ std::make_unique<ObfuscatedFileUtilMemoryDelegate>(profile_path);
} else {
delegate_ = std::make_unique<ObfuscatedFileUtilDiskDelegate>();
}
@@ -867,19 +905,15 @@ bool ObfuscatedFileUtil::IsDirectoryEmpty(FileSystemOperationContext* context,
}
base::FileErrorOr<base::FilePath>
-ObfuscatedFileUtil::GetDirectoryForBucketAndType(const BucketLocator& bucket,
- const std::string& type_string,
- bool create) {
+ObfuscatedFileUtil::GetDirectoryForBucketAndType(
+ const BucketLocator& bucket,
+ const absl::optional<FileSystemType>& type,
+ bool create) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// A default bucket in a first-party context uses
// GetDirectoryForStorageKeyAndType() to determine its file path.
if (bucket.storage_key.IsFirstPartyContext() && bucket.is_default) {
- base::File::Error error = base::File::FILE_OK;
- base::FilePath path = GetDirectoryForStorageKeyAndType(
- bucket.storage_key, type_string, create, &error);
- if (error != base::File::FILE_OK)
- return error;
- return path;
+ return GetDirectoryForStorageKeyAndType(bucket.storage_key, type, create);
}
// All other contexts use the provided bucket information to construct the
// file path.
@@ -887,63 +921,64 @@ ObfuscatedFileUtil::GetDirectoryForBucketAndType(const BucketLocator& bucket,
sandbox_delegate_->quota_manager_proxy()->GetClientBucketPath(
bucket, QuotaClientType::kFileSystem);
// Append the file system type and verify the path is valid.
- path = path.AppendASCII(type_string);
+ if (type) {
+ path = path.AppendASCII(
+ SandboxFileSystemBackendDelegate::GetTypeString(type.value()));
+ }
base::File::Error error = GetDirectoryHelper(path, create);
if (error != base::File::FILE_OK)
return error;
return path;
}
-// TODO(https://crbug.com/1310361): refactor GetDirectoryForStorageKeyAndType
-// and its callers to return a base::FileErrorOr<base::FilePath>.
-base::FilePath ObfuscatedFileUtil::GetDirectoryForStorageKeyAndType(
+base::FileErrorOr<base::FilePath>
+ObfuscatedFileUtil::GetDirectoryForStorageKeyAndType(
const blink::StorageKey& storage_key,
- const std::string& type_string,
- bool create,
- base::File::Error* error_code) {
+ const absl::optional<FileSystemType>& type,
+ bool create) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- base::FileErrorOr<base::FilePath> origin_dir =
+ base::FileErrorOr<base::FilePath> dir =
GetDirectoryForStorageKey(storage_key, create);
- if (origin_dir.is_error()) {
- *error_code = origin_dir.error();
- return base::FilePath();
+ if (dir.is_error()) {
+ return dir;
}
- if (origin_dir->empty()) {
- *error_code = base::File::FILE_OK;
- return base::FilePath();
- }
- if (type_string.empty()) {
- *error_code = base::File::FILE_OK;
- return origin_dir.value();
+ DCHECK(!dir->empty());
+ if (!type) {
+ return dir;
}
// Append the file system type and verify the path is valid.
- base::FilePath path = origin_dir->AppendASCII(type_string);
+ base::FilePath path = dir.value();
+ if (type) {
+ path = path.AppendASCII(
+ SandboxFileSystemBackendDelegate::GetTypeString(type.value()));
+ }
base::File::Error error = GetDirectoryHelper(path, create);
- if (error_code)
- *error_code = error;
+ if (error != base::File::FILE_OK)
+ return error;
return path;
}
bool ObfuscatedFileUtil::DeleteDirectoryForStorageKeyAndType(
const blink::StorageKey& storage_key,
- const std::string& type_string) {
+ const absl::optional<FileSystemType>& type) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DestroyDirectoryDatabase(storage_key, type_string);
+ DestroyDirectoryDatabaseForStorageKey(storage_key, type);
base::FileErrorOr<base::FilePath> origin_path =
GetDirectoryForStorageKey(storage_key, false);
if (origin_path.is_error() || origin_path->empty())
return true;
- if (!type_string.empty()) {
+ if (type) {
// Delete the filesystem type directory.
- base::File::Error error = base::File::FILE_OK;
- const base::FilePath origin_type_path = GetDirectoryForStorageKeyAndType(
- storage_key, type_string, false, &error);
- if (error == base::File::FILE_ERROR_FAILED)
+ const base::FileErrorOr<base::FilePath> origin_type_path =
+ GetDirectoryForStorageKeyAndType(storage_key, type.value(), false);
+ if (origin_type_path.is_error() &&
+ origin_type_path.error() == base::File::FILE_ERROR_FAILED) {
return false;
- if (error == base::File::FILE_OK && !origin_type_path.empty() &&
- !delegate_->DeleteFileOrDirectory(origin_type_path,
+ }
+ if (!origin_type_path.is_error() && !origin_type_path->empty() &&
+ !delegate_->DeleteFileOrDirectory(origin_type_path.value(),
true /* recursive */)) {
return false;
}
@@ -951,10 +986,12 @@ bool ObfuscatedFileUtil::DeleteDirectoryForStorageKeyAndType(
// At this point we are sure we had successfully deleted the origin/type
// directory (i.e. we're ready to just return true).
// See if we have other directories in this origin directory.
- for (const std::string& type : known_type_strings_) {
- if (type == type_string)
+ const std::string type_string =
+ SandboxFileSystemBackendDelegate::GetTypeString(type.value());
+ for (const std::string& known_type : known_type_strings_) {
+ if (known_type == type_string)
continue;
- if (delegate_->DirectoryExists(origin_path->AppendASCII(type))) {
+ if (delegate_->DirectoryExists(origin_path->AppendASCII(known_type))) {
// Other type's directory exists; just return true here.
return true;
}
@@ -974,21 +1011,56 @@ bool ObfuscatedFileUtil::DeleteDirectoryForStorageKeyAndType(
true /* recursive */);
}
-void ObfuscatedFileUtil::CloseFileSystemForStorageKeyAndType(
- const blink::StorageKey& storage_key,
- const std::string& type_string) {
+bool ObfuscatedFileUtil::DeleteDirectoryForBucketAndType(
+ const BucketLocator& bucket_locator,
+ const absl::optional<FileSystemType>& type) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (bucket_locator.is_default &&
+ bucket_locator.storage_key.IsFirstPartyContext())
+ return DeleteDirectoryForStorageKeyAndType(bucket_locator.storage_key,
+ type);
- 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,
- base::CompareCase::SENSITIVE))
- break;
- DCHECK(type_string.empty() || iter->first == key_prefix);
- directories_.erase(iter++);
+ DestroyDirectoryDatabaseForBucket(bucket_locator, type);
+
+ // Get the base path for the bucket without the type string appended.
+ base::FilePath path =
+ sandbox_delegate_->quota_manager_proxy()->GetClientBucketPath(
+ bucket_locator, QuotaClientType::kFileSystem);
+ base::File::Error error = GetDirectoryHelper(path, /*create=*/false);
+ if (error != base::File::FILE_OK || path.empty())
+ return true;
+
+ if (type) {
+ // Delete the filesystem type directory.
+ const base::FileErrorOr<base::FilePath> path_with_type =
+ GetDirectoryForBucketAndType(bucket_locator, type.value(), false);
+ if (path_with_type.is_error())
+ return false;
+ if (!path_with_type->empty() &&
+ !delegate_->DeleteFileOrDirectory(path_with_type.value(),
+ true /* recursive */)) {
+ return false;
+ }
+
+ // At this point we are sure we had successfully deleted the bucket/type
+ // directory. Now we need to see if we have other sub-type-directories under
+ // the higher-level `path` directory. If so, we need to return early to
+ // avoid deleting the higher-level `path` directory.
+ const std::string type_string =
+ SandboxFileSystemBackendDelegate::GetTypeString(type.value());
+ for (const std::string& known_type : known_type_strings_) {
+ if (known_type == type_string)
+ continue;
+ if (delegate_->DirectoryExists(path.AppendASCII(known_type))) {
+ // Other type's directory exists; return to avoid deleting the higher
+ // level directory.
+ return true;
+ }
+ }
}
+
+ // Delete the higher-level directory.
+ return delegate_->DeleteFileOrDirectory(path, true /* recursive */);
}
std::unique_ptr<ObfuscatedFileUtil::AbstractStorageKeyEnumerator>
@@ -1006,27 +1078,67 @@ ObfuscatedFileUtil::CreateStorageKeyEnumerator() {
origin_database_.get(), file_util_delegate, file_system_directory_);
}
-void ObfuscatedFileUtil::DestroyDirectoryDatabase(
+void ObfuscatedFileUtil::DestroyDirectoryDatabaseForStorageKey(
const blink::StorageKey& storage_key,
- const std::string& type_string) {
+ const absl::optional<FileSystemType>& type) {
+ DestroyDirectoryDatabaseHelper(absl::nullopt, storage_key, type);
+}
+
+void ObfuscatedFileUtil::DestroyDirectoryDatabaseForBucket(
+ const BucketLocator& bucket_locator,
+ const absl::optional<FileSystemType>& type) {
+ DestroyDirectoryDatabaseHelper(bucket_locator, bucket_locator.storage_key,
+ type);
+}
+
+void ObfuscatedFileUtil::DestroyDirectoryDatabaseHelper(
+ const absl::optional<BucketLocator>& bucket_locator,
+ const blink::StorageKey& storage_key,
+ const absl::optional<FileSystemType>& type) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- // If `type_string` is empty, delete all filesystem types under `storage_key`.
- const std::string key_prefix =
- GetDirectoryDatabaseKey(storage_key, type_string);
+ DatabaseKey key_prefix;
+ const std::string type_string =
+ type ? SandboxFileSystemBackendDelegate::GetTypeString(type.value())
+ : std::string();
+ // `key.bucket()` is absl::nullopt for all non-kTemporary types.
+ if (type && (FileSystemTypeToQuotaStorageType(type.value()) ==
+ ::blink::mojom::StorageType::kTemporary)) {
+ if (bucket_locator.has_value()) {
+ key_prefix =
+ DatabaseKey(bucket_locator->storage_key, bucket_locator, type_string);
+ } else {
+ // If we are not provided a custom bucket value we must find the default
+ // bucket corresponding to the StorageKey.
+ QuotaErrorOr<BucketLocator> default_bucket =
+ GetOrCreateDefaultBucket(storage_key);
+ // If there is no default bucket for a given StorageKey, there is not a
+ // valid FileSystem to close, so we return.
+ if (!default_bucket.ok())
+ return;
+ key_prefix =
+ DatabaseKey(storage_key, default_bucket.value(), type_string);
+ }
+ } else { // All other storage types.
+ key_prefix = DatabaseKey(storage_key, absl::nullopt, type_string);
+ }
+
+ // If `type` is empty, delete all filesystem types under `storage_key`.
for (auto iter = directories_.lower_bound(key_prefix);
iter != directories_.end();) {
- if (!base::StartsWith(iter->first, key_prefix,
- base::CompareCase::SENSITIVE))
+ // If the key matches exactly or `type` is absl::nullopt and just the
+ // StorageKey and BucketLocator match exactly, delete the database.
+ if (iter->first == key_prefix ||
+ (type == absl::nullopt &&
+ iter->first.storage_key() == key_prefix.storage_key() &&
+ iter->first.bucket() == key_prefix.bucket())) {
+ std::unique_ptr<SandboxDirectoryDatabase> database =
+ std::move(iter->second);
+ directories_.erase(iter++);
+ database->DestroyDatabase();
+ } else {
break;
- DCHECK(type_string.empty() || iter->first == key_prefix);
- std::unique_ptr<SandboxDirectoryDatabase> database =
- std::move(iter->second);
- directories_.erase(iter++);
-
- // Continue to destroy databases even if it failed because it doesn't affect
- // the final result.
- database->DestroyDatabase();
+ }
}
}
@@ -1041,24 +1153,38 @@ base::FileErrorOr<base::FilePath> ObfuscatedFileUtil::GetDirectoryForURL(
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!url.bucket().has_value()) {
// Access the SandboxDirectoryDatabase to construct the file path.
- // TODO(https://crbug.com/1310361): refactor GetDirectoryForStorageKey and
- // its related functions to return a base::FileErrorOr<base::FilePath>.
- base::File::Error error = base::File::FILE_OK;
- base::FilePath path = GetDirectoryForStorageKeyAndType(
- url.storage_key(), CallGetTypeStringForURL(url), create, &error);
- if (error != base::File::FILE_OK)
- return error;
- return path;
+ return GetDirectoryForStorageKeyAndType(url.storage_key(), url.type(),
+ create);
}
// Construct the file path using the provided bucket information.
- return GetDirectoryForBucketAndType(url.bucket().value(),
- CallGetTypeStringForURL(url), create);
+ return GetDirectoryForBucketAndType(url.bucket().value(), url.type(), create);
}
-std::string ObfuscatedFileUtil::CallGetTypeStringForURL(
- const FileSystemURL& url) {
- DCHECK(!get_type_string_for_url_.is_null());
- return get_type_string_for_url_.Run(url);
+QuotaErrorOr<BucketLocator> ObfuscatedFileUtil::GetOrCreateDefaultBucket(
+ const blink::StorageKey& storage_key) {
+ // If we have already looked up this default bucket for this StorageKey,
+ // return the cached value.
+ auto iter = default_buckets_.find(storage_key);
+ if (iter != default_buckets_.end()) {
+ return iter->second;
+ }
+ // GetOrCreateBucketSync() called below requires the use of the
+ // base::WaitableEvent sync primitive. We must explicitly declare the usage
+ // of this primitive to avoid thread restriction errors.
+ base::ScopedAllowBaseSyncPrimitives allow_wait;
+ // Instead of crashing, return a QuotaError if the proxy is a nullptr.
+ if (!sandbox_delegate_->quota_manager_proxy()) {
+ LOG(WARNING) << "Failed to GetOrCreateBucket: QuotaManagerProxy is null";
+ return QuotaError::kUnknownError;
+ }
+ // Retrieve or create the default bucket for this StorageKey.
+ QuotaErrorOr<BucketInfo> bucket =
+ sandbox_delegate_->quota_manager_proxy()->GetOrCreateBucketSync(
+ BucketInitParams::ForDefaultBucket(storage_key));
+ if (!bucket.ok())
+ return bucket.error();
+ default_buckets_[storage_key] = bucket->ToBucketLocator();
+ return bucket->ToBucketLocator();
}
base::File::Error ObfuscatedFileUtil::GetFileInfoInternal(
@@ -1230,14 +1356,6 @@ base::FilePath ObfuscatedFileUtil::DataPathToLocalPath(
return root.value().Append(data_path);
}
-std::string ObfuscatedFileUtil::GetDirectoryDatabaseKey(
- const blink::StorageKey& storage_key,
- const std::string& type_string) {
- // For isolated origin we just use a type string as a key.
- return GetIdentifierFromOrigin(storage_key.origin()) +
- kDirectoryDatabaseKeySeparator + type_string;
-}
-
// TODO(ericu): How to do the whole validation-without-creation thing?
// We may not have quota even to create the database.
// Ah, in that case don't even get here?
@@ -1247,10 +1365,26 @@ SandboxDirectoryDatabase* ObfuscatedFileUtil::GetDirectoryDatabase(
bool create) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- std::string key =
- GetDirectoryDatabaseKey(url.storage_key(), CallGetTypeStringForURL(url));
- if (key.empty())
- return nullptr;
+ DatabaseKey key;
+ const std::string type_string =
+ SandboxFileSystemBackendDelegate::GetTypeString(url.type());
+ // `key.bucket()` is absl::nullopt for all non-kTemporary types.
+ if (FileSystemTypeToQuotaStorageType(url.type()) ==
+ ::blink::mojom::StorageType::kTemporary) {
+ if (url.bucket().has_value()) {
+ key = DatabaseKey(url.storage_key(), url.bucket().value(), type_string);
+ } else {
+ // If we are not provided a custom bucket value we must find the default
+ // bucket corresponding to the url's StorageKey.
+ QuotaErrorOr<BucketLocator> default_bucket =
+ GetOrCreateDefaultBucket(url.storage_key());
+ if (!default_bucket.ok())
+ return nullptr;
+ key = DatabaseKey(url.storage_key(), default_bucket.value(), type_string);
+ }
+ } else { // All other storage types.
+ key = DatabaseKey(url.storage_key(), absl::nullopt, type_string);
+ }
auto iter = directories_.find(key);
if (iter != directories_.end()) {
@@ -1276,20 +1410,14 @@ base::FileErrorOr<base::FilePath> ObfuscatedFileUtil::GetDirectoryForStorageKey(
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (storage_key.IsThirdPartyContext()) {
- // GetOrCreateBucketSync() called below requires the use of the
- // base::WaitableEvent sync primitive. We must explicitly declare the usage
- // of this primitive to avoid thread restriction errors.
- base::ScopedAllowBaseSyncPrimitives allow_wait;
- // Retrieve the bucket information for third-party StorageKey.
- QuotaErrorOr<BucketInfo> bucket =
- sandbox_delegate_->quota_manager_proxy()->GetOrCreateBucketSync(
- BucketInitParams::ForDefaultBucket(storage_key));
+ // Retrieve the default bucket value for `storage_key`.
+ QuotaErrorOr<BucketLocator> bucket = GetOrCreateDefaultBucket(storage_key);
if (!bucket.ok())
return base::File::FILE_ERROR_FAILED;
// Get the path and verify it is valid.
base::FileErrorOr<base::FilePath> path =
sandbox_delegate_->quota_manager_proxy()->GetClientBucketPath(
- bucket->ToBucketLocator(), QuotaClientType::kFileSystem);
+ bucket.value(), QuotaClientType::kFileSystem);
if (path.is_error())
return path.error();
base::File::Error error = GetDirectoryHelper(path.value(), create);
@@ -1374,6 +1502,45 @@ void ObfuscatedFileUtil::RewriteDatabases() {
origin_database_->RewriteDatabase();
}
+void ObfuscatedFileUtil::DeleteDefaultBucketForStorageKey(
+ const blink::StorageKey& storage_key) {
+ auto default_bucket_iter = default_buckets_.find(storage_key);
+ // If we are not already caching the bucket for that StorageKey, it does not
+ // need to be deleted.
+ if (default_bucket_iter == default_buckets_.end())
+ return;
+ BucketLocator default_bucket = default_buckets_[storage_key];
+ // Ensure that all directories with that StorageKey and bucket have been
+ // erased.
+ DCHECK(directories_.find(
+ DatabaseKey(storage_key, default_bucket,
+ SandboxFileSystemBackendDelegate::GetTypeString(
+ FileSystemType::kFileSystemTypeTemporary))) ==
+ directories_.end());
+ default_buckets_.erase(default_bucket_iter);
+}
+
+void ObfuscatedFileUtil::DeleteDefaultBucket(
+ const BucketLocator& bucket_locator) {
+ blink::StorageKey storage_key = bucket_locator.storage_key;
+ auto default_bucket_iter = default_buckets_.find(storage_key);
+ // If we are not already caching the bucket for that StorageKey, it does not
+ // need to be deleted.
+ if (default_bucket_iter == default_buckets_.end())
+ return;
+ BucketLocator default_bucket = default_buckets_[storage_key];
+ // Ensure that `default_bucket` matches `bucket_locator`
+ DCHECK(default_bucket == bucket_locator);
+ // Ensure that all directories with that StorageKey and bucket have been
+ // erased.
+ DCHECK(directories_.find(
+ DatabaseKey(storage_key, default_bucket,
+ SandboxFileSystemBackendDelegate::GetTypeString(
+ FileSystemType::kFileSystemTypeTemporary))) ==
+ directories_.end());
+ default_buckets_.erase(default_bucket_iter);
+}
+
bool ObfuscatedFileUtil::InitOriginDatabase(const url::Origin& origin_hint,
bool create) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/chromium/storage/browser/file_system/obfuscated_file_util.h b/chromium/storage/browser/file_system/obfuscated_file_util.h
index 32bcb0ecec1..81187361e58 100644
--- a/chromium/storage/browser/file_system/obfuscated_file_util.h
+++ b/chromium/storage/browser/file_system/obfuscated_file_util.h
@@ -34,10 +34,6 @@ namespace blink {
class StorageKey;
} // namespace blink
-namespace url {
-class Origin;
-} // namespace url
-
namespace storage {
class FileSystemOperationContext;
@@ -46,20 +42,68 @@ class QuotaBackendImplTest;
class SandboxOriginDatabaseInterface;
class SpecialStoragePolicy;
-// This file util stores directory information in LevelDB to obfuscate
-// and to neutralize virtual file paths given by arbitrary apps.
-// Files are stored with two-level isolation: per-origin and per-type.
-// The isolation is done by storing data in separate directory partitions.
-// For example, a file in Temporary file system for origin 'www.example.com'
-// is stored in a different partition for a file in Persistent file system
-// for the same origin, or for Temporary file system for another origin.
+// Class representing the key for directories_. NOTE: The `bucket` value is
+// optional due to usage of ObfuscatedFileUtil where the type is not kTemporary
+// (i.e. kPersistent or kSyncable). For all non-temporary types, expect the
+// bucket member value to be absl::nullopt. The class is implemented as such to
+// avoid mapping the same StorageKey to potentially different bucket values,
+// which would cause directories_ lookup errors. NOTE: The `type_string` value
+// is empty when designating a "top-level directory" or a directory that
+// contains one or more subdirectories with a non-empty type. This class stores
+// a string rather than the FileSystemType itself because multiple
+// FileSystemTypes can map to the same `type_string`, and preserving this
+// behavior is necessary to retrieving and deleting ObfuscatedFilePaths
+// correctly.
+class DatabaseKey {
+ public:
+ DatabaseKey();
+ ~DatabaseKey();
+
+ // Copyable and movable
+ DatabaseKey(const DatabaseKey& other);
+ DatabaseKey& operator=(const DatabaseKey& other);
+ DatabaseKey(DatabaseKey&& other);
+ DatabaseKey& operator=(DatabaseKey&& other);
+
+ DatabaseKey(const blink::StorageKey& storage_key,
+ const absl::optional<BucketLocator>& bucket,
+ const std::string& type_string);
+
+ const blink::StorageKey& storage_key() const { return storage_key_; }
+ const absl::optional<BucketLocator>& bucket() const { return bucket_; }
+ const std::string& type() const { return type_; }
+
+ bool operator==(const DatabaseKey& other) const;
+ bool operator!=(const DatabaseKey& other) const;
+ bool operator<(const DatabaseKey& other) const;
+
+ private:
+ blink::StorageKey storage_key_;
+ absl::optional<BucketLocator> bucket_;
+ std::string type_;
+};
+
+// This file util stores directory information in either LevelDB or
+// StorageBuckets to obfuscate and to neutralize virtual file paths given by
+// arbitrary apps. Files are stored with three-level isolation: (1)
+// per-StorageKey, (2) per-bucket, and (3) per-type. The isolation is done by
+// storing data in separate directory partitions. For example, a file in
+// Temporary file system for origin 'www.example.com' is stored in a different
+// partition from a file in Persistent file system for the same origin, or from
+// a file in a Temporary file system for another origin. Similarly, a file in a
+// Temporary file system for origin 'www.foo.com' with a default bucket is
+// stored in a different partition from a non-default bucket for the same origin
+// and Temporary file system.
//
-// * Per-origin directory name information is stored in a separate LevelDB,
-// which is maintained by SandboxOriginDatabase.
-// * Per-type directory name information is given by
-// GetTypeStringForURLCallback that is given in CTOR.
-// We use a small static mapping (e.g. 't' for Temporary type) for
-// regular sandbox filesystems.
+// * For default first-party StorageKeys, per-origin directory name information
+// is stored in a separate LevelDB, which is maintained by
+// SandboxOriginDatabase. For per-type information, we use a small static
+// mapping (e.g. 't' for Temporary type) for regular sandbox filesystems.
+// NOTE/TODO(https://crbug.com/1349156): the goal is to eventually deprecate
+// SandboxOriginDatabase and rely entirely on Storage Buckets.
+// * For all other StorageKeys, we rely on quota management of Storage Buckets
+// in addition to the same static mapping of per-type information described
+// above.
//
// The overall implementation philosophy of this class is that partial failures
// should leave us with an intact database; we'd prefer to leak the occasional
@@ -69,21 +113,16 @@ 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:
// StorageKey enumerator interface.
// An instance of this interface is assumed to be called on the file thread.
+ // NOTE: currently, ObfuscatedFileUtil still relies on SandboxOriginDatabases
+ // for first-party StorageKeys/default buckets. The
+ // AbstractStorageKeyEnumerator is only used in these cases. While this class
+ // stores StorageKeys, it ultimately relies on only the origin information to
+ // access the appropriate SandboxOriginDatabase.
class AbstractStorageKeyEnumerator {
public:
virtual ~AbstractStorageKeyEnumerator() = default;
@@ -92,28 +131,26 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) ObfuscatedFileUtil
// StorageKeys.
virtual absl::optional<blink::StorageKey> Next() = 0;
- // Returns the current origin's information.
+ // Returns the current StorageKey's information.
// `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
- // 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
- // should care about.
- // This info is used to determine whether we could delete the entire
- // 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.
+ // The FileSystem directory component.
+ static const base::FilePath::CharType kFileSystemDirectory[];
+
+ // 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 should care about. This info is used to determine whether
+ // we could delete the entire 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. NOTE: type strings are not mapped 1-to-1 with FileSystemType,
+ // and as a result, directories should only be directly compared using type
+ // string values.
ObfuscatedFileUtil(scoped_refptr<SpecialStoragePolicy> special_storage_policy,
- const base::FilePath& file_system_directory,
+ const base::FilePath& profile_path,
leveldb::Env* env_override,
- GetTypeStringForURLCallback get_type_string_for_url,
const std::set<std::string>& known_type_strings,
SandboxFileSystemBackendDelegate* sandbox_delegate,
bool is_incognito);
@@ -177,47 +214,56 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) ObfuscatedFileUtil
// Gets the topmost directory specific to this BucketLocator 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` is empty.
// Returns a base::FileError if the directory is undefined.
base::FileErrorOr<base::FilePath> GetDirectoryForBucketAndType(
const BucketLocator& bucket_locator,
- const std::string& type_string,
+ const absl::optional<FileSystemType>& type,
bool create);
// 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` 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
- // the returned path is usable.
- base::FilePath GetDirectoryForStorageKeyAndType(
+ // `create` is false).
+ base::FileErrorOr<base::FilePath> GetDirectoryForStorageKeyAndType(
const blink::StorageKey& storage_key,
- const std::string& type_string,
- bool create,
- base::File::Error* error_code);
+ const absl::optional<FileSystemType>& type,
+ bool create);
- // 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);
+ // Deletes the topmost directory specific to this StorageKey and type. This
+ // will delete its directory database. Deletes the topmost StorageKey
+ // directory if `type` is absl::nullopt.
+ bool DeleteDirectoryForStorageKeyAndType(
+ const blink::StorageKey& storage_key,
+ const absl::optional<FileSystemType>& type);
- // Frees resources used by a StorageKey's filesystem.
- void CloseFileSystemForStorageKeyAndType(const blink::StorageKey& storage_key,
- const std::string& type_string);
+ // Deletes the topmost directory specific to this BucketLocator and type. This
+ // will delete its directory database. Deletes the topmost bucket
+ // directory if `type` is absl::nullopt.
+ bool DeleteDirectoryForBucketAndType(
+ const BucketLocator& bucket_locator,
+ const absl::optional<FileSystemType>& type);
// 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<AbstractStorageKeyEnumerator> CreateStorageKeyEnumerator();
- // Deletes a directory database from the database list in the ObfuscatedFSFU
- // and destroys the database on the disk.
- void DestroyDirectoryDatabase(const blink::StorageKey& storage_key,
- const std::string& type_string);
+ // Deletes a directory database from the database list and destroys the
+ // database on the disk corresponding to the provided StorageKey and type.
+ void DestroyDirectoryDatabaseForStorageKey(
+ const blink::StorageKey& storage_key,
+ const absl::optional<FileSystemType>& type);
+
+ // Deletes a directory database from the database list and destroys the
+ // database on the disk corresponding to the provided bucket locator and type.
+ void DestroyDirectoryDatabaseForBucket(
+ const BucketLocator& bucket_locator,
+ const absl::optional<FileSystemType>& type);
// Computes a cost for storing a given file in the obfuscated FSFU.
// As the cost of a file is independent of the cost of its parent directories,
@@ -229,6 +275,18 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) ObfuscatedFileUtil
// This will rewrite the databases to remove traces of deleted data from disk.
void RewriteDatabases();
+ // This function removes the key-value pair from default_buckets_ keyed at
+ // `storage_key`. Called when a default bucket is deleted from Quota
+ // management and the default_buckets_ cache needs to be updated to reflect
+ // that change in state.
+ void DeleteDefaultBucketForStorageKey(const blink::StorageKey& storage_key);
+
+ // This function removes the key-value pair(s) from default_buckets_ with the
+ // value `bucket_locator`. Called when a default bucket is deleted from Quota
+ // management and the default_buckets_ cache needs to be updated to reflect
+ // that change in state.
+ void DeleteDefaultBucket(const BucketLocator& bucket_locator);
+
bool is_incognito() { return is_incognito_; }
ObfuscatedFileUtilDelegate* delegate() { return delegate_.get(); }
@@ -244,6 +302,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) ObfuscatedFileUtil
friend class ObfuscatedFileEnumerator;
friend class ObfuscatedFileUtilTest;
friend class QuotaBackendImplTest;
+ friend class SandboxFileSystemBackendDelegate;
// Helper method to create an obfuscated file util for regular
// (temporary, persistent) file systems. Used only for testing.
@@ -257,9 +316,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) ObfuscatedFileUtil
base::FileErrorOr<base::FilePath> GetDirectoryForURL(const FileSystemURL& url,
bool create);
- // This just calls get_type_string_for_url_ callback that is given in ctor.
- std::string CallGetTypeStringForURL(const FileSystemURL& url);
-
base::File::Error GetFileInfoInternal(SandboxDirectoryDatabase* db,
FileSystemOperationContext* context,
const FileSystemURL& url,
@@ -301,8 +357,12 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) ObfuscatedFileUtil
base::FilePath DataPathToLocalPath(const FileSystemURL& url,
const base::FilePath& data_file_path);
- std::string GetDirectoryDatabaseKey(const blink::StorageKey& storage_key,
- const std::string& type_string);
+ // Deletes a directory database from the database list and destroys the
+ // database on the disk.
+ void DestroyDirectoryDatabaseHelper(
+ const absl::optional<BucketLocator>& bucket_locator,
+ const blink::StorageKey& storage_key,
+ const absl::optional<FileSystemType>& type);
// This returns nullptr if `create` flag is false and a filesystem does not
// exist for the given `url`.
@@ -327,6 +387,14 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) ObfuscatedFileUtil
const blink::StorageKey& storage_key,
FileSystemType type);
+ // Given a StorageKey, retrieve its default bucket either from the
+ // default_buckets_ in-memory structure or via GetOrCreateBucketSync(). NOTE:
+ // this function may use base::ScopedAllowBaseSyncPrimitives and call
+ // QuotaManagerProxy::GetOrCreateBucketSync() which relies on a blocking
+ // base::WaitableEvent.
+ QuotaErrorOr<BucketLocator> GetOrCreateDefaultBucket(
+ const blink::StorageKey& storage_key);
+
void MarkUsed();
void DropDatabases();
@@ -348,7 +416,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) ObfuscatedFileUtil
SEQUENCE_CHECKER(sequence_checker_);
- std::map<std::string, std::unique_ptr<SandboxDirectoryDatabase>> directories_;
+ // Keeps tracks of previously-seen default buckets mapped to their
+ // corresponding StorageKey. Should remain in parallel with directories_.
+ std::map<blink::StorageKey, BucketLocator> default_buckets_;
+ std::map<DatabaseKey, std::unique_ptr<SandboxDirectoryDatabase>> directories_;
std::unique_ptr<SandboxOriginDatabaseInterface> origin_database_;
scoped_refptr<SpecialStoragePolicy> special_storage_policy_;
base::FilePath file_system_directory_;
@@ -360,7 +431,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) ObfuscatedFileUtil
base::OneShotTimer timer_;
- GetTypeStringForURLCallback get_type_string_for_url_;
std::set<std::string> known_type_strings_;
// Not owned.
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 326e9d85df9..e9db5bb939b 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
@@ -10,6 +10,7 @@
#include "base/allocator/partition_allocator/partition_alloc_constants.h"
#include "base/files/file_util.h"
#include "base/numerics/checked_math.h"
+#include "base/numerics/safe_conversions.h"
#include "base/system/sys_info.h"
#include "build/build_config.h"
#include "net/base/io_buffer.h"
@@ -26,14 +27,14 @@ namespace {
// crash possibility.
// Note that quota assignment is the same for on-disk filesystem and the
// assigned quota is not guaranteed to be allocatable later.
-bool IsMemoryAvailable(int64_t required_memory) {
+bool IsMemoryAvailable(size_t required_memory) {
#if BUILDFLAG(IS_FUCHSIA)
// This function is not implemented on FUCHSIA, yet. (crbug.com/986608)
return true;
#else
- int64_t max_allocatable =
+ uint64_t max_allocatable =
std::min(base::SysInfo::AmountOfAvailablePhysicalMemory(),
- static_cast<int64_t>(partition_alloc::MaxDirectMapped()));
+ static_cast<uint64_t>(partition_alloc::MaxDirectMapped()));
return max_allocatable >= required_memory;
#endif
@@ -335,12 +336,13 @@ base::File::Error ObfuscatedFileUtilMemoryDelegate::Truncate(
return base::File::FILE_ERROR_NOT_FOUND;
// Fail if enough memory is not available.
- if (static_cast<size_t>(length) > dp->entry->file_content.capacity() &&
- !IsMemoryAvailable(length)) {
+ if (!base::IsValueInRangeForNumericType<size_t>(length) ||
+ (static_cast<size_t>(length) > dp->entry->file_content.capacity() &&
+ !IsMemoryAvailable(static_cast<size_t>(length)))) {
return base::File::FILE_ERROR_NO_SPACE;
}
- dp->entry->file_content.resize(length);
+ dp->entry->file_content.resize(static_cast<size_t>(length));
return base::File::FILE_OK;
}
@@ -620,7 +622,7 @@ base::File::Error ObfuscatedFileUtilMemoryDelegate::CopyInForeignFile(
}
// Fail if enough memory is not available.
- if (!IsMemoryAvailable(source_info.size))
+ if (!IsMemoryAvailable(static_cast<size_t>(source_info.size)))
return base::File::FILE_ERROR_NO_SPACE;
// Create file.
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 2335c0dd625..09174f73c3a 100644
--- a/chromium/storage/browser/file_system/obfuscated_file_util_unittest.cc
+++ b/chromium/storage/browser/file_system/obfuscated_file_util_unittest.cc
@@ -27,10 +27,12 @@
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
+#include "base/test/test_future.h"
#include "base/threading/thread_restrictions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "components/services/filesystem/public/mojom/types.mojom.h"
+#include "net/base/features.h"
#include "net/base/io_buffer.h"
#include "storage/browser/file_system/external_mount_points.h"
#include "storage/browser/file_system/file_system_backend.h"
@@ -53,7 +55,6 @@
#include "storage/common/database/database_identifier.h"
#include "storage/common/file_system/file_system_types.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/leveldatabase/leveldb_chrome.h"
#include "url/gurl.h"
@@ -64,7 +65,16 @@ namespace storage {
namespace {
-enum TestMode { kRegular, kIncognito };
+enum TestMode {
+ kRegularFirstParty,
+ kRegularFirstPartyNonDefaultBucket,
+ kRegularThirdParty,
+ kRegularThirdPartyNonDefaultBucket,
+ kIncognitoFirstParty,
+ kIncognitoFirstPartyNonDefaultBucket,
+ kIncognitoThirdParty,
+ kIncognitoThirdPartyNonDefaultBucket
+};
bool FileExists(const base::FilePath& path) {
return base::PathExists(path) && !base::DirectoryExists(path);
@@ -124,20 +134,30 @@ const OriginEnumerationTestRecord kOriginEnumerationTestRecords[] = {
FileSystemURL FileSystemURLAppend(const FileSystemURL& url,
const base::FilePath::StringType& child) {
- return FileSystemURL::CreateForTest(url.storage_key(), url.mount_type(),
- url.virtual_path().Append(child));
+ FileSystemURL new_url = FileSystemURL::CreateForTest(
+ url.storage_key(), url.mount_type(), url.virtual_path().Append(child));
+ if (url.bucket().has_value())
+ new_url.SetBucket(url.bucket().value());
+ return new_url;
}
FileSystemURL FileSystemURLAppendUTF8(const FileSystemURL& url,
const std::string& child) {
- return FileSystemURL::CreateForTest(
+ FileSystemURL new_url = FileSystemURL::CreateForTest(
url.storage_key(), url.mount_type(),
url.virtual_path().Append(base::FilePath::FromUTF8Unsafe(child)));
+ if (url.bucket().has_value())
+ new_url.SetBucket(url.bucket().value());
+ return new_url;
}
FileSystemURL FileSystemURLDirName(const FileSystemURL& url) {
- return FileSystemURL::CreateForTest(url.storage_key(), url.mount_type(),
- VirtualPath::DirName(url.virtual_path()));
+ FileSystemURL new_url =
+ FileSystemURL::CreateForTest(url.storage_key(), url.mount_type(),
+ VirtualPath::DirName(url.virtual_path()));
+ if (url.bucket().has_value())
+ new_url.SetBucket(url.bucket().value());
+ return new_url;
}
std::string GetTypeString(FileSystemType type) {
@@ -166,14 +186,42 @@ class ObfuscatedFileUtilTest : public testing::Test,
type_(kFileSystemTypeTemporary),
sandbox_file_system_(storage_key_, type_),
quota_status_(blink::mojom::QuotaStatusCode::kUnknown),
- usage_(-1) {}
+ usage_(-1) {
+ if (is_third_party_context()) {
+ scoped_feature_list_.InitAndEnableFeature(
+ net::features::kThirdPartyStoragePartitioning);
+ // Once we enable third-party storage partitioning, we can create a
+ // third-party StorageKey and re-assign the StorageKey value in the
+ // SandboxFileSystem with this value in SetUp for default buckets.
+ storage_key_ = blink::StorageKey::CreateWithOptionalNonce(
+ storage_key_.origin(), storage_key_.top_level_site(), nullptr,
+ blink::mojom::AncestorChainBit::kCrossSite);
+ }
+ }
ObfuscatedFileUtilTest(const ObfuscatedFileUtilTest&) = delete;
ObfuscatedFileUtilTest& operator=(const ObfuscatedFileUtilTest&) = delete;
~ObfuscatedFileUtilTest() override = default;
- bool is_incognito() { return GetParam() == TestMode::kIncognito; }
+ bool is_incognito() {
+ return GetParam() == TestMode::kIncognitoFirstParty ||
+ (GetParam() == TestMode::kIncognitoFirstPartyNonDefaultBucket) ||
+ (GetParam() == TestMode::kIncognitoThirdParty) ||
+ (GetParam() == TestMode::kIncognitoThirdPartyNonDefaultBucket);
+ }
+ bool is_third_party_context() {
+ return GetParam() == TestMode::kRegularThirdParty ||
+ (GetParam() == TestMode::kRegularThirdPartyNonDefaultBucket) ||
+ (GetParam() == TestMode::kIncognitoThirdParty) ||
+ (GetParam() == TestMode::kIncognitoThirdPartyNonDefaultBucket);
+ }
+ bool is_non_default_bucket() {
+ return GetParam() == TestMode::kRegularFirstPartyNonDefaultBucket ||
+ (GetParam() == TestMode::kRegularThirdPartyNonDefaultBucket) ||
+ (GetParam() == TestMode::kIncognitoFirstPartyNonDefaultBucket) ||
+ (GetParam() == TestMode::kIncognitoThirdPartyNonDefaultBucket);
+ }
void SetUp() override {
ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
@@ -212,7 +260,42 @@ class ObfuscatedFileUtilTest : public testing::Test,
: CreateFileSystemContextForTesting(
quota_manager_->proxy(), data_dir_.GetPath());
- sandbox_file_system_.SetUp(file_system_context_);
+ // Create the default bucket member corresponding to the StorageKey member
+ // we created.
+ base::test::TestFuture<QuotaErrorOr<BucketInfo>> default_future;
+ quota_manager_->proxy()->UpdateOrCreateBucket(
+ BucketInitParams::ForDefaultBucket(storage_key()),
+ base::SequencedTaskRunnerHandle::Get(), default_future.GetCallback());
+ QuotaErrorOr<BucketInfo> default_bucket = default_future.Take();
+ CHECK(default_bucket.ok());
+ default_bucket_ = default_bucket.value().ToBucketLocator();
+
+ // Create a non-default bucket member corresponding to the StorageKey
+ // member we created.
+ base::test::TestFuture<QuotaErrorOr<BucketInfo>> custom_future;
+ BucketInitParams params = BucketInitParams::ForDefaultBucket(storage_key());
+ params.name = "non-default bucket";
+ quota_manager_->proxy()->UpdateOrCreateBucket(
+ params, base::SequencedTaskRunnerHandle::Get(),
+ custom_future.GetCallback());
+ QuotaErrorOr<BucketInfo> custom_bucket = custom_future.Take();
+ CHECK(custom_bucket.ok());
+ custom_bucket_ = custom_bucket.value().ToBucketLocator();
+
+ // Create an alternate non-default bucket member corresponding to the
+ // StorageKey member we created.
+ base::test::TestFuture<QuotaErrorOr<BucketInfo>> alternate_future;
+ params.name = "alternate non-default bucket";
+ quota_manager_->proxy()->UpdateOrCreateBucket(
+ params, base::SequencedTaskRunnerHandle::Get(),
+ alternate_future.GetCallback());
+ QuotaErrorOr<BucketInfo> alternate_bucket = alternate_future.Take();
+ CHECK(alternate_bucket.ok());
+ alternate_custom_bucket_ = alternate_bucket.value().ToBucketLocator();
+
+ is_non_default_bucket()
+ ? sandbox_file_system_.SetUp(file_system_context_, custom_bucket_)
+ : sandbox_file_system_.SetUp(file_system_context_, storage_key_);
change_observers_ = MockFileChangeObserver::CreateList(&change_observer_);
@@ -263,17 +346,28 @@ class ObfuscatedFileUtilTest : public testing::Test,
// This can only be used after SetUp has run and created file_system_context_
// and obfuscated_file_util_.
- // Use this for tests which need to run in multiple origins; we need a test
- // helper per origin.
+ // Use this for tests which need to run in multiple StorageKeys; we need a
+ // test helper per StorageKey.
+ std::unique_ptr<SandboxFileSystemTestHelper> NewFileSystem(
+ const blink::StorageKey& storage_key,
+ FileSystemType type) {
+ auto file_system =
+ std::make_unique<SandboxFileSystemTestHelper>(storage_key, type);
+ file_system->SetUp(file_system_context_);
+ return file_system;
+ }
+
+ // This can only be used after SetUp has run and created file_system_context_
+ // and obfuscated_file_util_.
+ // Use this for tests which need to run in multiple BucketLocators; we need a
+ // test helper per BucketLocator.
std::unique_ptr<SandboxFileSystemTestHelper> NewFileSystem(
- const Origin& origin,
+ const BucketLocator& bucket_locator,
FileSystemType 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);
+ bucket_locator.storage_key, type);
- file_system->SetUp(file_system_context_);
+ file_system->SetUp(file_system_context_, bucket_locator);
return file_system;
}
@@ -307,8 +401,8 @@ class ObfuscatedFileUtilTest : public testing::Test,
void GetUsageFromQuotaManager() {
int64_t quota = -1;
quota_status_ = AsyncFileTestHelper::GetUsageAndQuota(
- quota_manager_->proxy(), origin(), sandbox_file_system_.type(), &usage_,
- &quota);
+ quota_manager_->proxy(), storage_key(), sandbox_file_system_.type(),
+ &usage_, &quota);
EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk, quota_status_);
}
@@ -321,7 +415,10 @@ class ObfuscatedFileUtilTest : public testing::Test,
sandbox_file_system->storage_type());
},
quota_manager_, &sandbox_file_system_));
- usage_cache()->Delete(sandbox_file_system_.GetUsageCachePath());
+ base::FileErrorOr<base::FilePath> path =
+ sandbox_file_system_.GetUsageCachePath();
+ if (!path.is_error())
+ usage_cache()->Delete(path.value());
}
int64_t SizeByQuotaUtil() { return sandbox_file_system_.GetCachedUsage(); }
@@ -329,10 +426,11 @@ class ObfuscatedFileUtilTest : public testing::Test,
int64_t SizeInUsageFile() {
task_environment_.RunUntilIdle();
int64_t usage = 0;
- return usage_cache()->GetUsage(sandbox_file_system_.GetUsageCachePath(),
- &usage)
- ? usage
- : -1;
+ base::FileErrorOr<base::FilePath> path =
+ sandbox_file_system_.GetUsageCachePath();
+ if (path.is_error())
+ return -1;
+ return usage_cache()->GetUsage(path.value(), &usage) ? usage : -1;
}
bool PathExists(const FileSystemURL& url) {
@@ -363,18 +461,24 @@ class ObfuscatedFileUtilTest : public testing::Test,
return sandbox_file_system_.usage_cache();
}
+ FileSystemURL CreateURL(const base::FilePath& path) {
+ FileSystemURL test_url = sandbox_file_system_.CreateURL(path);
+ if (is_non_default_bucket())
+ test_url.SetBucket(custom_bucket_);
+ return test_url;
+ }
+
FileSystemURL CreateURLFromUTF8(const std::string& path) {
- return sandbox_file_system_.CreateURLFromUTF8(path);
+ FileSystemURL test_url = sandbox_file_system_.CreateURLFromUTF8(path);
+ if (is_non_default_bucket())
+ test_url.SetBucket(custom_bucket_);
+ return test_url;
}
int64_t PathCost(const FileSystemURL& url) {
return ObfuscatedFileUtil::ComputeFilePathCost(url.path());
}
- FileSystemURL CreateURL(const base::FilePath& path) {
- return sandbox_file_system_.CreateURL(path);
- }
-
void CheckFile(const FileSystemURL& url) {
std::unique_ptr<FileSystemOperationContext> context = NewContext(nullptr);
base::FilePath local_path;
@@ -757,42 +861,45 @@ class ObfuscatedFileUtilTest : public testing::Test,
}
void DestroyDirectoryDatabase_IsolatedTestBody() {
- storage_policy_->AddIsolated(storage_key_.origin().GetURL());
- std::unique_ptr<ObfuscatedFileUtil> file_util =
- CreateObfuscatedFileUtil(/*storage_policy=*/storage_policy_);
- const FileSystemURL url = FileSystemURL::CreateForTest(
- storage_key_, kFileSystemTypePersistent, base::FilePath());
+ storage_policy_->AddIsolated(origin().GetURL());
+ FileSystemURL url = FileSystemURL::CreateForTest(
+ storage_key(), kFileSystemTypePersistent, base::FilePath());
+ if (is_non_default_bucket())
+ url.SetBucket(custom_bucket_);
// Create DirectoryDatabase for isolated origin.
SandboxDirectoryDatabase* db =
- file_util->GetDirectoryDatabase(url, true /* create */);
+ ofu()->GetDirectoryDatabase(url, true /* create */);
ASSERT_TRUE(db != nullptr);
// Destroy it.
- file_util->DestroyDirectoryDatabase(url.storage_key(),
- GetTypeString(url.type()));
- ASSERT_TRUE(file_util->directories_.empty());
+ (is_non_default_bucket()) ? ofu()->DestroyDirectoryDatabaseForBucket(
+ url.bucket().value(), url.type())
+ : ofu()->DestroyDirectoryDatabaseForStorageKey(
+ url.storage_key(), url.type());
+ ASSERT_TRUE(ofu()->directories_.empty());
}
void GetDirectoryDatabase_IsolatedTestBody() {
- storage_policy_->AddIsolated(storage_key_.origin().GetURL());
- std::unique_ptr<ObfuscatedFileUtil> file_util =
- CreateObfuscatedFileUtil(storage_policy_);
- const FileSystemURL url = FileSystemURL::CreateForTest(
- storage_key_, kFileSystemTypePersistent, base::FilePath());
+ storage_policy_->AddIsolated(origin().GetURL());
+ FileSystemURL url = FileSystemURL::CreateForTest(
+ blink::StorageKey(origin()), kFileSystemTypePersistent,
+ base::FilePath());
+ if (is_non_default_bucket())
+ url.SetBucket(custom_bucket_);
// Create DirectoryDatabase for isolated origin.
SandboxDirectoryDatabase* db =
- file_util->GetDirectoryDatabase(url, true /* create */);
+ ofu()->GetDirectoryDatabase(url, true /* create */);
ASSERT_TRUE(db != nullptr);
- ASSERT_EQ(1U, file_util->directories_.size());
+ ASSERT_EQ(1U, ofu()->directories_.size());
// Remove isolated.
storage_policy_->RemoveIsolated(url.origin().GetURL());
// This should still get the same database.
SandboxDirectoryDatabase* db2 =
- file_util->GetDirectoryDatabase(url, false /* create */);
+ ofu()->GetDirectoryDatabase(url, false /* create */);
ASSERT_EQ(db, db2);
}
@@ -816,6 +923,7 @@ class ObfuscatedFileUtilTest : public testing::Test,
}
protected:
+ base::test::ScopedFeatureList scoped_feature_list_;
std::unique_ptr<leveldb::Env> incognito_leveldb_environment_;
base::test::TaskEnvironment task_environment_;
base::ScopedTempDir data_dir_;
@@ -824,6 +932,9 @@ class ObfuscatedFileUtilTest : public testing::Test,
scoped_refptr<base::SingleThreadTaskRunner> quota_manager_task_runner_;
scoped_refptr<FileSystemContext> file_system_context_;
blink::StorageKey storage_key_;
+ BucketLocator default_bucket_;
+ BucketLocator custom_bucket_;
+ BucketLocator alternate_custom_bucket_;
FileSystemType type_;
SandboxFileSystemTestHelper sandbox_file_system_;
blink::mojom::QuotaStatusCode quota_status_;
@@ -833,10 +944,17 @@ class ObfuscatedFileUtilTest : public testing::Test,
base::WeakPtrFactory<ObfuscatedFileUtilTest> weak_factory_{this};
};
-INSTANTIATE_TEST_SUITE_P(All,
- ObfuscatedFileUtilTest,
- testing::Values(TestMode::kRegular,
- TestMode::kIncognito));
+INSTANTIATE_TEST_SUITE_P(
+ All,
+ ObfuscatedFileUtilTest,
+ testing::Values(TestMode::kRegularFirstParty,
+ TestMode::kRegularFirstPartyNonDefaultBucket,
+ TestMode::kRegularThirdParty,
+ TestMode::kRegularThirdPartyNonDefaultBucket,
+ TestMode::kIncognitoFirstParty,
+ TestMode::kIncognitoFirstPartyNonDefaultBucket,
+ TestMode::kIncognitoThirdParty,
+ TestMode::kIncognitoThirdPartyNonDefaultBucket));
TEST_P(ObfuscatedFileUtilTest, TestCreateAndDeleteFile) {
FileSystemURL url = CreateURLFromUTF8("fake/file");
@@ -1602,6 +1720,14 @@ TEST_P(ObfuscatedFileUtilTest, TestStorageKeyEnumerator) {
ofu()->CreateStorageKeyEnumerator();
// The test helper starts out with a single filesystem.
EXPECT_TRUE(enumerator.get());
+ // This test is not relevant for third-party or non-default buckets code paths
+ // because these paths do not add to the OriginDatabase, the structure that
+ // populates the enumerator being tested. So in a test environment, this
+ // enumerator should not have any additional StorageKeys to access via Next().
+ if (is_third_party_context() || is_non_default_bucket()) {
+ EXPECT_EQ(absl::nullopt, enumerator->Next());
+ return;
+ }
EXPECT_EQ(storage_key(), enumerator->Next());
ASSERT_TRUE(type() == kFileSystemTypeTemporary);
EXPECT_TRUE(HasFileSystemType(enumerator.get(), kFileSystemTypeTemporary));
@@ -1623,7 +1749,7 @@ TEST_P(ObfuscatedFileUtilTest, TestStorageKeyEnumerator) {
storage_keys_expected.insert(storage_key);
if (record.has_temporary) {
std::unique_ptr<SandboxFileSystemTestHelper> file_system =
- NewFileSystem(storage_key.origin(), kFileSystemTypeTemporary);
+ NewFileSystem(storage_key, kFileSystemTypeTemporary);
std::unique_ptr<FileSystemOperationContext> context(
NewContext(file_system.get()));
bool created = false;
@@ -1635,7 +1761,7 @@ TEST_P(ObfuscatedFileUtilTest, TestStorageKeyEnumerator) {
}
if (record.has_persistent) {
std::unique_ptr<SandboxFileSystemTestHelper> file_system =
- NewFileSystem(storage_key.origin(), kFileSystemTypePersistent);
+ NewFileSystem(storage_key, kFileSystemTypePersistent);
std::unique_ptr<FileSystemOperationContext> context(
NewContext(file_system.get()));
bool created = false;
@@ -1752,7 +1878,9 @@ TEST_P(ObfuscatedFileUtilTest, TestInconsistency) {
EXPECT_EQ(10, file_info.size);
// Destroy database to make inconsistency between database and filesystem.
- ofu()->DestroyDirectoryDatabase(storage_key(), type_string());
+ (is_non_default_bucket())
+ ? ofu()->DestroyDirectoryDatabaseForBucket(custom_bucket_, type())
+ : ofu()->DestroyDirectoryDatabaseForStorageKey(storage_key(), type());
// Try to get file info of broken file.
EXPECT_FALSE(PathExists(kPath1));
@@ -1772,7 +1900,9 @@ TEST_P(ObfuscatedFileUtilTest, TestInconsistency) {
EXPECT_TRUE(created);
// Destroy again.
- ofu()->DestroyDirectoryDatabase(storage_key(), type_string());
+ (is_non_default_bucket())
+ ? ofu()->DestroyDirectoryDatabaseForBucket(custom_bucket_, type())
+ : ofu()->DestroyDirectoryDatabaseForStorageKey(storage_key(), type());
// Repair broken `kPath1`.
context = NewContext(nullptr);
@@ -1790,7 +1920,9 @@ TEST_P(ObfuscatedFileUtilTest, TestInconsistency) {
FileSystemOperation::CopyOrMoveOptionSet(),
true /* copy */));
- ofu()->DestroyDirectoryDatabase(storage_key(), type_string());
+ (is_non_default_bucket())
+ ? ofu()->DestroyDirectoryDatabaseForBucket(custom_bucket_, type())
+ : ofu()->DestroyDirectoryDatabaseForStorageKey(storage_key(), type());
context = NewContext(nullptr);
created = false;
EXPECT_EQ(base::File::FILE_OK,
@@ -2051,12 +2183,12 @@ TEST_P(ObfuscatedFileUtilTest, TestFileEnumeratorTimestamp) {
while (!(file_path_each = file_enum->Next()).empty()) {
context = NewContext(nullptr);
base::File::Info file_info;
- EXPECT_EQ(base::File::FILE_OK,
- ofu()->GetFileInfo(
- context.get(),
- FileSystemURL::CreateForTest(
- dir.storage_key(), dir.mount_type(), file_path_each),
- &file_info, &file_path));
+ FileSystemURL new_url = FileSystemURL::CreateForTest(
+ dir.storage_key(), dir.mount_type(), file_path_each);
+ if (dir.bucket().has_value())
+ new_url.SetBucket(dir.bucket().value());
+ EXPECT_EQ(base::File::FILE_OK, ofu()->GetFileInfo(context.get(), new_url,
+ &file_info, &file_path));
EXPECT_EQ(file_info.is_directory, file_enum->IsDirectory());
EXPECT_EQ(file_info.last_modified, file_enum->LastModifiedTime());
EXPECT_EQ(file_info.size, file_enum->Size());
@@ -2421,7 +2553,80 @@ TEST_P(ObfuscatedFileUtilTest, CreateDirectory_NotADirectoryInRecursive) {
false /* exclusive */, true /* recursive */));
}
-TEST_P(ObfuscatedFileUtilTest, DeleteDirectoryForOriginAndType) {
+TEST_P(ObfuscatedFileUtilTest, DeleteDirectoryForBucketAndType) {
+ // Create directories.
+ std::unique_ptr<SandboxFileSystemTestHelper> fs1 =
+ NewFileSystem(default_bucket_, kFileSystemTypeTemporary);
+ std::unique_ptr<SandboxFileSystemTestHelper> fs2 =
+ NewFileSystem(default_bucket_, kFileSystemTypePersistent);
+ std::unique_ptr<SandboxFileSystemTestHelper> fs3 =
+ NewFileSystem(custom_bucket_, kFileSystemTypeTemporary);
+ std::unique_ptr<SandboxFileSystemTestHelper> fs4 =
+ NewFileSystem(custom_bucket_, kFileSystemTypePersistent);
+
+ // Make sure directories for default_bucket_ exist.
+ ASSERT_FALSE(ofu()
+ ->GetDirectoryForBucketAndType(default_bucket_,
+ kFileSystemTypeTemporary,
+ /*create=*/false)
+ .is_error());
+ ASSERT_FALSE(ofu()
+ ->GetDirectoryForBucketAndType(default_bucket_,
+ kFileSystemTypePersistent,
+ /*create=*/false)
+ .is_error());
+
+ // Make sure directories for custom_bucket_ exist.
+ ASSERT_FALSE(ofu()
+ ->GetDirectoryForBucketAndType(custom_bucket_,
+ kFileSystemTypeTemporary,
+ /*create=*/false)
+ .is_error());
+ ASSERT_FALSE(ofu()
+ ->GetDirectoryForBucketAndType(custom_bucket_,
+ kFileSystemTypePersistent,
+ /*create=*/false)
+ .is_error());
+
+ // Delete a directory for default_bucket_'s persistent filesystem.
+ ASSERT_TRUE(ofu()->DeleteDirectoryForBucketAndType(
+ default_bucket_, kFileSystemTypePersistent));
+
+ // The directory for default_bucket_'s temporary filesystem should not be
+ // removed.
+ ASSERT_FALSE(ofu()
+ ->GetDirectoryForBucketAndType(default_bucket_,
+ kFileSystemTypeTemporary,
+ /*create=*/false)
+ .is_error());
+
+ // The directory for default_bucket_'s persistent filesystem should be
+ // removed.
+ ASSERT_EQ(ofu()
+ ->GetDirectoryForBucketAndType(default_bucket_,
+ kFileSystemTypePersistent,
+ /*create=*/false)
+ .error(),
+ base::File::FILE_ERROR_NOT_FOUND);
+
+ // The directories for custom_bucket_ should not be removed.
+ ASSERT_FALSE(ofu()
+ ->GetDirectoryForBucketAndType(custom_bucket_,
+ kFileSystemTypeTemporary,
+ /*create=*/false)
+ .is_error());
+ ASSERT_FALSE(ofu()
+ ->GetDirectoryForBucketAndType(custom_bucket_,
+ kFileSystemTypePersistent,
+ /*create=*/false)
+ .is_error());
+
+ // Deleting directories which don't exist is not an error.
+ ASSERT_TRUE(ofu()->DeleteDirectoryForBucketAndType(
+ alternate_custom_bucket_, kFileSystemTypePersistent));
+}
+
+TEST_P(ObfuscatedFileUtilTest, DeleteDirectoryForStorageKeyAndType) {
const blink::StorageKey storage_key1 =
blink::StorageKey::CreateFromStringForTesting(
"http://www.example.com:12");
@@ -2433,79 +2638,157 @@ TEST_P(ObfuscatedFileUtilTest, DeleteDirectoryForOriginAndType) {
// Create origin directories.
std::unique_ptr<SandboxFileSystemTestHelper> fs1 =
- NewFileSystem(storage_key1.origin(), kFileSystemTypeTemporary);
+ NewFileSystem(storage_key1, kFileSystemTypeTemporary);
std::unique_ptr<SandboxFileSystemTestHelper> fs2 =
- NewFileSystem(storage_key1.origin(), kFileSystemTypePersistent);
+ NewFileSystem(storage_key1, kFileSystemTypePersistent);
std::unique_ptr<SandboxFileSystemTestHelper> fs3 =
- NewFileSystem(storage_key2.origin(), kFileSystemTypeTemporary);
+ NewFileSystem(storage_key2, kFileSystemTypeTemporary);
std::unique_ptr<SandboxFileSystemTestHelper> fs4 =
- NewFileSystem(storage_key2.origin(), kFileSystemTypePersistent);
+ NewFileSystem(storage_key2, kFileSystemTypePersistent);
// Make sure directories for storage_key1 exist.
- base::File::Error error = base::File::FILE_ERROR_FAILED;
- ofu()->GetDirectoryForStorageKeyAndType(
- storage_key1, GetTypeString(kFileSystemTypeTemporary), false, &error);
- ASSERT_EQ(base::File::FILE_OK, error);
- error = base::File::FILE_ERROR_FAILED;
- ofu()->GetDirectoryForStorageKeyAndType(
- storage_key1, GetTypeString(kFileSystemTypePersistent), false, &error);
- ASSERT_EQ(base::File::FILE_OK, error);
+ ASSERT_FALSE(ofu()
+ ->GetDirectoryForStorageKeyAndType(storage_key1,
+ kFileSystemTypeTemporary,
+ /*create=*/false)
+ .is_error());
+ ASSERT_FALSE(ofu()
+ ->GetDirectoryForStorageKeyAndType(storage_key1,
+ kFileSystemTypePersistent,
+ /*create=*/false)
+ .is_error());
// Make sure directories for storage_key2 exist.
- error = base::File::FILE_ERROR_FAILED;
- ofu()->GetDirectoryForStorageKeyAndType(
- storage_key2, GetTypeString(kFileSystemTypeTemporary), false, &error);
- ASSERT_EQ(base::File::FILE_OK, error);
- error = base::File::FILE_ERROR_FAILED;
- ofu()->GetDirectoryForStorageKeyAndType(
- storage_key2, GetTypeString(kFileSystemTypePersistent), false, &error);
- ASSERT_EQ(base::File::FILE_OK, error);
+ ASSERT_FALSE(ofu()
+ ->GetDirectoryForStorageKeyAndType(storage_key2,
+ kFileSystemTypeTemporary,
+ /*create=*/false)
+ .is_error());
+ ASSERT_FALSE(ofu()
+ ->GetDirectoryForStorageKeyAndType(storage_key2,
+ kFileSystemTypePersistent,
+ /*create=*/false)
+ .is_error());
// Delete a directory for storage_key1's persistent filesystem.
ASSERT_TRUE(ofu()->DeleteDirectoryForStorageKeyAndType(
- storage_key1, GetTypeString(kFileSystemTypePersistent)));
+ storage_key1, kFileSystemTypePersistent));
// The directory for storage_key1's temporary filesystem should not be
// removed.
- error = base::File::FILE_ERROR_FAILED;
- ofu()->GetDirectoryForStorageKeyAndType(
- storage_key1, GetTypeString(kFileSystemTypeTemporary), false, &error);
- ASSERT_EQ(base::File::FILE_OK, error);
+ ASSERT_FALSE(ofu()
+ ->GetDirectoryForStorageKeyAndType(storage_key1,
+ kFileSystemTypeTemporary,
+ /*create=*/false)
+ .is_error());
// The directory for storage_key1's persistent filesystem should be removed.
- error = base::File::FILE_ERROR_FAILED;
- ofu()->GetDirectoryForStorageKeyAndType(
- storage_key1, GetTypeString(kFileSystemTypePersistent), false, &error);
- ASSERT_EQ(base::File::FILE_ERROR_NOT_FOUND, error);
+ ASSERT_EQ(ofu()
+ ->GetDirectoryForStorageKeyAndType(storage_key1,
+ kFileSystemTypePersistent,
+ /*create=*/false)
+ .error(),
+ base::File::FILE_ERROR_NOT_FOUND);
// The directories for storage_key2 should not be removed.
- error = base::File::FILE_ERROR_FAILED;
- ofu()->GetDirectoryForStorageKeyAndType(
- storage_key2, GetTypeString(kFileSystemTypeTemporary), false, &error);
- ASSERT_EQ(base::File::FILE_OK, error);
- error = base::File::FILE_ERROR_FAILED;
- ofu()->GetDirectoryForStorageKeyAndType(
- storage_key2, GetTypeString(kFileSystemTypePersistent), false, &error);
- ASSERT_EQ(base::File::FILE_OK, error);
+ ASSERT_FALSE(ofu()
+ ->GetDirectoryForStorageKeyAndType(storage_key2,
+ kFileSystemTypeTemporary,
+ /*create=*/false)
+ .is_error());
+ ASSERT_FALSE(ofu()
+ ->GetDirectoryForStorageKeyAndType(storage_key2,
+ kFileSystemTypePersistent,
+ /*create=*/false)
+ .is_error());
// Make sure storage_key3's directories don't exist.
- error = base::File::FILE_ERROR_FAILED;
- ofu()->GetDirectoryForStorageKeyAndType(
- storage_key3, GetTypeString(kFileSystemTypeTemporary), false, &error);
- ASSERT_EQ(base::File::FILE_ERROR_NOT_FOUND, error);
- error = base::File::FILE_ERROR_FAILED;
- ofu()->GetDirectoryForStorageKeyAndType(
- storage_key3, GetTypeString(kFileSystemTypePersistent), false, &error);
- ASSERT_EQ(base::File::FILE_ERROR_NOT_FOUND, error);
+ ASSERT_EQ(ofu()
+ ->GetDirectoryForStorageKeyAndType(storage_key3,
+ kFileSystemTypeTemporary,
+ /*create=*/false)
+ .error(),
+ base::File::FILE_ERROR_NOT_FOUND);
+ ASSERT_EQ(ofu()
+ ->GetDirectoryForStorageKeyAndType(storage_key3,
+ kFileSystemTypePersistent,
+ /*create=*/false)
+ .error(),
+ base::File::FILE_ERROR_NOT_FOUND);
// Deleting directories which don't exist is not an error.
ASSERT_TRUE(ofu()->DeleteDirectoryForStorageKeyAndType(
- storage_key3, GetTypeString(kFileSystemTypeTemporary)));
+ storage_key3, kFileSystemTypeTemporary));
ASSERT_TRUE(ofu()->DeleteDirectoryForStorageKeyAndType(
- storage_key3, GetTypeString(kFileSystemTypePersistent)));
+ storage_key3, kFileSystemTypePersistent));
+}
+
+TEST_P(ObfuscatedFileUtilTest, DeleteDirectoryForBucketAndType_DeleteAll) {
+ // Create origin directories.
+ std::unique_ptr<SandboxFileSystemTestHelper> fs1 =
+ NewFileSystem(default_bucket_, kFileSystemTypeTemporary);
+ std::unique_ptr<SandboxFileSystemTestHelper> fs2 =
+ NewFileSystem(default_bucket_, kFileSystemTypePersistent);
+ std::unique_ptr<SandboxFileSystemTestHelper> fs3 =
+ NewFileSystem(custom_bucket_, kFileSystemTypeTemporary);
+ std::unique_ptr<SandboxFileSystemTestHelper> fs4 =
+ NewFileSystem(custom_bucket_, kFileSystemTypePersistent);
+
+ // Make sure directories for default_bucket_ exist.
+ ASSERT_FALSE(ofu()
+ ->GetDirectoryForBucketAndType(default_bucket_,
+ kFileSystemTypeTemporary,
+ /*create=*/false)
+ .is_error());
+ ASSERT_FALSE(ofu()
+ ->GetDirectoryForBucketAndType(default_bucket_,
+ kFileSystemTypePersistent,
+ /*create=*/false)
+ .is_error());
+
+ // Make sure directories for custom_bucket_ exist.
+ ASSERT_FALSE(ofu()
+ ->GetDirectoryForBucketAndType(custom_bucket_,
+ kFileSystemTypeTemporary,
+ /*create=*/false)
+ .is_error());
+ ASSERT_FALSE(ofu()
+ ->GetDirectoryForBucketAndType(custom_bucket_,
+ kFileSystemTypePersistent,
+ /*create=*/false)
+ .is_error());
+
+ // Delete all directories for default_bucket_.
+ ofu()->DeleteDirectoryForBucketAndType(default_bucket_, absl::nullopt);
+
+ // The directories for default_bucket_ should be removed.
+ ASSERT_EQ(ofu()
+ ->GetDirectoryForBucketAndType(default_bucket_,
+ kFileSystemTypeTemporary,
+ /*create=*/false)
+ .error(),
+ base::File::FILE_ERROR_NOT_FOUND);
+ ASSERT_EQ(ofu()
+ ->GetDirectoryForBucketAndType(default_bucket_,
+ kFileSystemTypePersistent,
+ /*create=*/false)
+ .error(),
+ base::File::FILE_ERROR_NOT_FOUND);
+
+ // The directories for custom_bucket_ should not be removed.
+ ASSERT_FALSE(ofu()
+ ->GetDirectoryForBucketAndType(custom_bucket_,
+ kFileSystemTypeTemporary,
+ /*create=*/false)
+ .is_error());
+ ASSERT_FALSE(ofu()
+ ->GetDirectoryForBucketAndType(custom_bucket_,
+ kFileSystemTypePersistent,
+ /*create=*/false)
+ .is_error());
}
-TEST_P(ObfuscatedFileUtilTest, DeleteDirectoryForOriginAndType_DeleteAll) {
+TEST_P(ObfuscatedFileUtilTest, DeleteDirectoryForStorageKeyAndType_DeleteAll) {
const blink::StorageKey storage_key1 =
blink::StorageKey::CreateFromStringForTesting(
"http://www.example.com:12");
@@ -2515,56 +2798,66 @@ TEST_P(ObfuscatedFileUtilTest, DeleteDirectoryForOriginAndType_DeleteAll) {
// Create origin directories.
std::unique_ptr<SandboxFileSystemTestHelper> fs1 =
- NewFileSystem(storage_key1.origin(), kFileSystemTypeTemporary);
+ NewFileSystem(storage_key1, kFileSystemTypeTemporary);
std::unique_ptr<SandboxFileSystemTestHelper> fs2 =
- NewFileSystem(storage_key1.origin(), kFileSystemTypePersistent);
+ NewFileSystem(storage_key1, kFileSystemTypePersistent);
std::unique_ptr<SandboxFileSystemTestHelper> fs3 =
- NewFileSystem(storage_key2.origin(), kFileSystemTypeTemporary);
+ NewFileSystem(storage_key2, kFileSystemTypeTemporary);
std::unique_ptr<SandboxFileSystemTestHelper> fs4 =
- NewFileSystem(storage_key2.origin(), kFileSystemTypePersistent);
+ NewFileSystem(storage_key2, kFileSystemTypePersistent);
// Make sure directories for storage_key1 exist.
- base::File::Error error = base::File::FILE_ERROR_FAILED;
- ofu()->GetDirectoryForStorageKeyAndType(
- storage_key1, GetTypeString(kFileSystemTypeTemporary), false, &error);
- ASSERT_EQ(base::File::FILE_OK, error);
- error = base::File::FILE_ERROR_FAILED;
- ofu()->GetDirectoryForStorageKeyAndType(
- storage_key1, GetTypeString(kFileSystemTypePersistent), false, &error);
- ASSERT_EQ(base::File::FILE_OK, error);
+ ASSERT_FALSE(ofu()
+ ->GetDirectoryForStorageKeyAndType(storage_key1,
+ kFileSystemTypeTemporary,
+ /*create=*/false)
+ .is_error());
+ ASSERT_FALSE(ofu()
+ ->GetDirectoryForStorageKeyAndType(storage_key1,
+ kFileSystemTypePersistent,
+ /*create=*/false)
+ .is_error());
// Make sure directories for storage_key2 exist.
- error = base::File::FILE_ERROR_FAILED;
- ofu()->GetDirectoryForStorageKeyAndType(
- storage_key2, GetTypeString(kFileSystemTypeTemporary), false, &error);
- ASSERT_EQ(base::File::FILE_OK, error);
- error = base::File::FILE_ERROR_FAILED;
- ofu()->GetDirectoryForStorageKeyAndType(
- storage_key2, GetTypeString(kFileSystemTypePersistent), false, &error);
- ASSERT_EQ(base::File::FILE_OK, error);
+ ASSERT_FALSE(ofu()
+ ->GetDirectoryForStorageKeyAndType(storage_key2,
+ kFileSystemTypeTemporary,
+ /*create=*/false)
+ .is_error());
+ ASSERT_FALSE(ofu()
+ ->GetDirectoryForStorageKeyAndType(storage_key2,
+ kFileSystemTypePersistent,
+ /*create=*/false)
+ .is_error());
// Delete all directories for storage_key1.
- ofu()->DeleteDirectoryForStorageKeyAndType(storage_key1, std::string());
+ ofu()->DeleteDirectoryForStorageKeyAndType(storage_key1, absl::nullopt);
// The directories for storage_key1 should be removed.
- error = base::File::FILE_ERROR_FAILED;
- ofu()->GetDirectoryForStorageKeyAndType(
- storage_key1, GetTypeString(kFileSystemTypeTemporary), false, &error);
- ASSERT_EQ(base::File::FILE_ERROR_NOT_FOUND, error);
- error = base::File::FILE_ERROR_FAILED;
- ofu()->GetDirectoryForStorageKeyAndType(
- storage_key1, GetTypeString(kFileSystemTypePersistent), false, &error);
- ASSERT_EQ(base::File::FILE_ERROR_NOT_FOUND, error);
+ ASSERT_EQ(ofu()
+ ->GetDirectoryForStorageKeyAndType(storage_key1,
+ kFileSystemTypeTemporary,
+ /*create=*/false)
+ .error(),
+ base::File::FILE_ERROR_NOT_FOUND);
+ ASSERT_EQ(ofu()
+ ->GetDirectoryForStorageKeyAndType(storage_key1,
+ kFileSystemTypePersistent,
+ /*create=*/false)
+ .error(),
+ base::File::FILE_ERROR_NOT_FOUND);
// The directories for storage_key2 should not be removed.
- error = base::File::FILE_ERROR_FAILED;
- ofu()->GetDirectoryForStorageKeyAndType(
- storage_key2, GetTypeString(kFileSystemTypeTemporary), false, &error);
- ASSERT_EQ(base::File::FILE_OK, error);
- error = base::File::FILE_ERROR_FAILED;
- ofu()->GetDirectoryForStorageKeyAndType(
- storage_key2, GetTypeString(kFileSystemTypePersistent), false, &error);
- ASSERT_EQ(base::File::FILE_OK, error);
+ ASSERT_FALSE(ofu()
+ ->GetDirectoryForStorageKeyAndType(storage_key2,
+ kFileSystemTypeTemporary,
+ /*create=*/false)
+ .is_error());
+ ASSERT_FALSE(ofu()
+ ->GetDirectoryForStorageKeyAndType(storage_key2,
+ kFileSystemTypePersistent,
+ /*create=*/false)
+ .is_error());
}
} // namespace storage
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
deleted file mode 100644
index faf7a36fb92..00000000000
--- a/chromium/storage/browser/file_system/plugin_private_file_system_backend.cc
+++ /dev/null
@@ -1,466 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "storage/browser/file_system/plugin_private_file_system_backend.h"
-
-#include <stdint.h>
-
-#include <map>
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/containers/contains.h"
-#include "base/files/file_enumerator.h"
-#include "base/files/file_path.h"
-#include "base/memory/scoped_refptr.h"
-#include "base/synchronization/lock.h"
-#include "base/task/task_runner_util.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/time/time.h"
-#include "storage/browser/file_system/async_file_util_adapter.h"
-#include "storage/browser/file_system/file_system_context.h"
-#include "storage/browser/file_system/file_system_operation.h"
-#include "storage/browser/file_system/file_system_operation_context.h"
-#include "storage/browser/file_system/isolated_context.h"
-#include "storage/browser/file_system/obfuscated_file_util.h"
-#include "storage/browser/file_system/obfuscated_file_util_memory_delegate.h"
-#include "storage/browser/file_system/quota/quota_reservation.h"
-#include "storage/browser/file_system/sandbox_file_stream_reader.h"
-#include "storage/browser/file_system/sandbox_file_stream_writer.h"
-#include "storage/browser/quota/special_storage_policy.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"
-
-namespace storage {
-
-class PluginPrivateFileSystemBackend::FileSystemIDToPluginMap {
- public:
- explicit FileSystemIDToPluginMap(
- scoped_refptr<base::SequencedTaskRunner> task_runner)
- : task_runner_(std::move(task_runner)) {}
- ~FileSystemIDToPluginMap() = default;
-
- std::string GetPluginIDForURL(const FileSystemURL& url) {
- DCHECK(task_runner_->RunsTasksInCurrentSequence());
- auto found = map_.find(url.filesystem_id());
- if (url.type() != kFileSystemTypePluginPrivate || found == map_.end()) {
- NOTREACHED() << "Unsupported url is given: " << url.DebugString();
- return std::string();
- }
- return found->second;
- }
-
- void RegisterFileSystem(const std::string& filesystem_id,
- const std::string& plugin_id) {
- DCHECK(task_runner_->RunsTasksInCurrentSequence());
- DCHECK(!filesystem_id.empty());
- DCHECK(!base::Contains(map_, filesystem_id)) << filesystem_id;
- map_[filesystem_id] = plugin_id;
- }
-
- void RemoveFileSystem(const std::string& filesystem_id) {
- DCHECK(task_runner_->RunsTasksInCurrentSequence());
- map_.erase(filesystem_id);
- }
-
- private:
- using Map = std::map<std::string, std::string>;
- const scoped_refptr<base::SequencedTaskRunner> task_runner_;
- Map map_;
-};
-
-namespace {
-
-const base::FilePath::CharType* kFileSystemDirectory =
- SandboxFileSystemBackendDelegate::kFileSystemDirectory;
-const base::FilePath::CharType* kPluginPrivateDirectory =
- FILE_PATH_LITERAL("Plugins");
-
-base::File::Error OpenFileSystemOnFileTaskRunner(
- ObfuscatedFileUtil* file_util,
- PluginPrivateFileSystemBackend::FileSystemIDToPluginMap* plugin_map,
- const url::Origin& origin,
- const std::string& filesystem_id,
- const std::string& plugin_id,
- OpenFileSystemMode mode) {
- base::File::Error error = base::File::FILE_ERROR_FAILED;
- const bool create = (mode == OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT);
- // 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;
-}
-
-} // namespace
-
-PluginPrivateFileSystemBackend::CdmFileInfo::CdmFileInfo(
- const std::string& name,
- const std::string& legacy_file_system_id)
- : name(name), legacy_file_system_id(legacy_file_system_id) {}
-PluginPrivateFileSystemBackend::CdmFileInfo::CdmFileInfo(const CdmFileInfo&) =
- default;
-PluginPrivateFileSystemBackend::CdmFileInfo::CdmFileInfo(CdmFileInfo&&) =
- default;
-PluginPrivateFileSystemBackend::CdmFileInfo::~CdmFileInfo() = default;
-
-PluginPrivateFileSystemBackend::PluginPrivateFileSystemBackend(
- scoped_refptr<base::SequencedTaskRunner> file_task_runner,
- const base::FilePath& profile_path,
- scoped_refptr<SpecialStoragePolicy> special_storage_policy,
- const FileSystemOptions& file_system_options,
- leveldb::Env* env_override)
- : file_task_runner_(std::move(file_task_runner)),
- file_system_options_(file_system_options),
- base_path_(profile_path.Append(kFileSystemDirectory)
- .Append(kPluginPrivateDirectory)),
- plugin_map_(new FileSystemIDToPluginMap(file_task_runner_)) {
- file_util_ = std::make_unique<AsyncFileUtilAdapter>(
- std::make_unique<ObfuscatedFileUtil>(
- std::move(special_storage_policy), base_path_, env_override,
- base::BindRepeating(&FileSystemIDToPluginMap::GetPluginIDForURL,
- base::Owned(plugin_map_.get())),
- std::set<std::string>(), nullptr,
- file_system_options.is_incognito()));
-}
-
-PluginPrivateFileSystemBackend::~PluginPrivateFileSystemBackend() {
- if (!file_task_runner_->RunsTasksInCurrentSequence()) {
- AsyncFileUtil* file_util = file_util_.release();
- if (!file_task_runner_->DeleteSoon(FROM_HERE, file_util))
- delete file_util;
- }
-}
-
-void PluginPrivateFileSystemBackend::OpenPrivateFileSystem(
- const url::Origin& origin,
- FileSystemType type,
- const std::string& filesystem_id,
- const std::string& plugin_id,
- OpenFileSystemMode mode,
- StatusCallback callback) {
- if (!CanHandleType(type)) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(callback), base::File::FILE_ERROR_SECURITY));
- return;
- }
-
- PostTaskAndReplyWithResult(
- file_task_runner_.get(), FROM_HERE,
- base::BindOnce(&OpenFileSystemOnFileTaskRunner, obfuscated_file_util(),
- plugin_map_, origin, filesystem_id, plugin_id, mode),
- std::move(callback));
-}
-
-bool PluginPrivateFileSystemBackend::CanHandleType(FileSystemType type) const {
- return type == kFileSystemTypePluginPrivate;
-}
-
-void PluginPrivateFileSystemBackend::Initialize(FileSystemContext* context) {}
-
-void PluginPrivateFileSystemBackend::ResolveURL(const FileSystemURL& url,
- OpenFileSystemMode mode,
- ResolveURLCallback callback) {
- // We never allow opening a new plugin-private filesystem via usual
- // ResolveURL.
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), GURL(), std::string(),
- base::File::FILE_ERROR_SECURITY));
-}
-
-AsyncFileUtil* PluginPrivateFileSystemBackend::GetAsyncFileUtil(
- FileSystemType type) {
- return file_util_.get();
-}
-
-WatcherManager* PluginPrivateFileSystemBackend::GetWatcherManager(
- FileSystemType type) {
- return nullptr;
-}
-
-CopyOrMoveFileValidatorFactory*
-PluginPrivateFileSystemBackend::GetCopyOrMoveFileValidatorFactory(
- FileSystemType type,
- base::File::Error* error_code) {
- DCHECK(error_code);
- *error_code = base::File::FILE_OK;
- return nullptr;
-}
-
-std::unique_ptr<FileSystemOperation>
-PluginPrivateFileSystemBackend::CreateFileSystemOperation(
- const FileSystemURL& url,
- FileSystemContext* context,
- base::File::Error* error_code) const {
- auto operation_context =
- std::make_unique<FileSystemOperationContext>(context);
- return FileSystemOperation::Create(url, context,
- std::move(operation_context));
-}
-
-bool PluginPrivateFileSystemBackend::SupportsStreaming(
- const FileSystemURL& url) const {
- // Streaming is required for incognito file systems in order to access
- // memory-backed files.
- DCHECK(CanHandleType(url.type()));
- return file_system_options_.is_incognito();
-}
-
-bool PluginPrivateFileSystemBackend::HasInplaceCopyImplementation(
- FileSystemType type) const {
- return false;
-}
-
-std::unique_ptr<FileStreamReader>
-PluginPrivateFileSystemBackend::CreateFileStreamReader(
- const FileSystemURL& url,
- int64_t offset,
- int64_t max_bytes_to_read,
- const base::Time& expected_modification_time,
- FileSystemContext* context) const {
- DCHECK(CanHandleType(url.type()));
- return std::make_unique<SandboxFileStreamReader>(context, url, offset,
- expected_modification_time);
-}
-
-std::unique_ptr<FileStreamWriter>
-PluginPrivateFileSystemBackend::CreateFileStreamWriter(
- const FileSystemURL& url,
- int64_t offset,
- FileSystemContext* context) const {
- DCHECK(CanHandleType(url.type()));
-
- // Observers not supported by PluginPrivateFileSystemBackend.
- return std::make_unique<SandboxFileStreamWriter>(context, url, offset,
- UpdateObserverList());
-}
-
-FileSystemQuotaUtil* PluginPrivateFileSystemBackend::GetQuotaUtil() {
- return this;
-}
-
-base::File::Error
-PluginPrivateFileSystemBackend::DeleteStorageKeyDataOnFileTaskRunner(
- FileSystemContext* context,
- QuotaManagerProxy* proxy,
- const blink::StorageKey& storage_key,
- FileSystemType type) {
- if (!CanHandleType(type))
- return base::File::FILE_ERROR_SECURITY;
- bool result = obfuscated_file_util()->DeleteDirectoryForStorageKeyAndType(
- storage_key, std::string());
- if (result)
- return base::File::FILE_OK;
- return base::File::FILE_ERROR_FAILED;
-}
-
-void PluginPrivateFileSystemBackend::PerformStorageCleanupOnFileTaskRunner(
- FileSystemContext* context,
- QuotaManagerProxy* proxy,
- FileSystemType type) {
- if (!CanHandleType(type))
- return;
- obfuscated_file_util()->RewriteDatabases();
-}
-
-std::vector<blink::StorageKey>
-PluginPrivateFileSystemBackend::GetStorageKeysForTypeOnFileTaskRunner(
- FileSystemType type) {
- if (!CanHandleType(type))
- 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;
-}
-
-int64_t PluginPrivateFileSystemBackend::GetStorageKeyUsageOnFileTaskRunner(
- FileSystemContext* context,
- const blink::StorageKey& storage_key,
- FileSystemType type) {
- DCHECK(file_task_runner_->RunsTasksInCurrentSequence());
-
- if (!CanHandleType(type))
- return 0;
-
- int64_t total_size;
- base::Time last_modified_time;
- GetOriginDetailsOnFileTaskRunner(context, storage_key.origin(), &total_size,
- &last_modified_time);
- return total_size;
-}
-
-void PluginPrivateFileSystemBackend::GetOriginDetailsOnFileTaskRunner(
- FileSystemContext* context,
- const url::Origin& origin,
- int64_t* total_size,
- base::Time* last_modified_time) {
- DCHECK(file_task_runner_->RunsTasksInCurrentSequence());
-
- *total_size = 0;
- *last_modified_time = base::Time::UnixEpoch();
- std::string fsid =
- IsolatedContext::GetInstance()->RegisterFileSystemForVirtualPath(
- kFileSystemTypePluginPrivate, kPluginPrivateRootName,
- base::FilePath());
- DCHECK(ValidateIsolatedFileSystemId(fsid));
-
- std::string root = GetIsolatedFileSystemRootURIString(origin.GetURL(), fsid,
- kPluginPrivateRootName);
-
- std::unique_ptr<FileSystemOperationContext> operation_context(
- std::make_unique<FileSystemOperationContext>(context));
-
- // Determine the available plugin private filesystem directories for this
- // origin. Currently the plugin private filesystem is only used by Encrypted
- // Media Content Decryption Modules. Each CDM gets a directory based on the
- // mimetype (e.g. plugin application/x-ppapi-widevine-cdm uses directory
- // 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;
- // 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;
- }
-
- base::FileEnumerator directory_enumerator(path, false,
- base::FileEnumerator::DIRECTORIES);
- base::FilePath plugin_path;
- while (!(plugin_path = directory_enumerator.Next()).empty()) {
- std::string plugin_name = plugin_path.BaseName().MaybeAsASCII();
- if (OpenFileSystemOnFileTaskRunner(
- obfuscated_file_util(), plugin_map_, origin, fsid, plugin_name,
- OPEN_FILE_SYSTEM_FAIL_IF_NONEXISTENT) != base::File::FILE_OK) {
- continue;
- }
-
- // TODO(https://crbug.com/1231162): determine whether EME/CDM/plugin private
- // file system will be partitioned and use the appropriate StorageKey
- std::unique_ptr<FileSystemFileUtil::AbstractFileEnumerator> enumerator(
- obfuscated_file_util()->CreateFileEnumerator(
- operation_context.get(),
- context->CrackURL(
- GURL(root), blink::StorageKey(url::Origin::Create(GURL(root)))),
- true));
-
- while (!enumerator->Next().empty()) {
- *total_size += enumerator->Size();
- if (enumerator->LastModifiedTime() > *last_modified_time)
- *last_modified_time = enumerator->LastModifiedTime();
- }
- }
-}
-
-std::vector<PluginPrivateFileSystemBackend::CdmFileInfo>
-PluginPrivateFileSystemBackend::GetMediaLicenseFilesForOriginOnFileTaskRunner(
- FileSystemContext* context,
- const url::Origin& origin) {
- DCHECK(file_task_runner_->RunsTasksInCurrentSequence());
-
- std::unique_ptr<FileSystemOperationContext> operation_context(
- std::make_unique<FileSystemOperationContext>(context));
-
- // Determine the available plugin private filesystem directories for this
- // origin. Currently the plugin private filesystem is only used by Encrypted
- // Media Content Decryption Modules. Each CDM gets a directory based on the
- // mimetype (e.g. plugin application/x-ppapi-widevine-cdm uses directory
- // 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()->GetDirectoryForStorageKeyAndType(
- blink::StorageKey(origin), "", false, &error);
- if (error != base::File::FILE_OK)
- return {};
-
- std::vector<CdmFileInfo> cdm_files;
- base::FileEnumerator directory_enumerator(path, false,
- base::FileEnumerator::DIRECTORIES);
- base::FilePath plugin_path;
- while (!(plugin_path = directory_enumerator.Next()).empty()) {
- std::string plugin_name = plugin_path.BaseName().MaybeAsASCII();
-
- std::string fsid =
- IsolatedContext::GetInstance()->RegisterFileSystemForVirtualPath(
- kFileSystemTypePluginPrivate, kPluginPrivateRootName,
- base::FilePath());
- DCHECK(ValidateIsolatedFileSystemId(fsid));
- std::string root = GetIsolatedFileSystemRootURIString(
- origin.GetURL(), fsid, kPluginPrivateRootName);
-
- if (OpenFileSystemOnFileTaskRunner(
- obfuscated_file_util(), plugin_map_, origin, fsid, plugin_name,
- OPEN_FILE_SYSTEM_FAIL_IF_NONEXISTENT) != base::File::FILE_OK) {
- continue;
- }
- std::unique_ptr<FileSystemFileUtil::AbstractFileEnumerator> enumerator(
- obfuscated_file_util()->CreateFileEnumerator(
- operation_context.get(),
- context->CrackURL(
- GURL(root), blink::StorageKey(url::Origin::Create(GURL(root)))),
- true));
-
- base::FilePath cdm_file_path;
- while (!(cdm_file_path = enumerator->Next()).empty()) {
- cdm_files.emplace_back(cdm_file_path.BaseName().AsUTF8Unsafe(),
- plugin_path.BaseName().AsUTF8Unsafe());
- }
- }
-
- return cdm_files;
-}
-
-scoped_refptr<QuotaReservation>
-PluginPrivateFileSystemBackend::CreateQuotaReservationOnFileTaskRunner(
- const blink::StorageKey& storage_key,
- FileSystemType type) {
- // We don't track usage on this filesystem.
- NOTREACHED();
- return scoped_refptr<QuotaReservation>();
-}
-
-const UpdateObserverList* PluginPrivateFileSystemBackend::GetUpdateObservers(
- FileSystemType type) const {
- return nullptr;
-}
-
-const ChangeObserverList* PluginPrivateFileSystemBackend::GetChangeObservers(
- FileSystemType type) const {
- return nullptr;
-}
-
-const AccessObserverList* PluginPrivateFileSystemBackend::GetAccessObservers(
- FileSystemType type) const {
- return nullptr;
-}
-
-ObfuscatedFileUtil* PluginPrivateFileSystemBackend::obfuscated_file_util() {
- return static_cast<ObfuscatedFileUtil*>(
- static_cast<AsyncFileUtilAdapter*>(file_util_.get())->sync_file_util());
-}
-
-ObfuscatedFileUtilMemoryDelegate*
-PluginPrivateFileSystemBackend::obfuscated_file_util_memory_delegate() {
- auto* file_util = obfuscated_file_util();
- DCHECK(file_util->is_incognito());
- return static_cast<ObfuscatedFileUtilMemoryDelegate*>(file_util->delegate());
-}
-
-} // namespace storage
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
deleted file mode 100644
index 29c7ecc1f8a..00000000000
--- a/chromium/storage/browser/file_system/plugin_private_file_system_backend.h
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef STORAGE_BROWSER_FILE_SYSTEM_PLUGIN_PRIVATE_FILE_SYSTEM_BACKEND_H_
-#define STORAGE_BROWSER_FILE_SYSTEM_PLUGIN_PRIVATE_FILE_SYSTEM_BACKEND_H_
-
-#include <stdint.h>
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/component_export.h"
-#include "base/memory/raw_ptr.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "storage/browser/file_system/file_system_backend.h"
-#include "storage/browser/file_system/file_system_options.h"
-#include "storage/browser/file_system/file_system_quota_util.h"
-#include "storage/browser/file_system/task_runner_bound_observer_list.h"
-
-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 {
-
-class ObfuscatedFileUtil;
-class ObfuscatedFileUtilMemoryDelegate;
-class SpecialStoragePolicy;
-class WatcherManager;
-
-// TODO(crbug.com/1231162): Remove this when removing the plugin private FS.
-// Name of the root directory in the plugin private file system.
-const char kPluginPrivateRootName[] = "pluginprivate";
-
-class COMPONENT_EXPORT(STORAGE_BROWSER) PluginPrivateFileSystemBackend
- : public FileSystemBackend,
- public FileSystemQuotaUtil {
- public:
- class FileSystemIDToPluginMap;
- using StatusCallback = base::OnceCallback<void(base::File::Error result)>;
-
- // Used to migrate media license data to the new backend.
- struct COMPONENT_EXPORT(STORAGE_BROWSER) CdmFileInfo {
- CdmFileInfo(const std::string& name,
- const std::string& legacy_file_system_id);
- CdmFileInfo(const CdmFileInfo&);
- CdmFileInfo(CdmFileInfo&&);
- ~CdmFileInfo();
-
- const std::string name;
- const std::string legacy_file_system_id;
- };
-
- PluginPrivateFileSystemBackend(
- scoped_refptr<base::SequencedTaskRunner> file_task_runner,
- const base::FilePath& profile_path,
- 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
- // OpenFileSystem.
- // |plugin_id| must be an identifier string for per-plugin
- // isolation, e.g. name, MIME type etc.
- // NOTE: |plugin_id| must be sanitized ASCII string that doesn't
- // include *any* dangerous character like '/'.
- void OpenPrivateFileSystem(const url::Origin& origin,
- FileSystemType type,
- const std::string& filesystem_id,
- const std::string& plugin_id,
- OpenFileSystemMode mode,
- StatusCallback callback);
-
- // FileSystemBackend overrides.
- bool CanHandleType(FileSystemType type) const override;
- void Initialize(FileSystemContext* context) override;
- void ResolveURL(const FileSystemURL& url,
- OpenFileSystemMode mode,
- ResolveURLCallback callback) override;
- AsyncFileUtil* GetAsyncFileUtil(FileSystemType type) override;
- WatcherManager* GetWatcherManager(FileSystemType type) override;
- CopyOrMoveFileValidatorFactory* GetCopyOrMoveFileValidatorFactory(
- FileSystemType type,
- base::File::Error* error_code) override;
- std::unique_ptr<FileSystemOperation> CreateFileSystemOperation(
- const FileSystemURL& url,
- FileSystemContext* context,
- base::File::Error* error_code) const override;
- bool SupportsStreaming(const FileSystemURL& url) const override;
- bool HasInplaceCopyImplementation(FileSystemType type) const override;
- std::unique_ptr<FileStreamReader> CreateFileStreamReader(
- const FileSystemURL& url,
- int64_t offset,
- int64_t max_bytes_to_read,
- const base::Time& expected_modification_time,
- FileSystemContext* context) const override;
- std::unique_ptr<FileStreamWriter> CreateFileStreamWriter(
- const FileSystemURL& url,
- int64_t offset,
- FileSystemContext* context) const override;
- FileSystemQuotaUtil* GetQuotaUtil() override;
- const UpdateObserverList* GetUpdateObservers(
- FileSystemType type) const override;
- const ChangeObserverList* GetChangeObservers(
- FileSystemType type) const override;
- const AccessObserverList* GetAccessObservers(
- FileSystemType type) const override;
-
- // FileSystemQuotaUtil overrides.
- base::File::Error DeleteStorageKeyDataOnFileTaskRunner(
- FileSystemContext* context,
- QuotaManagerProxy* proxy,
- const blink::StorageKey& storage_key,
- FileSystemType type) override;
- void PerformStorageCleanupOnFileTaskRunner(FileSystemContext* context,
- QuotaManagerProxy* proxy,
- FileSystemType type) override;
- std::vector<blink::StorageKey> GetStorageKeysForTypeOnFileTaskRunner(
- FileSystemType type) override;
- int64_t GetStorageKeyUsageOnFileTaskRunner(
- FileSystemContext* context,
- const blink::StorageKey& storage_key,
- FileSystemType type) override;
- scoped_refptr<QuotaReservation> CreateQuotaReservationOnFileTaskRunner(
- const blink::StorageKey& storage_key,
- FileSystemType type) override;
-
- // Get details on the files saved for the specified |origin_url|. Returns
- // the total size and last modified time for the set of all files stored
- // for the particular origin. |total_size| = 0 and |last_modified_time| =
- // base::Time::UnixEpoch() if no files found.
- void GetOriginDetailsOnFileTaskRunner(FileSystemContext* context,
- const url::Origin& origin,
- int64_t* total_size,
- base::Time* last_modified_time);
-
- // Used to migrate media license data to the new backend.
- // TODO(crbug.com/1231162): Once all media license data has been migrated, the
- // PPFS will have no more consumers and we can remove it entirely.
- std::vector<CdmFileInfo> GetMediaLicenseFilesForOriginOnFileTaskRunner(
- FileSystemContext* context,
- const url::Origin& origin);
-
- ObfuscatedFileUtilMemoryDelegate* obfuscated_file_util_memory_delegate();
- const base::FilePath& base_path() const { return base_path_; }
-
- private:
- friend class PluginPrivateFileSystemBackendTest;
-
- ObfuscatedFileUtil* obfuscated_file_util();
-
- const scoped_refptr<base::SequencedTaskRunner> file_task_runner_;
- const FileSystemOptions file_system_options_;
- const base::FilePath base_path_;
- std::unique_ptr<AsyncFileUtil> file_util_;
- raw_ptr<FileSystemIDToPluginMap> plugin_map_; // Owned by file_util_.
- base::WeakPtrFactory<PluginPrivateFileSystemBackend> weak_factory_{this};
-};
-
-} // namespace storage
-
-#endif // STORAGE_BROWSER_FILE_SYSTEM_PLUGIN_PRIVATE_FILE_SYSTEM_BACKEND_H_
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
deleted file mode 100644
index f162888f09a..00000000000
--- a/chromium/storage/browser/file_system/plugin_private_file_system_backend_unittest.cc
+++ /dev/null
@@ -1,268 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <memory>
-
-#include "base/bind.h"
-#include "base/files/file_util.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/run_loop.h"
-#include "base/test/task_environment.h"
-#include "storage/browser/file_system/file_system_context.h"
-#include "storage/browser/file_system/isolated_context.h"
-#include "storage/browser/file_system/obfuscated_file_util.h"
-#include "storage/browser/file_system/plugin_private_file_system_backend.h"
-#include "storage/browser/quota/quota_manager_proxy.h"
-#include "storage/browser/test/async_file_test_helper.h"
-#include "storage/browser/test/test_file_system_context.h"
-#include "storage/browser/test/test_file_system_options.h"
-#include "storage/common/file_system/file_system_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/common/storage_key/storage_key.h"
-#include "url/gurl.h"
-#include "url/origin.h"
-
-using url::Origin;
-
-namespace storage {
-
-namespace {
-
-const FileSystemType kType = kFileSystemTypePluginPrivate;
-
-void DidOpenFileSystem(base::File::Error* error_out, base::File::Error error) {
- *error_out = error;
-}
-
-} // namespace
-
-class PluginPrivateFileSystemBackendTest : public testing::Test {
- protected:
- void SetUp() override {
- ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
- context_ = CreateFileSystemContextForTesting(
- /*quota_manager_proxy=*/nullptr, data_dir_.GetPath());
- }
-
- // TODO(https://crbug.com/1231162): determine whether EME/CDM/plugin private
- // file system will be partitioned and use the appropriate StorageKey
- FileSystemURL CreateURL(const GURL& root_url, const std::string& relative) {
- FileSystemURL root = context_->CrackURL(
- root_url, blink::StorageKey(url::Origin::Create(root_url)));
- return context_->CreateCrackedFileSystemURL(
- root.storage_key(), root.mount_type(),
- root.virtual_path().AppendASCII(relative));
- }
-
- PluginPrivateFileSystemBackend* backend() const {
- return context_->plugin_private_backend();
- }
-
- std::string RegisterFileSystem() {
- return IsolatedContext::GetInstance()->RegisterFileSystemForVirtualPath(
- kType, kRootName, base::FilePath());
- }
-
- const base::FilePath& base_path() const { return backend()->base_path(); }
-
- const std::string kPlugin1 = "plugin1";
- const std::string kPlugin2 = "plugin2";
- const std::string kRootName = "pluginprivate";
-
- base::ScopedTempDir data_dir_;
- base::test::SingleThreadTaskEnvironment task_environment_;
- scoped_refptr<FileSystemContext> context_;
-};
-
-// TODO(kinuko,nhiroki): There are a lot of duplicate code in these tests. Write
-// helper functions to simplify the tests.
-
-TEST_F(PluginPrivateFileSystemBackendTest, OpenFileSystemBasic) {
- const Origin kOrigin = Origin::Create(GURL("http://www.example.com"));
-
- const std::string filesystem_id1 = RegisterFileSystem();
- base::File::Error error = base::File::FILE_ERROR_FAILED;
- backend()->OpenPrivateFileSystem(kOrigin, kType, filesystem_id1, kPlugin1,
- OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
- base::BindOnce(&DidOpenFileSystem, &error));
- base::RunLoop().RunUntilIdle();
- ASSERT_EQ(base::File::FILE_OK, error);
-
- // Run this again with FAIL_IF_NONEXISTENT to see if it succeeds.
- const std::string filesystem_id2 = RegisterFileSystem();
- error = base::File::FILE_ERROR_FAILED;
- backend()->OpenPrivateFileSystem(kOrigin, kType, filesystem_id2, kPlugin1,
- OPEN_FILE_SYSTEM_FAIL_IF_NONEXISTENT,
- base::BindOnce(&DidOpenFileSystem, &error));
- base::RunLoop().RunUntilIdle();
- ASSERT_EQ(base::File::FILE_OK, error);
-
- const GURL root_url(GetIsolatedFileSystemRootURIString(
- kOrigin.GetURL(), filesystem_id1, kRootName));
- FileSystemURL file = CreateURL(root_url, "foo");
- base::FilePath platform_path;
- EXPECT_EQ(base::File::FILE_OK,
- AsyncFileTestHelper::CreateFile(context_.get(), file));
- EXPECT_EQ(base::File::FILE_OK, AsyncFileTestHelper::GetPlatformPath(
- context_.get(), file, &platform_path));
- EXPECT_TRUE(base_path().AppendASCII("000").AppendASCII(kPlugin1).IsParent(
- platform_path));
-}
-
-TEST_F(PluginPrivateFileSystemBackendTest, PluginIsolation) {
- const Origin kOrigin = Origin::Create(GURL("http://www.example.com"));
-
- // Open filesystem for kPlugin1 and kPlugin2.
- const std::string filesystem_id1 = RegisterFileSystem();
- base::File::Error error = base::File::FILE_ERROR_FAILED;
- backend()->OpenPrivateFileSystem(kOrigin, kType, filesystem_id1, kPlugin1,
- OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
- base::BindOnce(&DidOpenFileSystem, &error));
- base::RunLoop().RunUntilIdle();
- ASSERT_EQ(base::File::FILE_OK, error);
-
- const std::string filesystem_id2 = RegisterFileSystem();
- error = base::File::FILE_ERROR_FAILED;
- backend()->OpenPrivateFileSystem(kOrigin, kType, filesystem_id2, kPlugin2,
- OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
- base::BindOnce(&DidOpenFileSystem, &error));
- base::RunLoop().RunUntilIdle();
- ASSERT_EQ(base::File::FILE_OK, error);
-
- // Create 'foo' in kPlugin1.
- const GURL root_url1(GetIsolatedFileSystemRootURIString(
- kOrigin.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));
-
- // See the same path is not available in kPlugin2.
- const GURL root_url2(GetIsolatedFileSystemRootURIString(
- kOrigin.GetURL(), filesystem_id2, kRootName));
- FileSystemURL file2 = CreateURL(root_url2, "foo");
- EXPECT_FALSE(AsyncFileTestHelper::FileExists(
- context_.get(), file2, AsyncFileTestHelper::kDontCheckSize));
-}
-
-TEST_F(PluginPrivateFileSystemBackendTest, OriginIsolation) {
- const Origin kOrigin1 = Origin::Create(GURL("http://www.example.com"));
- const Origin kOrigin2 = Origin::Create(GURL("https://www.example.com"));
-
- // Open filesystem for kOrigin1 and kOrigin2.
- const std::string filesystem_id1 = RegisterFileSystem();
- base::File::Error error = base::File::FILE_ERROR_FAILED;
- backend()->OpenPrivateFileSystem(kOrigin1, kType, filesystem_id1, kPlugin1,
- OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
- base::BindOnce(&DidOpenFileSystem, &error));
- base::RunLoop().RunUntilIdle();
- ASSERT_EQ(base::File::FILE_OK, error);
-
- const std::string filesystem_id2 = RegisterFileSystem();
- error = base::File::FILE_ERROR_FAILED;
- backend()->OpenPrivateFileSystem(kOrigin2, 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.
- const GURL root_url1(GetIsolatedFileSystemRootURIString(
- kOrigin1.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));
-
- // See the same path is not available in kOrigin2.
- const GURL root_url2(GetIsolatedFileSystemRootURIString(
- kOrigin2.GetURL(), filesystem_id2, kRootName));
- FileSystemURL file2 = CreateURL(root_url2, "foo");
- EXPECT_FALSE(AsyncFileTestHelper::FileExists(
- context_.get(), file2, AsyncFileTestHelper::kDontCheckSize));
-}
-
-TEST_F(PluginPrivateFileSystemBackendTest, DeleteOriginDirectory) {
- 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 kStorageKey1.origin() and kStorageKey2.origin().
- const std::string filesystem_id1 = RegisterFileSystem();
- base::File::Error error = base::File::FILE_ERROR_FAILED;
- backend()->OpenPrivateFileSystem(kStorageKey1.origin(), kType, filesystem_id1,
- kPlugin1,
- OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
- base::BindOnce(&DidOpenFileSystem, &error));
- base::RunLoop().RunUntilIdle();
- ASSERT_EQ(base::File::FILE_OK, error);
-
- const std::string filesystem_id2 = RegisterFileSystem();
- error = base::File::FILE_ERROR_FAILED;
- 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 kStorageKey1.origin().
- const GURL root_url1(GetIsolatedFileSystemRootURIString(
- 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 kStorageKey2.origin().
- const GURL root_url2(GetIsolatedFileSystemRootURIString(
- 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 kStorageKey1.origin().
- error = backend()->DeleteStorageKeyDataOnFileTaskRunner(
- context_.get(), nullptr, kStorageKey1, kType);
- EXPECT_EQ(base::File::FILE_OK, error);
-
- // Confirm 'foo' in kStorageKey1.origin() is deleted.
- EXPECT_FALSE(AsyncFileTestHelper::FileExists(
- context_.get(), file1, AsyncFileTestHelper::kDontCheckSize));
-
- // Confirm 'foo' in kStorageKey2.origin() is NOT deleted.
- EXPECT_TRUE(AsyncFileTestHelper::FileExists(
- context_.get(), file2, AsyncFileTestHelper::kDontCheckSize));
-
- // Re-open filesystem for kStorageKey1.origin().
- const std::string filesystem_id3 = RegisterFileSystem();
- error = base::File::FILE_ERROR_FAILED;
- 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 kStorageKey1.origin().
- const GURL root_url3(GetIsolatedFileSystemRootURIString(
- 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 kStorageKey1.origin() is re-created.
- EXPECT_TRUE(AsyncFileTestHelper::FileExists(
- context_.get(), file3, AsyncFileTestHelper::kDontCheckSize));
-}
-
-} // 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 618bc3a7978..b6e7e81b5ea 100644
--- a/chromium/storage/browser/file_system/quota/quota_backend_impl.cc
+++ b/chromium/storage/browser/file_system/quota/quota_backend_impl.cc
@@ -13,6 +13,7 @@
#include "base/bind.h"
#include "base/callback.h"
#include "base/check_op.h"
+#include "base/files/file_error_or.h"
#include "base/numerics/safe_conversions.h"
#include "base/task/sequenced_task_runner.h"
#include "storage/browser/file_system/file_system_usage_cache.h"
@@ -76,10 +77,11 @@ void QuotaBackendImpl::CommitQuotaUsage(const url::Origin& origin,
if (!delta)
return;
ReserveQuotaInternal(QuotaReservationInfo(origin, type, delta));
- base::FilePath path;
- if (GetUsageCachePath(origin, type, &path) != base::File::FILE_OK)
+ base::FileErrorOr<base::FilePath> path = GetUsageCachePath(origin, type);
+ if (path.is_error())
return;
- bool result = file_system_usage_cache_->AtomicUpdateUsageByDelta(path, delta);
+ bool result =
+ file_system_usage_cache_->AtomicUpdateUsageByDelta(path.value(), delta);
DCHECK(result);
}
@@ -87,22 +89,22 @@ void QuotaBackendImpl::IncrementDirtyCount(const url::Origin& origin,
FileSystemType type) {
DCHECK(file_task_runner_->RunsTasksInCurrentSequence());
DCHECK(!origin.opaque());
- base::FilePath path;
- if (GetUsageCachePath(origin, type, &path) != base::File::FILE_OK)
+ base::FileErrorOr<base::FilePath> path = GetUsageCachePath(origin, type);
+ if (path.is_error())
return;
DCHECK(file_system_usage_cache_);
- file_system_usage_cache_->IncrementDirty(path);
+ file_system_usage_cache_->IncrementDirty(path.value());
}
void QuotaBackendImpl::DecrementDirtyCount(const url::Origin& origin,
FileSystemType type) {
DCHECK(file_task_runner_->RunsTasksInCurrentSequence());
DCHECK(!origin.opaque());
- base::FilePath path;
- if (GetUsageCachePath(origin, type, &path) != base::File::FILE_OK)
+ base::FileErrorOr<base::FilePath> path = GetUsageCachePath(origin, type);
+ if (path.is_error())
return;
DCHECK(file_system_usage_cache_);
- file_system_usage_cache_->DecrementDirty(path);
+ file_system_usage_cache_->DecrementDirty(path.value());
}
void QuotaBackendImpl::DidGetUsageAndQuotaForReserveQuota(
@@ -149,18 +151,14 @@ void QuotaBackendImpl::ReserveQuotaInternal(const QuotaReservationInfo& info) {
base::DoNothing());
}
-base::File::Error QuotaBackendImpl::GetUsageCachePath(
+base::FileErrorOr<base::FilePath> QuotaBackendImpl::GetUsageCachePath(
const url::Origin& origin,
- FileSystemType type,
- base::FilePath* usage_file_path) {
+ FileSystemType type) {
DCHECK(file_task_runner_->RunsTasksInCurrentSequence());
DCHECK(!origin.opaque());
- DCHECK(usage_file_path);
- base::File::Error error = base::File::FILE_OK;
- *usage_file_path =
- SandboxFileSystemBackendDelegate::GetUsageCachePathForStorageKeyAndType(
- obfuscated_file_util_, blink::StorageKey(origin), type, &error);
- return error;
+ return SandboxFileSystemBackendDelegate::
+ GetUsageCachePathForStorageKeyAndType(obfuscated_file_util_,
+ blink::StorageKey(origin), type);
}
QuotaBackendImpl::QuotaReservationInfo::QuotaReservationInfo(
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 7b3415dd6d7..8bb50a14b66 100644
--- a/chromium/storage/browser/file_system/quota/quota_backend_impl.h
+++ b/chromium/storage/browser/file_system/quota/quota_backend_impl.h
@@ -8,6 +8,7 @@
#include <stdint.h>
#include "base/component_export.h"
+#include "base/files/file_error_or.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
@@ -79,9 +80,8 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaBackendImpl
int64_t quota);
void ReserveQuotaInternal(const QuotaReservationInfo& info);
- base::File::Error GetUsageCachePath(const url::Origin& origin,
- FileSystemType type,
- base::FilePath* usage_file_path);
+ base::FileErrorOr<base::FilePath> GetUsageCachePath(const url::Origin& origin,
+ FileSystemType type);
const scoped_refptr<base::SequencedTaskRunner> file_task_runner_;
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 abc4b126e1f..6d40b5d2394 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
@@ -12,6 +12,7 @@
#include "base/bind.h"
#include "base/check.h"
+#include "base/files/file_error_or.h"
#include "base/files/scoped_temp_dir.h"
#include "base/memory/scoped_refptr.h"
#include "base/run_loop.h"
@@ -137,12 +138,10 @@ class QuotaBackendImplTest : public testing::Test,
ASSERT_TRUE(file_util_->InitOriginDatabase(origin, true /* create */));
ASSERT_TRUE(file_util_->origin_database_ != nullptr);
- std::string type_string =
- SandboxFileSystemBackendDelegate::GetTypeString(type);
- base::File::Error error = base::File::FILE_ERROR_FAILED;
- base::FilePath path = file_util_->GetDirectoryForStorageKeyAndType(
- blink::StorageKey(origin), type_string, true /* create */, &error);
- ASSERT_EQ(base::File::FILE_OK, error);
+ base::FileErrorOr<base::FilePath> path =
+ file_util_->GetDirectoryForStorageKeyAndType(blink::StorageKey(origin),
+ type, true /* create */);
+ ASSERT_FALSE(path.is_error());
ASSERT_TRUE(file_system_usage_cache_.UpdateUsage(
GetUsageCachePath(origin, type), 0));
@@ -154,11 +153,11 @@ class QuotaBackendImplTest : public testing::Test,
base::FilePath GetUsageCachePath(const url::Origin& origin,
FileSystemType type) {
- base::FilePath path;
- base::File::Error error = backend_->GetUsageCachePath(origin, type, &path);
- EXPECT_EQ(base::File::FILE_OK, error);
- EXPECT_FALSE(path.empty());
- return path;
+ base::FileErrorOr<base::FilePath> path =
+ backend_->GetUsageCachePath(origin, type);
+ EXPECT_FALSE(path.is_error());
+ EXPECT_FALSE(path->empty());
+ return path.value();
}
base::test::SingleThreadTaskEnvironment task_environment_;
diff --git a/chromium/storage/browser/file_system/recursive_operation_delegate.cc b/chromium/storage/browser/file_system/recursive_operation_delegate.cc
index 925cd2ac08b..079908861e1 100644
--- a/chromium/storage/browser/file_system/recursive_operation_delegate.cc
+++ b/chromium/storage/browser/file_system/recursive_operation_delegate.cc
@@ -121,6 +121,8 @@ void RecursiveOperationDelegate::DidReadDirectory(const FileSystemURL& parent,
FileSystemURL url = file_system_context_->CreateCrackedFileSystemURL(
parent.storage_key(), parent.mount_type(),
parent.virtual_path().Append(entries[i].name));
+ if (parent.bucket().has_value())
+ url.SetBucket(parent.bucket().value());
if (entries[i].type == filesystem::mojom::FsFileType::DIRECTORY)
pending_directory_stack_.top().push(url);
else
diff --git a/chromium/storage/browser/file_system/recursive_operation_delegate.h b/chromium/storage/browser/file_system/recursive_operation_delegate.h
index 72b28fa2708..9b99b0dd4c6 100644
--- a/chromium/storage/browser/file_system/recursive_operation_delegate.h
+++ b/chromium/storage/browser/file_system/recursive_operation_delegate.h
@@ -150,7 +150,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) RecursiveOperationDelegate
// Called when all recursive operation is done (or an error occurs).
void Done(base::File::Error error);
- raw_ptr<FileSystemContext> file_system_context_;
+ raw_ptr<FileSystemContext, DanglingUntriaged> file_system_context_;
StatusCallback callback_;
base::stack<FileSystemURL> pending_directories_;
base::stack<base::queue<FileSystemURL>> pending_directory_stack_;
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 5a9827959e8..82eb5ed1ac3 100644
--- a/chromium/storage/browser/file_system/recursive_operation_delegate_unittest.cc
+++ b/chromium/storage/browser/file_system/recursive_operation_delegate_unittest.cc
@@ -21,6 +21,9 @@
#include "storage/browser/file_system/file_system_file_util.h"
#include "storage/browser/file_system/file_system_operation.h"
#include "storage/browser/file_system/file_system_operation_runner.h"
+#include "storage/browser/test/mock_quota_manager.h"
+#include "storage/browser/test/mock_quota_manager_proxy.h"
+#include "storage/browser/test/mock_special_storage_policy.h"
#include "storage/browser/test/sandbox_file_system_test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -145,7 +148,13 @@ class RecursiveOperationDelegateTest : public testing::Test {
protected:
void SetUp() override {
EXPECT_TRUE(base_.CreateUniqueTempDir());
- sandbox_file_system_.SetUp(base_.GetPath().AppendASCII("filesystem"));
+ base::FilePath base_dir = base_.GetPath().AppendASCII("filesystem");
+ quota_manager_ = base::MakeRefCounted<storage::MockQuotaManager>(
+ /*is_incognito=*/false, base_dir, base::ThreadTaskRunnerHandle::Get(),
+ base::MakeRefCounted<storage::MockSpecialStoragePolicy>());
+ quota_manager_proxy_ = base::MakeRefCounted<storage::MockQuotaManagerProxy>(
+ quota_manager_.get(), base::ThreadTaskRunnerHandle::Get());
+ sandbox_file_system_.SetUp(base_dir, quota_manager_proxy_);
}
void TearDown() override { sandbox_file_system_.TearDown(); }
@@ -186,6 +195,8 @@ class RecursiveOperationDelegateTest : public testing::Test {
// Common temp base for nondestructive uses.
base::ScopedTempDir base_;
SandboxFileSystemTestHelper sandbox_file_system_;
+ scoped_refptr<storage::MockQuotaManager> quota_manager_;
+ scoped_refptr<storage::MockQuotaManagerProxy> quota_manager_proxy_;
};
TEST_F(RecursiveOperationDelegateTest, RootIsFile) {
diff --git a/chromium/storage/browser/file_system/sandbox_file_stream_reader.cc b/chromium/storage/browser/file_system/sandbox_file_stream_reader.cc
index cf8b331be8d..41cf7f07604 100644
--- a/chromium/storage/browser/file_system/sandbox_file_stream_reader.cc
+++ b/chromium/storage/browser/file_system/sandbox_file_stream_reader.cc
@@ -18,7 +18,6 @@
#include "storage/browser/file_system/file_system_operation_runner.h"
#include "storage/browser/file_system/memory_file_stream_reader.h"
#include "storage/browser/file_system/obfuscated_file_util_memory_delegate.h"
-#include "storage/browser/file_system/plugin_private_file_system_backend.h"
// TODO(kinuko): Remove this temporary namespace hack after we move both
// blob and fileapi into content namespace.
@@ -92,17 +91,8 @@ void SandboxFileStreamReader::DidCreateSnapshot(
snapshot_ref_ = std::move(file_ref);
if (file_system_context_->is_incognito()) {
- base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util_delegate;
- if (url_.type() == kFileSystemTypePluginPrivate) {
- auto* backend = static_cast<PluginPrivateFileSystemBackend*>(
- file_system_context_->GetFileSystemBackend(
- kFileSystemTypePluginPrivate));
- memory_file_util_delegate =
- backend->obfuscated_file_util_memory_delegate()->GetWeakPtr();
- } else {
- memory_file_util_delegate =
- file_system_context_->sandbox_delegate()->memory_file_util_delegate();
- }
+ base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util_delegate =
+ file_system_context_->sandbox_delegate()->memory_file_util_delegate();
file_reader_ = std::make_unique<MemoryFileStreamReader>(
file_system_context_->default_file_task_runner(),
memory_file_util_delegate, platform_path, initial_offset_,
diff --git a/chromium/storage/browser/file_system/sandbox_file_stream_reader.h b/chromium/storage/browser/file_system/sandbox_file_stream_reader.h
index 5e815b1050f..fa5efcfd37c 100644
--- a/chromium/storage/browser/file_system/sandbox_file_stream_reader.h
+++ b/chromium/storage/browser/file_system/sandbox_file_stream_reader.h
@@ -66,7 +66,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SandboxFileStreamReader
void OnRead(int rv);
void OnGetLength(int64_t rv);
- raw_ptr<net::IOBuffer> read_buf_;
+ raw_ptr<net::IOBuffer, DanglingUntriaged> read_buf_;
int read_buf_len_;
net::CompletionOnceCallback read_callback_;
net::Int64CompletionOnceCallback get_length_callback_;
diff --git a/chromium/storage/browser/file_system/sandbox_file_stream_writer.cc b/chromium/storage/browser/file_system/sandbox_file_stream_writer.cc
index f82f43bb54a..27f568fc748 100644
--- a/chromium/storage/browser/file_system/sandbox_file_stream_writer.cc
+++ b/chromium/storage/browser/file_system/sandbox_file_stream_writer.cc
@@ -22,7 +22,6 @@
#include "storage/browser/file_system/file_system_util.h"
#include "storage/browser/file_system/memory_file_stream_writer.h"
#include "storage/browser/file_system/obfuscated_file_util_memory_delegate.h"
-#include "storage/browser/file_system/plugin_private_file_system_backend.h"
#include "storage/browser/quota/quota_manager_proxy.h"
#include "storage/common/file_system/file_system_util.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
@@ -147,17 +146,8 @@ void SandboxFileStreamWriter::DidCreateSnapshotFile(
DCHECK(!file_writer_.get());
if (file_system_context_->is_incognito()) {
- base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util_delegate;
- if (url_.type() == kFileSystemTypePluginPrivate) {
- auto* backend = static_cast<PluginPrivateFileSystemBackend*>(
- file_system_context_->GetFileSystemBackend(
- kFileSystemTypePluginPrivate));
- memory_file_util_delegate =
- backend->obfuscated_file_util_memory_delegate()->GetWeakPtr();
- } else {
- memory_file_util_delegate =
- file_system_context_->sandbox_delegate()->memory_file_util_delegate();
- }
+ base::WeakPtr<ObfuscatedFileUtilMemoryDelegate> memory_file_util_delegate =
+ file_system_context_->sandbox_delegate()->memory_file_util_delegate();
file_writer_ = std::make_unique<MemoryFileStreamWriter>(
file_system_context_->default_file_task_runner(),
memory_file_util_delegate, platform_path, initial_offset_);
diff --git a/chromium/storage/browser/file_system/sandbox_file_stream_writer_unittest.cc b/chromium/storage/browser/file_system/sandbox_file_stream_writer_unittest.cc
index 756a1260636..d854c07364f 100644
--- a/chromium/storage/browser/file_system/sandbox_file_stream_writer_unittest.cc
+++ b/chromium/storage/browser/file_system/sandbox_file_stream_writer_unittest.cc
@@ -3,7 +3,7 @@
// found in the LICENSE file.
#include "storage/browser/file_system/sandbox_file_stream_writer.h"
-#include "base/test/bind.h"
+#include "base/test/test_future.h"
#include "storage/browser/file_system/file_stream_writer_test.h"
#include <stdint.h>
@@ -157,16 +157,16 @@ class SandboxFileStreamWriterTest : public FileStreamWriterTest {
}
quota_usage_and_info GetUsageAndQuotaSync() {
- quota_usage_and_info info;
+ base::test::TestFuture<blink::mojom::QuotaStatusCode, int64_t, int64_t>
+ future;
quota_manager_->GetUsageAndQuota(
blink::StorageKey::CreateFromStringForTesting(kURLOrigin),
- blink::mojom::StorageType::kTemporary,
- base::BindLambdaForTesting([&](blink::mojom::QuotaStatusCode status,
- int64_t usage, int64_t quota) {
- info.status = status;
- info.usage = usage;
- info.quota = quota;
- }));
+ blink::mojom::StorageType::kTemporary, future.GetCallback());
+
+ quota_usage_and_info info;
+ info.status = future.Get<0>();
+ info.usage = future.Get<1>();
+ info.quota = future.Get<2>();
return info;
}
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 1717a4e12d3..b16792cfcef 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.storage_key(), url.type(), mode, std::move(callback),
+ url.storage_key(), url.bucket(), url.type(), mode, std::move(callback),
GetFileSystemRootURI(url.origin().GetURL(), url.type()));
}
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 e3a11138341..eaccad9a816 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
@@ -14,6 +14,7 @@
#include "base/callback_helpers.h"
#include "base/command_line.h"
#include "base/containers/contains.h"
+#include "base/files/file_error_or.h"
#include "base/files/file_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/task/task_runner_util.h"
@@ -81,10 +82,6 @@ const base::FilePath::CharType kRestrictedChars[] = {
FILE_PATH_LITERAL('\\'),
};
-std::string GetTypeStringForURL(const FileSystemURL& url) {
- return SandboxFileSystemBackendDelegate::GetTypeString(url.type());
-}
-
std::set<std::string> GetKnownTypeStrings() {
std::set<std::string> known_type_strings;
known_type_strings.insert(kTemporaryDirectoryName);
@@ -116,13 +113,22 @@ class SandboxObfuscatedStorageKeyEnumerator
base::File::Error OpenSandboxFileSystemOnFileTaskRunner(
ObfuscatedFileUtil* file_util,
const GURL& origin_url,
+ const absl::optional<BucketLocator>& bucket_locator,
FileSystemType type,
OpenFileSystemMode mode) {
const bool create = (mode == OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT);
base::File::Error error;
- file_util->GetDirectoryForStorageKeyAndType(
- blink::StorageKey(url::Origin::Create(origin_url)),
- SandboxFileSystemBackendDelegate::GetTypeString(type), create, &error);
+ if (bucket_locator.has_value()) {
+ base::FileErrorOr<base::FilePath> path =
+ file_util->GetDirectoryForBucketAndType(bucket_locator.value(), type,
+ create);
+ error = (path.is_error()) ? path.error() : base::File::FILE_OK;
+ } else {
+ base::FileErrorOr<base::FilePath> path =
+ file_util->GetDirectoryForStorageKeyAndType(
+ blink::StorageKey(url::Origin::Create(origin_url)), type, create);
+ error = (path.is_error()) ? path.error() : base::File::FILE_OK;
+ }
if (error != base::File::FILE_OK) {
UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemLabel, kCreateDirectoryError,
kFileSystemErrorMax);
@@ -156,10 +162,6 @@ void DeleteSoon(base::SequencedTaskRunner* runner, T* ptr) {
} // namespace
-const base::FilePath::CharType
- SandboxFileSystemBackendDelegate::kFileSystemDirectory[] =
- FILE_PATH_LITERAL("File System");
-
// static
std::string SandboxFileSystemBackendDelegate::GetTypeString(
FileSystemType type) {
@@ -190,9 +192,8 @@ SandboxFileSystemBackendDelegate::SandboxFileSystemBackendDelegate(
sandbox_file_util_(std::make_unique<AsyncFileUtilAdapter>(
std::make_unique<ObfuscatedFileUtil>(
special_storage_policy,
- profile_path.Append(kFileSystemDirectory),
+ profile_path,
env_override,
- base::BindRepeating(&GetTypeStringForURL),
GetKnownTypeStrings(),
this,
file_system_options.is_incognito()))),
@@ -217,8 +218,12 @@ SandboxFileSystemBackendDelegate::~SandboxFileSystemBackendDelegate() {
if (!file_task_runner_->RunsTasksInCurrentSequence()) {
DeleteSoon(file_task_runner_.get(), quota_reservation_manager_.release());
- DeleteSoon(file_task_runner_.get(), sandbox_file_util_.release());
+ // `quota_observer_` depends on `sandbox_file_util_` and
+ // `file_system_usage_cache_` so it must be released first.
DeleteSoon(file_task_runner_.get(), quota_observer_.release());
+ // Clear pointer to |this| to avoid holding a dangling ptr.
+ obfuscated_file_util()->sandbox_delegate_ = nullptr;
+ DeleteSoon(file_task_runner_.get(), sandbox_file_util_.release());
DeleteSoon(file_task_runner_.get(), file_system_usage_cache_.release());
}
}
@@ -233,13 +238,12 @@ 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()->GetDirectoryForStorageKeyAndType(
- storage_key, GetTypeString(type), create, &error);
- if (error != base::File::FILE_OK)
+ base::FileErrorOr<base::FilePath> path =
+ obfuscated_file_util()->GetDirectoryForStorageKeyAndType(storage_key,
+ type, create);
+ if (path.is_error())
return base::FilePath();
- return path;
+ return path.value();
}
base::FilePath
@@ -248,8 +252,8 @@ SandboxFileSystemBackendDelegate::GetBaseDirectoryForBucketAndType(
FileSystemType type,
bool create) {
base::FileErrorOr<base::FilePath> path =
- obfuscated_file_util()->GetDirectoryForBucketAndType(
- bucket_locator, GetTypeString(type), create);
+ obfuscated_file_util()->GetDirectoryForBucketAndType(bucket_locator, type,
+ create);
if (path.is_error())
return base::FilePath();
return path.value();
@@ -257,6 +261,7 @@ SandboxFileSystemBackendDelegate::GetBaseDirectoryForBucketAndType(
void SandboxFileSystemBackendDelegate::OpenFileSystem(
const blink::StorageKey& storage_key,
+ const absl::optional<BucketLocator>& bucket_locator,
FileSystemType type,
OpenFileSystemMode mode,
ResolveURLCallback callback,
@@ -270,19 +275,25 @@ void SandboxFileSystemBackendDelegate::OpenFileSystem(
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_, storage_key,
- FileSystemTypeToQuotaStorageType(type),
- base::Time::Now())
- : base::DoNothing();
+ base::OnceClosure quota_callback;
+ if (quota_manager_proxy_.get()) {
+ quota_callback =
+ (bucket_locator.has_value())
+ ? base::BindOnce(&QuotaManagerProxy::NotifyBucketAccessed,
+ quota_manager_proxy_, bucket_locator->id,
+ base::Time::Now())
+ : base::BindOnce(&QuotaManagerProxy::NotifyStorageAccessed,
+ quota_manager_proxy_, storage_key,
+ FileSystemTypeToQuotaStorageType(type),
+ base::Time::Now());
+ } else
+ quota_callback = base::DoNothing();
file_task_runner_->PostTaskAndReplyWithResult(
FROM_HERE,
base::BindOnce(&OpenSandboxFileSystemOnFileTaskRunner,
obfuscated_file_util(), storage_key.origin().GetURL(),
- type, mode),
+ bucket_locator, type, mode),
base::BindOnce(&DidOpenFileSystem, weak_factory_.GetWeakPtr(),
std::move(quota_callback),
base::BindOnce(std::move(callback), root_url, name)));
@@ -351,7 +362,7 @@ SandboxFileSystemBackendDelegate::DeleteStorageKeyDataOnFileTaskRunner(
storage_key, type);
usage_cache()->CloseCacheFiles();
bool result = obfuscated_file_util()->DeleteDirectoryForStorageKeyAndType(
- storage_key, GetTypeString(type));
+ storage_key, type);
if (result && proxy && usage) {
proxy->NotifyStorageModified(
QuotaClientType::kFileSystem, storage_key,
@@ -359,6 +370,51 @@ SandboxFileSystemBackendDelegate::DeleteStorageKeyDataOnFileTaskRunner(
base::SequencedTaskRunnerHandle::Get(), base::DoNothing());
}
+ // If obfuscated_file_util() was caching the default bucket for this
+ // StorageKey, it should be deleted as well. If it was not cached, result is a
+ // no-op. NOTE: one StorageKey may map to many BucketLocators depending on the
+ // type. We only want to cache and delete kFileSystemTypeTemporary buckets.
+ // Otherwise, we may accidentally delete the wrong databases.
+ if (FileSystemTypeToQuotaStorageType(type) ==
+ blink::mojom::StorageType::kTemporary) {
+ obfuscated_file_util()->DeleteDefaultBucketForStorageKey(storage_key);
+ }
+
+ if (result)
+ return base::File::FILE_OK;
+ return base::File::FILE_ERROR_FAILED;
+}
+
+base::File::Error
+SandboxFileSystemBackendDelegate::DeleteBucketDataOnFileTaskRunner(
+ FileSystemContext* file_system_context,
+ QuotaManagerProxy* proxy,
+ const BucketLocator& bucket_locator,
+ FileSystemType type) {
+ DCHECK(file_task_runner_->RunsTasksInCurrentSequence());
+ int64_t usage = (proxy) ? GetBucketUsageOnFileTaskRunner(file_system_context,
+ bucket_locator, type)
+ : 0;
+ usage_cache()->CloseCacheFiles();
+ bool result = obfuscated_file_util()->DeleteDirectoryForBucketAndType(
+ bucket_locator, type);
+ if (result && proxy && usage) {
+ proxy->NotifyBucketModified(QuotaClientType::kFileSystem, bucket_locator.id,
+ -usage, base::Time::Now(),
+ base::SequencedTaskRunnerHandle::Get(),
+ base::DoNothing());
+ }
+
+ // If obfuscated_file_util() was caching this default bucket, it should be
+ // deleted as well. If it was not cached, result is a no-op. NOTE: We only
+ // want to cache and delete kTemporary buckets. Otherwise, we may accidentally
+ // delete the wrong databases.
+ if (FileSystemTypeToQuotaStorageType(type) ==
+ blink::mojom::StorageType::kTemporary &&
+ bucket_locator.is_default) {
+ obfuscated_file_util()->DeleteDefaultBucket(bucket_locator);
+ }
+
if (result)
return base::File::FILE_OK;
return base::File::FILE_ERROR_FAILED;
@@ -547,12 +603,12 @@ void SandboxFileSystemBackendDelegate::RegisterQuotaUpdateObserver(
void SandboxFileSystemBackendDelegate::InvalidateUsageCache(
const blink::StorageKey& storage_key,
FileSystemType type) {
- base::File::Error error = base::File::FILE_OK;
- base::FilePath usage_file_path = GetUsageCachePathForStorageKeyAndType(
- obfuscated_file_util(), storage_key, type, &error);
- if (error != base::File::FILE_OK)
+ base::FileErrorOr<base::FilePath> usage_file_path =
+ GetUsageCachePathForStorageKeyAndType(obfuscated_file_util(), storage_key,
+ type);
+ if (usage_file_path.is_error())
return;
- usage_cache()->IncrementDirty(usage_file_path);
+ usage_cache()->IncrementDirty(usage_file_path.value());
}
void SandboxFileSystemBackendDelegate::StickyInvalidateUsageCache(
@@ -616,62 +672,48 @@ bool SandboxFileSystemBackendDelegate::IsAllowedScheme(const GURL& url) const {
return false;
}
-base::FilePath
+base::FileErrorOr<base::FilePath>
SandboxFileSystemBackendDelegate::GetUsageCachePathForStorageKeyAndType(
const blink::StorageKey& storage_key,
FileSystemType type) {
- base::File::Error error;
- base::FilePath path = GetUsageCachePathForStorageKeyAndType(
- obfuscated_file_util(), storage_key, type, &error);
- if (error != base::File::FILE_OK)
- return base::FilePath();
- return path;
+ return GetUsageCachePathForStorageKeyAndType(obfuscated_file_util(),
+ storage_key, type);
}
// static
-base::FilePath
+base::FileErrorOr<base::FilePath>
SandboxFileSystemBackendDelegate::GetUsageCachePathForStorageKeyAndType(
ObfuscatedFileUtil* sandbox_file_util,
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->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);
+ FileSystemType type) {
+ base::FileErrorOr<base::FilePath> base_path =
+ sandbox_file_util->GetDirectoryForStorageKeyAndType(storage_key, type,
+ false /* create */);
+ if (base_path.is_error()) {
+ return base_path;
+ }
+ return base_path->Append(FileSystemUsageCache::kUsageFileName);
}
-base::FilePath
+base::FileErrorOr<base::FilePath>
SandboxFileSystemBackendDelegate::GetUsageCachePathForBucketAndType(
const BucketLocator& bucket_locator,
FileSystemType type) {
- base::File::Error error;
- base::FilePath path = GetUsageCachePathForBucketAndType(
- obfuscated_file_util(), bucket_locator, type, &error);
- if (error != base::File::FILE_OK)
- return base::FilePath();
- return path;
+ return GetUsageCachePathForBucketAndType(obfuscated_file_util(),
+ bucket_locator, type);
}
// static
-base::FilePath
+base::FileErrorOr<base::FilePath>
SandboxFileSystemBackendDelegate::GetUsageCachePathForBucketAndType(
ObfuscatedFileUtil* sandbox_file_util,
const BucketLocator& bucket_locator,
- FileSystemType type,
- base::File::Error* error_out) {
- DCHECK(error_out);
- *error_out = base::File::FILE_OK;
+ FileSystemType type) {
base::FileErrorOr<base::FilePath> base_path =
- sandbox_file_util->GetDirectoryForBucketAndType(
- bucket_locator, GetTypeString(type), /*create=*/false);
+ sandbox_file_util->GetDirectoryForBucketAndType(bucket_locator, type,
+ /*create=*/false);
if (base_path.is_error()) {
- *error_out = base_path.error();
- return base::FilePath();
+ return base_path;
}
return base_path->Append(FileSystemUsageCache::kUsageFileName);
}
@@ -752,13 +794,12 @@ SandboxFileSystemBackendDelegate::memory_file_util_delegate() {
// static
std::unique_ptr<ObfuscatedFileUtil> ObfuscatedFileUtil::CreateForTesting(
scoped_refptr<SpecialStoragePolicy> special_storage_policy,
- const base::FilePath& file_system_directory,
+ const base::FilePath& profile_path,
leveldb::Env* env_override,
bool is_incognito) {
return std::make_unique<ObfuscatedFileUtil>(
- std::move(special_storage_policy), file_system_directory, env_override,
- base::BindRepeating(&GetTypeStringForURL), GetKnownTypeStrings(),
- /*sandbox_delegate=*/nullptr, is_incognito);
+ std::move(special_storage_policy), profile_path, env_override,
+ GetKnownTypeStrings(), /*sandbox_delegate=*/nullptr, is_incognito);
}
} // namespace storage
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 4bff8911206..30fef5ca0a1 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
@@ -15,6 +15,7 @@
#include <vector>
#include "base/component_export.h"
+#include "base/files/file_error_or.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
@@ -72,9 +73,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SandboxFileSystemBackendDelegate
using OpenFileSystemCallback = FileSystemBackend::OpenFileSystemCallback;
using ResolveURLCallback = FileSystemBackend::ResolveURLCallback;
- // The FileSystem directory name.
- static const base::FilePath::CharType kFileSystemDirectory[];
-
// StorageKey enumerator interface.
// An instance of this interface is assumed to be called on the file thread.
class StorageKeyEnumerator {
@@ -136,6 +134,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SandboxFileSystemBackendDelegate
// FileSystemBackend helpers.
void OpenFileSystem(const blink::StorageKey& storage_key,
+ const absl::optional<BucketLocator>& bucket_locator,
FileSystemType type,
OpenFileSystemMode mode,
ResolveURLCallback callback,
@@ -161,6 +160,11 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SandboxFileSystemBackendDelegate
QuotaManagerProxy* proxy,
const blink::StorageKey& storage_key,
FileSystemType type) override;
+ base::File::Error DeleteBucketDataOnFileTaskRunner(
+ FileSystemContext* context,
+ QuotaManagerProxy* proxy,
+ const BucketLocator& bucket_locator,
+ FileSystemType type) override;
void PerformStorageCleanupOnFileTaskRunner(FileSystemContext* context,
QuotaManagerProxy* proxy,
FileSystemType type) override;
@@ -172,7 +176,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SandboxFileSystemBackendDelegate
FileSystemType type) override;
int64_t GetBucketUsageOnFileTaskRunner(FileSystemContext* context,
const BucketLocator& bucket_locator,
- FileSystemType type);
+ FileSystemType type) override;
scoped_refptr<QuotaReservation> CreateQuotaReservationOnFileTaskRunner(
const blink::StorageKey& storage_key,
FileSystemType type) override;
@@ -246,29 +250,27 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SandboxFileSystemBackendDelegate
bool IsAllowedScheme(const GURL& url) const;
// Returns a path to the usage cache file.
- base::FilePath GetUsageCachePathForStorageKeyAndType(
+ base::FileErrorOr<base::FilePath> GetUsageCachePathForStorageKeyAndType(
const blink::StorageKey& storage_key,
FileSystemType type);
// Returns a path to the usage cache file (static version).
- static base::FilePath GetUsageCachePathForStorageKeyAndType(
- ObfuscatedFileUtil* sandbox_file_util,
- const blink::StorageKey& storage_key,
- FileSystemType type,
- base::File::Error* error_out);
+ static base::FileErrorOr<base::FilePath>
+ GetUsageCachePathForStorageKeyAndType(ObfuscatedFileUtil* sandbox_file_util,
+ const blink::StorageKey& storage_key,
+ FileSystemType type);
// Returns a path to the usage cache file for a given bucket and type.
- base::FilePath GetUsageCachePathForBucketAndType(
+ base::FileErrorOr<base::FilePath> GetUsageCachePathForBucketAndType(
const BucketLocator& bucket_locator,
FileSystemType type);
// Returns a path to the usage cache file for a given bucket and type(static
// version).
- static base::FilePath GetUsageCachePathForBucketAndType(
+ static base::FileErrorOr<base::FilePath> GetUsageCachePathForBucketAndType(
ObfuscatedFileUtil* sandbox_file_util,
const BucketLocator& bucket_locator,
- FileSystemType type,
- base::File::Error* error_out);
+ FileSystemType type);
// Helper function to obtain usage for a StorageKey value and optionally a
// BucketLocator value. `storage_key` and `bucket_locator->storage_key` should
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 c6fb104ae60..19a4a5e5b5d 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
@@ -49,10 +49,11 @@ class SandboxFileSystemBackendDelegateTest : public testing::Test {
}
void OpenFileSystem(const blink::StorageKey& storage_key,
+ const absl::optional<BucketLocator>& bucket_locator,
FileSystemType type,
OpenFileSystemMode mode) {
delegate_->OpenFileSystem(
- storage_key, type, mode,
+ storage_key, bucket_locator, type, mode,
base::BindOnce(
&SandboxFileSystemBackendDelegateTest::OpenFileSystemCallback,
base::Unretained(this)),
@@ -126,7 +127,10 @@ TEST_F(SandboxFileSystemBackendDelegateTest, OpenFileSystemAccessesStorage) {
const blink::StorageKey& storage_key =
blink::StorageKey::CreateFromStringForTesting("http://example.com");
- OpenFileSystem(storage_key, kFileSystemTypeTemporary,
+ // TODO(https://crbug.com/1330608): ensure that this test suite properly
+ // integrates non-default BucketLocators into OpenFileSystem.
+ OpenFileSystem(storage_key, /*bucket_locator=*/absl::nullopt,
+ kFileSystemTypeTemporary,
OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT);
EXPECT_EQ(callback_count(), 1);
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 2290b355129..fd43d573af4 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
@@ -23,6 +23,7 @@
#include "storage/browser/file_system/file_system_backend.h"
#include "storage/browser/file_system/file_system_features.h"
#include "storage/browser/file_system/file_system_url.h"
+#include "storage/browser/file_system/obfuscated_file_util.h"
#include "storage/browser/file_system/sandbox_file_system_backend_delegate.h"
#include "storage/browser/quota/quota_manager.h"
#include "storage/browser/quota/quota_manager_proxy.h"
@@ -203,8 +204,7 @@ class SandboxFileSystemBackendTest
}
base::FilePath file_system_path() const {
- return data_dir_.GetPath().Append(
- SandboxFileSystemBackendDelegate::kFileSystemDirectory);
+ return data_dir_.GetPath().Append(ObfuscatedFileUtil::kFileSystemDirectory);
}
base::FilePath file_system_path_for_buckets() const {
diff --git a/chromium/storage/browser/file_system/sandbox_quota_observer.cc b/chromium/storage/browser/file_system/sandbox_quota_observer.cc
index 706c47fc6ad..3b98154e5ec 100644
--- a/chromium/storage/browser/file_system/sandbox_quota_observer.cc
+++ b/chromium/storage/browser/file_system/sandbox_quota_observer.cc
@@ -7,6 +7,7 @@
#include <stdint.h>
#include "base/bind.h"
+#include "base/files/file_error_or.h"
#include "base/memory/scoped_refptr.h"
#include "base/task/sequenced_task_runner.h"
#include "storage/browser/file_system/file_system_usage_cache.h"
@@ -33,10 +34,10 @@ SandboxQuotaObserver::~SandboxQuotaObserver() = default;
void SandboxQuotaObserver::OnStartUpdate(const FileSystemURL& url) {
DCHECK(update_notify_runner_->RunsTasksInCurrentSequence());
- base::FilePath usage_file_path = GetUsageCachePath(url);
- if (usage_file_path.empty())
+ base::FileErrorOr<base::FilePath> usage_file_path = GetUsageCachePath(url);
+ if (usage_file_path.is_error() || usage_file_path->empty())
return;
- file_system_usage_cache_->IncrementDirty(usage_file_path);
+ file_system_usage_cache_->IncrementDirty(usage_file_path.value());
}
void SandboxQuotaObserver::OnUpdate(const FileSystemURL& url, int64_t delta) {
@@ -49,11 +50,11 @@ void SandboxQuotaObserver::OnUpdate(const FileSystemURL& url, int64_t delta) {
base::SequencedTaskRunnerHandle::Get(), base::DoNothing());
}
- base::FilePath usage_file_path = GetUsageCachePath(url);
- if (usage_file_path.empty())
+ base::FileErrorOr<base::FilePath> usage_file_path = GetUsageCachePath(url);
+ if (usage_file_path.is_error() || usage_file_path->empty())
return;
- pending_update_notification_[usage_file_path] += delta;
+ pending_update_notification_[usage_file_path.value()] += delta;
if (!delayed_cache_update_helper_.IsRunning()) {
delayed_cache_update_helper_.Start(
FROM_HERE,
@@ -66,17 +67,17 @@ void SandboxQuotaObserver::OnUpdate(const FileSystemURL& url, int64_t delta) {
void SandboxQuotaObserver::OnEndUpdate(const FileSystemURL& url) {
DCHECK(update_notify_runner_->RunsTasksInCurrentSequence());
- base::FilePath usage_file_path = GetUsageCachePath(url);
- if (usage_file_path.empty())
+ base::FileErrorOr<base::FilePath> usage_file_path = GetUsageCachePath(url);
+ if (usage_file_path.is_error() || usage_file_path->empty())
return;
- auto found = pending_update_notification_.find(usage_file_path);
+ auto found = pending_update_notification_.find(usage_file_path.value());
if (found != pending_update_notification_.end()) {
UpdateUsageCacheFile(found->first, found->second);
pending_update_notification_.erase(found);
}
- file_system_usage_cache_->DecrementDirty(usage_file_path);
+ file_system_usage_cache_->DecrementDirty(usage_file_path.value());
}
void SandboxQuotaObserver::OnAccess(const FileSystemURL& url) {
@@ -97,22 +98,20 @@ void SandboxQuotaObserver::SetUsageCacheEnabled(const url::Origin& origin,
}
}
-base::FilePath SandboxQuotaObserver::GetUsageCachePath(
+base::FileErrorOr<base::FilePath> SandboxQuotaObserver::GetUsageCachePath(
const FileSystemURL& url) {
DCHECK(sandbox_file_util_);
- base::File::Error error = base::File::FILE_OK;
- base::FilePath path;
+ base::FileErrorOr<base::FilePath> path = base::FilePath();
if (url.bucket().has_value()) {
path = SandboxFileSystemBackendDelegate::GetUsageCachePathForBucketAndType(
- sandbox_file_util_, url.bucket().value(), url.type(), &error);
+ sandbox_file_util_, url.bucket().value(), url.type());
} else {
path =
SandboxFileSystemBackendDelegate::GetUsageCachePathForStorageKeyAndType(
- sandbox_file_util_, url.storage_key(), url.type(), &error);
+ sandbox_file_util_, url.storage_key(), url.type());
}
- if (error != base::File::FILE_OK) {
+ if (path.is_error()) {
LOG(WARNING) << "Could not get usage cache path for: " << url.DebugString();
- return base::FilePath();
}
return path;
}
diff --git a/chromium/storage/browser/file_system/sandbox_quota_observer.h b/chromium/storage/browser/file_system/sandbox_quota_observer.h
index 59be57fbb44..3231d1a7eb3 100644
--- a/chromium/storage/browser/file_system/sandbox_quota_observer.h
+++ b/chromium/storage/browser/file_system/sandbox_quota_observer.h
@@ -10,6 +10,7 @@
#include <map>
#include "base/compiler_specific.h"
+#include "base/files/file_error_or.h"
#include "base/files/file_path.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
@@ -65,7 +66,7 @@ class SandboxQuotaObserver : public FileUpdateObserver,
void UpdateUsageCacheFile(const base::FilePath& usage_file_path,
int64_t delta);
- base::FilePath GetUsageCachePath(const FileSystemURL& url);
+ base::FileErrorOr<base::FilePath> GetUsageCachePath(const FileSystemURL& url);
const scoped_refptr<QuotaManagerProxy> quota_manager_proxy_;
const scoped_refptr<base::SequencedTaskRunner> update_notify_runner_;
diff --git a/chromium/storage/browser/quota/OWNERS b/chromium/storage/browser/quota/OWNERS
index 22981a38b9a..97011b2f221 100644
--- a/chromium/storage/browser/quota/OWNERS
+++ b/chromium/storage/browser/quota/OWNERS
@@ -4,7 +4,6 @@ ayui@chromium.org
# Secondary
asully@chromium.org
estade@chromium.org
-jarrydg@chromium.org
jsbell@chromium.org
per-file *.mojom=set noparent
diff --git a/chromium/storage/browser/quota/README.md b/chromium/storage/browser/quota/README.md
index c94d182ac3c..7997cdf5c8c 100644
--- a/chromium/storage/browser/quota/README.md
+++ b/chromium/storage/browser/quota/README.md
@@ -51,7 +51,7 @@ Storage Buckets. The currently stored information is a usage count,
last-modified-time, and last-accessed-time for each origin (used to implement
LRU eviction on storage pressure, and Clear Site Data with a time filter), and
quota granted via the deprecated API
-webkitStorageInfo.requestQuota(PERSISTENT,...).
+navigator.webkitPersistentStorage.requestQuota(1000, ...).
### QuotaTemporaryStorageEvictor
Handles eviction and records stats about eviction rounds.
diff --git a/chromium/storage/browser/quota/quota_database.cc b/chromium/storage/browser/quota/quota_database.cc
index fd8b3b8262f..792b909cc94 100644
--- a/chromium/storage/browser/quota/quota_database.cc
+++ b/chromium/storage/browser/quota/quota_database.cc
@@ -27,6 +27,7 @@
#include "sql/statement.h"
#include "sql/transaction.h"
#include "storage/browser/quota/quota_database_migrations.h"
+#include "storage/browser/quota/quota_internals.mojom.h"
#include "storage/browser/quota/special_storage_policy.h"
#include "url/gurl.h"
@@ -104,6 +105,25 @@ void BindBucketInitParamsToInsertStatement(const BucketInitParams& params,
statement.BindInt(10, durability);
}
+// Fields to be retrieved from the database and stored in a
+// `BucketTableEntryPtr`.
+#define BUCKET_TABLE_ENTRY_FIELDS_SELECTOR \
+ "id, storage_key, type, name, use_count, last_accessed, last_modified "
+
+mojom::BucketTableEntryPtr BucketTableEntryFromSqlStatement(
+ sql::Statement& statement) {
+ mojom::BucketTableEntryPtr entry = mojom::BucketTableEntry::New();
+ entry->bucket_id = statement.ColumnInt64(0);
+ entry->storage_key = statement.ColumnString(1);
+ entry->type =
+ static_cast<storage::mojom::StorageType>(statement.ColumnInt(2));
+ entry->name = statement.ColumnString(3);
+ entry->use_count = statement.ColumnInt(4);
+ entry->last_accessed = statement.ColumnTime(5);
+ entry->last_modified = statement.ColumnTime(6);
+ return entry;
+}
+
// Fields to be retrieved from the database and stored in a `BucketInfo`.
#define BUCKET_INFO_FIELDS_SELECTOR \
" id, storage_key, type, name, expiration, quota, persistent, durability "
@@ -127,6 +147,16 @@ QuotaErrorOr<BucketInfo> BucketInfoFromSqlStatement(sql::Statement& statement) {
static_cast<blink::mojom::BucketDurability>(statement.ColumnInt(7)));
}
+std::set<BucketInfo> BucketInfosFromSqlStatement(sql::Statement& statement) {
+ std::set<BucketInfo> result;
+ QuotaErrorOr<BucketInfo> bucket;
+ while ((bucket = BucketInfoFromSqlStatement(statement)).ok()) {
+ result.insert(bucket.value());
+ }
+
+ return result;
+}
+
} // anonymous namespace
const QuotaDatabase::TableSchema QuotaDatabase::kTables[] = {
@@ -162,31 +192,6 @@ const QuotaDatabase::IndexSchema QuotaDatabase::kIndexes[] = {
};
const size_t QuotaDatabase::kIndexCount = std::size(QuotaDatabase::kIndexes);
-QuotaDatabase::BucketTableEntry::BucketTableEntry() = default;
-
-QuotaDatabase::BucketTableEntry::~BucketTableEntry() = default;
-
-QuotaDatabase::BucketTableEntry::BucketTableEntry(const BucketTableEntry&) =
- default;
-QuotaDatabase::BucketTableEntry& QuotaDatabase::BucketTableEntry::operator=(
- const QuotaDatabase::BucketTableEntry&) = default;
-
-QuotaDatabase::BucketTableEntry::BucketTableEntry(
- BucketId bucket_id,
- StorageKey storage_key,
- StorageType type,
- std::string name,
- int use_count,
- const base::Time& last_accessed,
- const base::Time& last_modified)
- : bucket_id(std::move(bucket_id)),
- storage_key(std::move(storage_key)),
- type(type),
- name(std::move(name)),
- use_count(use_count),
- last_accessed(last_accessed),
- last_modified(last_modified) {}
-
// QuotaDatabase ------------------------------------------------------------
QuotaDatabase::QuotaDatabase(const base::FilePath& profile_path)
: storage_directory_(
@@ -410,7 +415,7 @@ QuotaErrorOr<BucketInfo> QuotaDatabase::GetBucketById(BucketId bucket_id) {
return BucketInfoFromSqlStatement(statement);
}
-QuotaErrorOr<std::set<BucketLocator>> QuotaDatabase::GetBucketsForType(
+QuotaErrorOr<std::set<BucketInfo>> QuotaDatabase::GetBucketsForType(
StorageType type) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
QuotaError open_error = EnsureOpened();
@@ -418,53 +423,39 @@ QuotaErrorOr<std::set<BucketLocator>> QuotaDatabase::GetBucketsForType(
return open_error;
static constexpr char kSql[] =
- "SELECT id, storage_key, name FROM buckets WHERE type = ?";
-
+ // clang-format off
+ "SELECT " BUCKET_INFO_FIELDS_SELECTOR
+ "FROM buckets "
+ "WHERE type = ?";
+ // clang-format on
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;
+ return BucketInfosFromSqlStatement(statement);
}
-QuotaErrorOr<std::set<BucketLocator>> QuotaDatabase::GetBucketsForHost(
+QuotaErrorOr<std::set<BucketInfo>> QuotaDatabase::GetBucketsForHost(
const std::string& host,
- blink::mojom::StorageType storage_type) {
+ StorageType type) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
QuotaError open_error = EnsureOpened();
if (open_error != QuotaError::kNone)
return open_error;
static constexpr char kSql[] =
- "SELECT id, storage_key, name FROM buckets WHERE host = ? AND type = ?";
-
+ // clang-format off
+ "SELECT " BUCKET_INFO_FIELDS_SELECTOR
+ "FROM buckets "
+ "WHERE host = ? AND type = ?";
+ // clang-format on
sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
statement.BindString(0, host);
- statement.BindInt(1, static_cast<int>(storage_type));
+ statement.BindInt(1, 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(), storage_type,
- statement.ColumnString(2) == kDefaultBucketName);
- }
- return buckets;
+ return BucketInfosFromSqlStatement(statement);
}
-QuotaErrorOr<std::set<BucketLocator>> QuotaDatabase::GetBucketsForStorageKey(
+QuotaErrorOr<std::set<BucketInfo>> QuotaDatabase::GetBucketsForStorageKey(
const StorageKey& storage_key,
StorageType type) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -473,18 +464,16 @@ QuotaErrorOr<std::set<BucketLocator>> QuotaDatabase::GetBucketsForStorageKey(
return open_error;
static constexpr char kSql[] =
- "SELECT id, name FROM buckets WHERE storage_key = ? AND type = ?";
-
+ // clang-format off
+ "SELECT " BUCKET_INFO_FIELDS_SELECTOR
+ "FROM buckets "
+ "WHERE storage_key = ? AND type = ?";
+ // 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));
- std::set<BucketLocator> buckets;
- while (statement.Step()) {
- buckets.emplace(BucketId(statement.ColumnInt64(0)), storage_key, type,
- statement.ColumnString(1) == kDefaultBucketName);
- }
- return buckets;
+ return BucketInfosFromSqlStatement(statement);
}
QuotaError QuotaDatabase::SetStorageKeyLastAccessTime(
@@ -589,7 +578,7 @@ QuotaError QuotaDatabase::RegisterInitialStorageKeyInfo(
return QuotaError::kNone;
}
-QuotaErrorOr<QuotaDatabase::BucketTableEntry> QuotaDatabase::GetBucketInfo(
+QuotaErrorOr<mojom::BucketTableEntryPtr> QuotaDatabase::GetBucketInfo(
BucketId bucket_id) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!bucket_id.is_null());
@@ -599,13 +588,7 @@ QuotaErrorOr<QuotaDatabase::BucketTableEntry> QuotaDatabase::GetBucketInfo(
static constexpr char kSql[] =
// clang-format off
- "SELECT "
- "storage_key,"
- "type,"
- "name,"
- "use_count,"
- "last_accessed,"
- "last_modified "
+ "SELECT " BUCKET_TABLE_ENTRY_FIELDS_SELECTOR
"FROM buckets "
"WHERE id = ?";
// clang-format on
@@ -618,14 +601,13 @@ QuotaErrorOr<QuotaDatabase::BucketTableEntry> QuotaDatabase::GetBucketInfo(
}
absl::optional<StorageKey> storage_key =
- StorageKey::Deserialize(statement.ColumnString(0));
+ StorageKey::Deserialize(statement.ColumnString(1));
if (!storage_key.has_value())
return QuotaError::kNotFound;
- return BucketTableEntry(bucket_id, std::move(storage_key).value(),
- static_cast<StorageType>(statement.ColumnInt(1)),
- statement.ColumnString(2), statement.ColumnInt(3),
- statement.ColumnTime(4), statement.ColumnTime(5));
+ mojom::BucketTableEntryPtr entry =
+ BucketTableEntryFromSqlStatement(statement);
+ return entry;
}
QuotaError QuotaDatabase::DeleteHostQuota(const std::string& host,
@@ -874,6 +856,10 @@ void QuotaDatabase::SetClockForTesting(base::Clock* clock) {
g_clock_for_testing = clock;
}
+void QuotaDatabase::CommitNow() {
+ Commit();
+}
+
void QuotaDatabase::Commit() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!db_)
@@ -1142,30 +1128,20 @@ QuotaError QuotaDatabase::DumpBucketTable(const BucketTableCallback& callback) {
static constexpr char kSql[] =
// clang-format off
- "SELECT "
- "id,"
- "storage_key,"
- "type,"
- "name,"
- "use_count,"
- "last_accessed,"
- "last_modified "
+ "SELECT " BUCKET_TABLE_ENTRY_FIELDS_SELECTOR
"FROM buckets";
// clang-format on
sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
while (statement.Step()) {
- BucketId bucket_id = BucketId(statement.ColumnInt64(0));
absl::optional<StorageKey> storage_key =
StorageKey::Deserialize(statement.ColumnString(1));
if (!storage_key.has_value())
continue;
- BucketTableEntry entry(std::move(bucket_id), std::move(storage_key).value(),
- static_cast<StorageType>(statement.ColumnInt(2)),
- statement.ColumnString(3), statement.ColumnInt(4),
- statement.ColumnTime(5), statement.ColumnTime(6));
- if (!callback.Run(entry))
+ auto entry = BucketTableEntryFromSqlStatement(statement);
+
+ if (!callback.Run(std::move(entry)))
return QuotaError::kNone;
}
return statement.Succeeded() ? QuotaError::kNone : QuotaError::kDatabaseError;
@@ -1204,10 +1180,4 @@ QuotaErrorOr<BucketInfo> QuotaDatabase::CreateBucketInternal(
return result;
}
-bool operator<(const QuotaDatabase::BucketTableEntry& lhs,
- const QuotaDatabase::BucketTableEntry& rhs) {
- return std::tie(lhs.storage_key, lhs.type, lhs.use_count, lhs.last_accessed) <
- std::tie(rhs.storage_key, rhs.type, rhs.use_count, rhs.last_accessed);
-}
-
} // namespace storage
diff --git a/chromium/storage/browser/quota/quota_database.h b/chromium/storage/browser/quota/quota_database.h
index 9f5f365c7fa..0bdbe80735d 100644
--- a/chromium/storage/browser/quota/quota_database.h
+++ b/chromium/storage/browser/quota/quota_database.h
@@ -26,6 +26,7 @@
#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 "storage/browser/quota/quota_internals.mojom-forward.h"
#include "storage/browser/quota/storage_directory.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
@@ -38,7 +39,7 @@ class Clock;
namespace sql {
class Database;
class MetaTable;
-}
+} // namespace sql
namespace storage {
@@ -65,34 +66,6 @@ enum class DatabaseResetReason {
// constructor, must called on the DB thread.
class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaDatabase {
public:
- struct COMPONENT_EXPORT(STORAGE_BROWSER) BucketTableEntry {
- BucketTableEntry();
- BucketTableEntry(BucketId bucket_id,
- blink::StorageKey storage_key,
- blink::mojom::StorageType type,
- std::string name,
- int use_count,
- const base::Time& last_accessed,
- const base::Time& last_modified);
- ~BucketTableEntry();
-
- BucketTableEntry(const BucketTableEntry&);
- BucketTableEntry& operator=(const BucketTableEntry&);
-
- BucketLocator ToBucketLocator() const {
- return BucketLocator(bucket_id, storage_key, type,
- name == kDefaultBucketName);
- }
-
- BucketId bucket_id;
- blink::StorageKey storage_key;
- blink::mojom::StorageType type = blink::mojom::StorageType::kUnknown;
- std::string name;
- int use_count = 0;
- base::Time last_accessed;
- base::Time last_modified;
- };
-
static constexpr char kDatabaseName[] = "QuotaManager";
// If `profile_path` is empty, an in-memory database will be used.
@@ -153,18 +126,18 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaDatabase {
// Returns all buckets for `type` in the buckets table. Returns a QuotaError
// if the operation has failed.
- QuotaErrorOr<std::set<BucketLocator>> GetBucketsForType(
+ QuotaErrorOr<std::set<BucketInfo>> 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(
+ QuotaErrorOr<std::set<BucketInfo>> 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(
+ QuotaErrorOr<std::set<BucketInfo>> GetBucketsForStorageKey(
const blink::StorageKey& storage_key,
blink::mojom::StorageType type);
@@ -203,7 +176,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaDatabase {
// Returns the BucketTableEntry for `bucket` if one exists. Returns a
// QuotaError if not found or the operation has failed.
- QuotaErrorOr<BucketTableEntry> GetBucketInfo(BucketId bucket_id);
+ QuotaErrorOr<mojom::BucketTableEntryPtr> GetBucketInfo(BucketId bucket_id);
// Deletes the bucket from the database as well as the bucket directory in the
// storage directory.
@@ -242,6 +215,9 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaDatabase {
// one doesn't exist.
QuotaError RazeAndReopen();
+ // Flushes previously scheduled commits.
+ void CommitNow();
+
// Testing support for database corruption handling.
//
// Runs `corrupter` on the same sequence used to do database I/O,
@@ -273,9 +249,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaDatabase {
friend COMPONENT_EXPORT(STORAGE_BROWSER) bool operator<(
const QuotaTableEntry& lhs,
const QuotaTableEntry& rhs);
- friend COMPONENT_EXPORT(STORAGE_BROWSER) bool operator<(
- const BucketTableEntry& lhs,
- const BucketTableEntry& rhs);
// Structures used for CreateSchema.
struct TableSchema {
@@ -292,7 +265,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaDatabase {
using QuotaTableCallback =
base::RepeatingCallback<bool(const QuotaTableEntry&)>;
using BucketTableCallback =
- base::RepeatingCallback<bool(const BucketTableEntry&)>;
+ base::RepeatingCallback<bool(mojom::BucketTableEntryPtr)>;
// For long-running transactions support. We always keep a transaction open
// so that multiple transactions can be batched. They are flushed
diff --git a/chromium/storage/browser/quota/quota_database_unittest.cc b/chromium/storage/browser/quota/quota_database_unittest.cc
index 11ba7b3edea..bc6b36ad493 100644
--- a/chromium/storage/browser/quota/quota_database_unittest.cc
+++ b/chromium/storage/browser/quota/quota_database_unittest.cc
@@ -32,6 +32,7 @@
#include "sql/test/test_helpers.h"
#include "storage/browser/quota/quota_client_type.h"
#include "storage/browser/quota/quota_database.h"
+#include "storage/browser/quota/quota_internals.mojom.h"
#include "storage/browser/quota/storage_directory_util.h"
#include "storage/browser/test/mock_special_storage_policy.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -50,6 +51,11 @@ static const blink::mojom::StorageType kTemp =
static const blink::mojom::StorageType kPerm =
blink::mojom::StorageType::kPersistent;
+static const storage::mojom::StorageType kStorageTemp =
+ storage::mojom::StorageType::kTemporary;
+static const storage::mojom::StorageType kStoragePerm =
+ storage::mojom::StorageType::kPersistent;
+
static constexpr char kDatabaseName[] = "QuotaManager";
bool ContainsBucket(const std::set<BucketLocator>& buckets,
@@ -64,7 +70,7 @@ bool ContainsBucket(const std::set<BucketLocator>& buckets,
// mode. True will create the database in memory.
class QuotaDatabaseTest : public testing::TestWithParam<bool> {
protected:
- using BucketTableEntry = QuotaDatabase::BucketTableEntry;
+ using BucketTableEntry = mojom::BucketTableEntry;
void SetUp() override { ASSERT_TRUE(temp_directory_.CreateUniqueTempDir()); }
@@ -93,12 +99,15 @@ class QuotaDatabaseTest : public testing::TestWithParam<bool> {
struct EntryVerifier {
std::set<EntryType> table;
- template <typename Iterator>
- EntryVerifier(Iterator itr, Iterator end)
- : table(itr, end) {}
+ template <size_t length>
+ explicit EntryVerifier(const EntryType (&entries)[length]) {
+ for (size_t i = 0; i < length; ++i) {
+ table.insert(entries[i]->Clone());
+ }
+ }
- bool Run(const EntryType& entry) {
- EXPECT_EQ(1u, table.erase(entry));
+ bool Run(EntryType entry) {
+ EXPECT_EQ(1u, table.erase(std::move(entry)));
return true;
}
};
@@ -163,14 +172,18 @@ class QuotaDatabaseTest : public testing::TestWithParam<bool> {
quota_database->db_->GetCachedStatement(SQL_FROM_HERE, kSql));
ASSERT_TRUE(statement.is_valid());
- statement.BindInt64(0, entry.bucket_id.value());
- statement.BindString(1, entry.storage_key.Serialize());
- 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);
+ absl::optional<StorageKey> storage_key =
+ StorageKey::Deserialize(entry->storage_key);
+ ASSERT_TRUE(storage_key.has_value());
+
+ statement.BindInt64(0, entry->bucket_id);
+ statement.BindString(1, entry->storage_key);
+ statement.BindString(2, std::move(storage_key).value().origin().host());
+ statement.BindInt(3, static_cast<int>(entry->type));
+ statement.BindString(4, entry->name);
+ statement.BindInt(5, static_cast<int>(entry->use_count));
+ statement.BindTime(6, entry->last_accessed);
+ statement.BindTime(7, entry->last_modified);
EXPECT_TRUE(statement.Run());
}
quota_database->Commit();
@@ -459,16 +472,16 @@ TEST_P(QuotaDatabaseTest, GetBucketsForType) {
ASSERT_TRUE(bucket_result.ok());
BucketInfo perm_bucket2 = bucket_result.value();
- QuotaErrorOr<std::set<BucketLocator>> result = db->GetBucketsForType(kTemp);
+ QuotaErrorOr<std::set<BucketInfo>> result = db->GetBucketsForType(kTemp);
ASSERT_TRUE(result.ok());
- std::set<BucketLocator> buckets = result.value();
+ std::set<BucketLocator> buckets = BucketInfosToBucketLocators(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();
+ buckets = BucketInfosToBucketLocators(result.value());
ASSERT_EQ(2U, buckets.size());
EXPECT_TRUE(ContainsBucket(buckets, perm_bucket1));
EXPECT_TRUE(ContainsBucket(buckets, perm_bucket2));
@@ -491,12 +504,12 @@ TEST_P(QuotaDatabaseTest, GetBucketsForHost) {
StorageKey::CreateFromStringForTesting("http://google.com:123/"),
"default", kTemp);
- QuotaErrorOr<std::set<BucketLocator>> result =
+ QuotaErrorOr<std::set<BucketInfo>> 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()));
+ EXPECT_TRUE(base::Contains(result.value(), temp_example_bucket1.value()));
+ EXPECT_TRUE(base::Contains(result.value(), temp_example_bucket2.value()));
result = db->GetBucketsForHost("example.com", kPerm);
ASSERT_TRUE(result.ok());
@@ -505,12 +518,12 @@ TEST_P(QuotaDatabaseTest, GetBucketsForHost) {
result = db->GetBucketsForHost("google.com", kPerm);
ASSERT_TRUE(result.ok());
ASSERT_EQ(result->size(), 1U);
- EXPECT_TRUE(ContainsBucket(result.value(), perm_google_bucket1.value()));
+ EXPECT_TRUE(base::Contains(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()));
+ EXPECT_TRUE(base::Contains(result.value(), temp_google_bucket2.value()));
}
TEST_P(QuotaDatabaseTest, GetBucketsForStorageKey) {
@@ -539,17 +552,17 @@ TEST_P(QuotaDatabaseTest, GetBucketsForStorageKey) {
ASSERT_TRUE(bucket_result.ok());
BucketInfo perm_bucket2 = bucket_result.value();
- QuotaErrorOr<std::set<BucketLocator>> result =
+ QuotaErrorOr<std::set<BucketInfo>> result =
db->GetBucketsForStorageKey(storage_key1, kTemp);
ASSERT_TRUE(result.ok());
- std::set<BucketLocator> buckets = result.value();
+ std::set<BucketLocator> buckets = BucketInfosToBucketLocators(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();
+ buckets = BucketInfosToBucketLocators(result.value());
ASSERT_EQ(1U, buckets.size());
EXPECT_TRUE(ContainsBucket(buckets, perm_bucket2));
}
@@ -566,37 +579,52 @@ TEST_P(QuotaDatabaseTest, BucketLastAccessTimeLRU) {
// Insert bucket entries into BucketTable.
base::Time now = base::Time::Now();
- using Entry = QuotaDatabase::BucketTableEntry;
- Entry bucket1 = Entry(
- BucketId(1), StorageKey::CreateFromStringForTesting("http://example-a/"),
- kTemp, kDefaultBucketName, 99, now, now);
- Entry bucket2 = Entry(
- BucketId(2), StorageKey::CreateFromStringForTesting("http://example-b/"),
- kTemp, kDefaultBucketName, 0, now, now);
- Entry bucket3 = Entry(
- BucketId(3), StorageKey::CreateFromStringForTesting("http://example-c/"),
- kTemp, "bucket_c", 1, now, now);
- Entry bucket4 = Entry(
- BucketId(4), StorageKey::CreateFromStringForTesting("http://example-d/"),
- kPerm, "bucket_d", 5, now, now);
- Entry kTableEntries[] = {bucket1, bucket2, bucket3, bucket4};
+ using Entry = mojom::BucketTableEntryPtr;
+ StorageKey storage_key1 =
+ StorageKey::CreateFromStringForTesting("http://example-a/");
+ StorageKey storage_key2 =
+ StorageKey::CreateFromStringForTesting("http://example-b/");
+ StorageKey storage_key3 =
+ StorageKey::CreateFromStringForTesting("http://example-c/");
+ StorageKey storage_key4 =
+ StorageKey::CreateFromStringForTesting("http://example-d/");
+
+ BucketId bucket_id1 = BucketId(1);
+ BucketId bucket_id2 = BucketId(2);
+ BucketId bucket_id3 = BucketId(3);
+ BucketId bucket_id4 = BucketId(4);
+
+ Entry bucket1 = mojom::BucketTableEntry::New(
+ bucket_id1.value(), storage_key1.Serialize(), kStorageTemp,
+ kDefaultBucketName, -1, 99, now, now);
+ Entry bucket2 = mojom::BucketTableEntry::New(
+ bucket_id2.value(), storage_key2.Serialize(), kStorageTemp,
+ kDefaultBucketName, -1, 0, now, now);
+ Entry bucket3 =
+ mojom::BucketTableEntry::New(bucket_id3.value(), storage_key3.Serialize(),
+ kStorageTemp, "bucket_c", -1, 1, now, now);
+ Entry bucket4 =
+ mojom::BucketTableEntry::New(bucket_id4.value(), storage_key4.Serialize(),
+ kStoragePerm, "bucket_d", -1, 5, now, now);
+ Entry kTableEntries[] = {bucket1->Clone(), bucket2->Clone(), bucket3->Clone(),
+ bucket4->Clone()};
AssignBucketTable(db.get(), kTableEntries);
// Update access time for three temporary storages, and
- 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);
+ EXPECT_EQ(
+ db->SetBucketLastAccessTime(bucket_id1, base::Time::FromJavaTime(10)),
+ QuotaError::kNone);
+ EXPECT_EQ(
+ db->SetBucketLastAccessTime(bucket_id2, base::Time::FromJavaTime(20)),
+ QuotaError::kNone);
+ EXPECT_EQ(
+ db->SetBucketLastAccessTime(bucket_id3, base::Time::FromJavaTime(30)),
+ QuotaError::kNone);
// One persistent.
- EXPECT_EQ(db->SetBucketLastAccessTime(bucket4.bucket_id,
- base::Time::FromJavaTime(40)),
- QuotaError::kNone);
+ EXPECT_EQ(
+ db->SetBucketLastAccessTime(bucket_id4, base::Time::FromJavaTime(40)),
+ QuotaError::kNone);
// One non-existent.
EXPECT_EQ(
@@ -605,53 +633,58 @@ TEST_P(QuotaDatabaseTest, BucketLastAccessTimeLRU) {
result = db->GetLruEvictableBucket(kTemp, bucket_exceptions, nullptr);
EXPECT_TRUE(result.ok());
- EXPECT_EQ(bucket1.bucket_id, result.value().id);
+ EXPECT_EQ(bucket_id1, result.value().id);
// Test that unlimited origins are excluded from eviction, but
// protected origins are not excluded.
auto policy = base::MakeRefCounted<MockSpecialStoragePolicy>();
- policy->AddUnlimited(bucket1.storage_key.origin().GetURL());
- policy->AddProtected(bucket2.storage_key.origin().GetURL());
+ policy->AddUnlimited(storage_key1.origin().GetURL());
+ policy->AddProtected(storage_key2.origin().GetURL());
result = db->GetLruEvictableBucket(kTemp, bucket_exceptions, policy.get());
EXPECT_TRUE(result.ok());
- EXPECT_EQ(bucket2.bucket_id, result.value().id);
+ EXPECT_EQ(bucket_id2, result.value().id);
// Test that durable origins are excluded from eviction.
- policy->AddDurable(bucket2.storage_key.origin().GetURL());
+ policy->AddDurable(storage_key2.origin().GetURL());
result = db->GetLruEvictableBucket(kTemp, bucket_exceptions, policy.get());
EXPECT_TRUE(result.ok());
- EXPECT_EQ(bucket3.bucket_id, result.value().id);
+ EXPECT_EQ(bucket_id3, result.value().id);
// Bucket exceptions exclude specified buckets.
- bucket_exceptions.insert(bucket1.bucket_id);
+ bucket_exceptions.insert(bucket_id1);
result = db->GetLruEvictableBucket(kTemp, bucket_exceptions, nullptr);
EXPECT_TRUE(result.ok());
- EXPECT_EQ(bucket2.bucket_id, result.value().id);
+ EXPECT_EQ(bucket_id2, result.value().id);
- bucket_exceptions.insert(bucket2.bucket_id);
+ bucket_exceptions.insert(bucket_id2);
result = db->GetLruEvictableBucket(kTemp, bucket_exceptions, nullptr);
EXPECT_TRUE(result.ok());
- EXPECT_EQ(bucket3.bucket_id, result.value().id);
+ EXPECT_EQ(bucket_id3, result.value().id);
- bucket_exceptions.insert(bucket3.bucket_id);
+ bucket_exceptions.insert(bucket_id3);
result = db->GetLruEvictableBucket(kTemp, bucket_exceptions, nullptr);
EXPECT_FALSE(result.ok());
EXPECT_EQ(result.error(), QuotaError::kNotFound);
- EXPECT_EQ(db->SetBucketLastAccessTime(bucket1.bucket_id, base::Time::Now()),
+ EXPECT_EQ(db->SetBucketLastAccessTime(bucket_id1, base::Time::Now()),
QuotaError::kNone);
+ BucketLocator bucketLocator =
+ BucketLocator(bucket_id3, storage_key3,
+ static_cast<blink::mojom::StorageType>(bucket3->type),
+ bucket3->name == kDefaultBucketName);
+
// Delete storage_key/type last access time information.
- EXPECT_EQ(db->DeleteBucketData(bucket3.ToBucketLocator()), QuotaError::kNone);
+ EXPECT_EQ(db->DeleteBucketData(bucketLocator), QuotaError::kNone);
// Querying again to see if the deletion has worked.
bucket_exceptions.clear();
result = db->GetLruEvictableBucket(kTemp, bucket_exceptions, nullptr);
EXPECT_TRUE(result.ok());
- EXPECT_EQ(bucket2.bucket_id, result.value().id);
+ EXPECT_EQ(bucket_id2, result.value().id);
- bucket_exceptions.insert(bucket1.bucket_id);
- bucket_exceptions.insert(bucket2.bucket_id);
+ bucket_exceptions.insert(bucket_id1);
+ bucket_exceptions.insert(bucket_id2);
result = db->GetLruEvictableBucket(kTemp, bucket_exceptions, nullptr);
EXPECT_FALSE(result.ok());
EXPECT_EQ(result.error(), QuotaError::kNotFound);
@@ -669,31 +702,40 @@ TEST_P(QuotaDatabaseTest, BucketPersistence) {
// Insert bucket entries into BucketTable.
base::Time now = base::Time::Now();
- using Entry = QuotaDatabase::BucketTableEntry;
- Entry bucket1 = Entry(
- BucketId(1), StorageKey::CreateFromStringForTesting("http://example-a/"),
- kTemp, kDefaultBucketName, 99, now, now);
- Entry bucket2 = Entry(
- BucketId(2), StorageKey::CreateFromStringForTesting("http://example-b/"),
- kTemp, kDefaultBucketName, 0, now, now);
- Entry kTableEntries[] = {bucket1, bucket2};
+ using Entry = mojom::BucketTableEntryPtr;
+
+ StorageKey storage_key1 =
+ StorageKey::CreateFromStringForTesting("http://example-a/");
+ StorageKey storage_key2 =
+ StorageKey::CreateFromStringForTesting("http://example-b/");
+
+ BucketId bucket_id1 = BucketId(1);
+ BucketId bucket_id2 = BucketId(2);
+
+ Entry bucket1 = mojom::BucketTableEntry::New(
+ bucket_id1.value(), storage_key1.Serialize(), kStorageTemp,
+ kDefaultBucketName, -1, 99, now, now);
+ Entry bucket2 = mojom::BucketTableEntry::New(
+ bucket_id2.value(), storage_key2.Serialize(), kStorageTemp,
+ kDefaultBucketName, -1, 0, now, now);
+ Entry kTableEntries[] = {bucket1->Clone(), bucket2->Clone()};
AssignBucketTable(db.get(), kTableEntries);
- 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(bucket_id1, base::Time::FromJavaTime(10)),
+ QuotaError::kNone);
+ EXPECT_EQ(
+ db->SetBucketLastAccessTime(bucket_id2, base::Time::FromJavaTime(20)),
+ QuotaError::kNone);
result = db->GetLruEvictableBucket(kTemp, bucket_exceptions, nullptr);
EXPECT_TRUE(result.ok());
- EXPECT_EQ(bucket1.bucket_id, result.value().id);
+ EXPECT_EQ(bucket_id1, result.value().id);
- ASSERT_TRUE(db->UpdateBucketPersistence(bucket1.bucket_id, true).ok());
+ ASSERT_TRUE(db->UpdateBucketPersistence(bucket_id1, true).ok());
result = db->GetLruEvictableBucket(kTemp, bucket_exceptions, nullptr);
EXPECT_TRUE(result.ok());
- EXPECT_EQ(bucket2.bucket_id, result.value().id);
+ EXPECT_EQ(bucket_id2, result.value().id);
}
TEST_P(QuotaDatabaseTest, SetStorageKeyLastAccessTime) {
@@ -714,11 +756,10 @@ TEST_P(QuotaDatabaseTest, SetStorageKeyLastAccessTime) {
EXPECT_EQ(db->SetStorageKeyLastAccessTime(storage_key, kTemp, now),
QuotaError::kNone);
- QuotaErrorOr<QuotaDatabase::BucketTableEntry> info =
- db->GetBucketInfo(bucket->id);
+ QuotaErrorOr<mojom::BucketTableEntryPtr> info = db->GetBucketInfo(bucket->id);
EXPECT_TRUE(info.ok());
- EXPECT_EQ(now, info->last_accessed);
- EXPECT_EQ(1, info->use_count);
+ EXPECT_EQ(now, info.value()->last_accessed);
+ EXPECT_EQ(1, info.value()->use_count);
}
TEST_P(QuotaDatabaseTest, GetStorageKeysForType) {
@@ -889,10 +930,10 @@ TEST_P(QuotaDatabaseTest, RegisterInitialStorageKeyInfo) {
kDefaultBucketName, kTemp);
ASSERT_TRUE(bucket_result.ok());
- QuotaErrorOr<QuotaDatabase::BucketTableEntry> info =
+ QuotaErrorOr<mojom::BucketTableEntryPtr> info =
db->GetBucketInfo(bucket_result->id);
EXPECT_TRUE(info.ok());
- EXPECT_EQ(0, info->use_count);
+ EXPECT_EQ(0, info.value()->use_count);
EXPECT_EQ(db->SetStorageKeyLastAccessTime(
StorageKey::CreateFromStringForTesting("http://a/"), kTemp,
@@ -900,26 +941,35 @@ TEST_P(QuotaDatabaseTest, RegisterInitialStorageKeyInfo) {
QuotaError::kNone);
info = db->GetBucketInfo(bucket_result->id);
EXPECT_TRUE(info.ok());
- EXPECT_EQ(1, info->use_count);
+ EXPECT_EQ(1, info.value()->use_count);
EXPECT_EQ(db->RegisterInitialStorageKeyInfo(storage_keys_by_type),
QuotaError::kNone);
info = db->GetBucketInfo(bucket_result->id);
EXPECT_TRUE(info.ok());
- EXPECT_EQ(1, info->use_count);
+ EXPECT_EQ(1, info.value()->use_count);
}
TEST_P(QuotaDatabaseTest, DumpBucketTable) {
base::Time now = base::Time::Now();
- using Entry = QuotaDatabase::BucketTableEntry;
+ using Entry = mojom::BucketTableEntryPtr;
+
+ StorageKey storage_key1 =
+ StorageKey::CreateFromStringForTesting("http://go/");
+ StorageKey storage_key2 =
+ StorageKey::CreateFromStringForTesting("http://oo/");
+ StorageKey storage_key3 =
+ StorageKey::CreateFromStringForTesting("http://gle/");
+
Entry kTableEntries[] = {
- Entry(BucketId(1), StorageKey::CreateFromStringForTesting("http://go/"),
- kTemp, kDefaultBucketName, 2147483647, now, now),
- Entry(BucketId(2), StorageKey::CreateFromStringForTesting("http://oo/"),
- kTemp, kDefaultBucketName, 0, now, now),
- Entry(BucketId(3), StorageKey::CreateFromStringForTesting("http://gle/"),
- kTemp, kDefaultBucketName, 1, now, now),
+ mojom::BucketTableEntry::New(1, storage_key1.Serialize(), kStorageTemp,
+ kDefaultBucketName, -1, 2147483647, now,
+ now),
+ mojom::BucketTableEntry::New(2, storage_key2.Serialize(), kStorageTemp,
+ kDefaultBucketName, -1, 0, now, now),
+ mojom::BucketTableEntry::New(3, storage_key3.Serialize(), kStorageTemp,
+ kDefaultBucketName, -1, 1, now, now),
};
auto db = CreateDatabase(use_in_memory_db());
@@ -927,7 +977,7 @@ TEST_P(QuotaDatabaseTest, DumpBucketTable) {
AssignBucketTable(db.get(), kTableEntries);
using Verifier = EntryVerifier<Entry>;
- Verifier verifier(kTableEntries, std::end(kTableEntries));
+ Verifier verifier(kTableEntries);
EXPECT_EQ(DumpBucketTable(db.get(),
base::BindRepeating(&Verifier::Run,
base::Unretained(&verifier))),
@@ -936,32 +986,34 @@ TEST_P(QuotaDatabaseTest, DumpBucketTable) {
}
TEST_P(QuotaDatabaseTest, GetBucketInfo) {
- using Entry = QuotaDatabase::BucketTableEntry;
- Entry kTableEntries[] = {
- Entry(BucketId(123), StorageKey::CreateFromStringForTesting("http://go/"),
- kTemp, "test_bucket", 100, base::Time(), base::Time())};
+ using Entry = mojom::BucketTableEntryPtr;
+ StorageKey storage_key = StorageKey::CreateFromStringForTesting("http://go/");
+ BucketId bucket_id = BucketId(123);
+ storage::mojom::StorageType type = kStorageTemp;
+
+ Entry kTableEntries[] = {mojom::BucketTableEntry::New(
+ bucket_id.value(), storage_key.Serialize(), type, "test_bucket", -1, 100,
+ base::Time(), base::Time())};
auto db = CreateDatabase(use_in_memory_db());
EXPECT_TRUE(EnsureOpened(db.get()));
AssignBucketTable(db.get(), kTableEntries);
{
- QuotaErrorOr<QuotaDatabase::BucketTableEntry> entry =
- db->GetBucketInfo(kTableEntries[0].bucket_id);
+ QuotaErrorOr<Entry> entry = db->GetBucketInfo(bucket_id);
EXPECT_TRUE(entry.ok());
- EXPECT_EQ(kTableEntries[0].bucket_id, entry->bucket_id);
- 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);
+ EXPECT_EQ(bucket_id.value(), entry.value()->bucket_id);
+ EXPECT_EQ(type, entry.value()->type);
+ EXPECT_EQ(storage_key.Serialize(), entry.value()->storage_key);
+ EXPECT_EQ(kTableEntries[0]->name, entry.value()->name);
+ EXPECT_EQ(kTableEntries[0]->use_count, entry.value()->use_count);
+ EXPECT_EQ(kTableEntries[0]->last_accessed, entry.value()->last_accessed);
+ EXPECT_EQ(kTableEntries[0]->last_modified, entry.value()->last_modified);
}
{
// BucketId 456 is not in the database.
- QuotaErrorOr<QuotaDatabase::BucketTableEntry> entry =
- db->GetBucketInfo(BucketId(456));
+ QuotaErrorOr<Entry> entry = db->GetBucketInfo(BucketId(456));
EXPECT_FALSE(entry.ok());
}
}
diff --git a/chromium/storage/browser/quota/quota_device_info_helper.cc b/chromium/storage/browser/quota/quota_device_info_helper.cc
index 8f415442983..cf12c20ac81 100644
--- a/chromium/storage/browser/quota/quota_device_info_helper.cc
+++ b/chromium/storage/browser/quota/quota_device_info_helper.cc
@@ -17,7 +17,7 @@ int64_t QuotaDeviceInfoHelper::AmountOfTotalDiskSpace(
return disk_space;
}
-int64_t QuotaDeviceInfoHelper::AmountOfPhysicalMemory() const {
+uint64_t QuotaDeviceInfoHelper::AmountOfPhysicalMemory() const {
return base::SysInfo::AmountOfPhysicalMemory();
}
diff --git a/chromium/storage/browser/quota/quota_device_info_helper.h b/chromium/storage/browser/quota/quota_device_info_helper.h
index 2ce8b16f8ee..1f865d87d4f 100644
--- a/chromium/storage/browser/quota/quota_device_info_helper.h
+++ b/chromium/storage/browser/quota/quota_device_info_helper.h
@@ -25,7 +25,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaDeviceInfoHelper {
virtual int64_t AmountOfTotalDiskSpace(const base::FilePath& path) const;
- virtual int64_t AmountOfPhysicalMemory() const;
+ virtual uint64_t AmountOfPhysicalMemory() const;
}; // class QuotaDeviceInfoHelper
} // namespace storage
diff --git a/chromium/storage/browser/quota/quota_internals.mojom b/chromium/storage/browser/quota/quota_internals.mojom
index 5db2a565bb7..39d676f10fb 100644
--- a/chromium/storage/browser/quota/quota_internals.mojom
+++ b/chromium/storage/browser/quota/quota_internals.mojom
@@ -11,10 +11,9 @@ import "url/mojom/origin.mojom";
struct BucketTableEntry {
int64 bucket_id;
string storage_key;
- string host;
- string type;
+ StorageType type;
string name;
- int64 usage;
+ int64 usage = -1;
int64 use_count;
mojo_base.mojom.Time last_accessed;
mojo_base.mojom.Time last_modified;
@@ -49,10 +48,6 @@ interface QuotaInternalsHandler {
// Returns an array of Storage Bucket entries stored in the QuotaDatabase.
RetrieveBucketsTable() => (array<BucketTableEntry> entries);
- // Returns a host's usage for a given storage type.
- GetHostUsageForInternals(string host, StorageType storage_type) =>
- (int64 host_usage);
-
// Returns the global usage and unlimited usage for a given storage type.
GetGlobalUsageForInternals(StorageType storage_type) =>
(int64 usage, int64 unlimited_usage);
diff --git a/chromium/storage/browser/quota/quota_manager_impl.cc b/chromium/storage/browser/quota/quota_manager_impl.cc
index 361e9927580..d3f076074e8 100644
--- a/chromium/storage/browser/quota/quota_manager_impl.cc
+++ b/chromium/storage/browser/quota/quota_manager_impl.cc
@@ -14,6 +14,7 @@
#include <memory>
#include <utility>
+#include "base/barrier_callback.h"
#include "base/barrier_closure.h"
#include "base/bind.h"
#include "base/callback.h"
@@ -85,14 +86,6 @@ int64_t RandomizeByPercent(int64_t value, int percent) {
double random_percent = (base::RandDouble() - 0.5) * percent * 2;
return value * (1 + (random_percent / 100.0));
}
-} // namespace
-
-// Heuristics: assuming average cloud server allows a few Gigs storage
-// on the server side and the storage needs to be shared for user data
-// and by multiple apps.
-int64_t QuotaManagerImpl::kSyncableStorageDefaultHostQuota = 500 * kMBytes;
-
-namespace {
bool IsSupportedType(StorageType type) {
return type == StorageType::kTemporary || type == StorageType::kPersistent ||
@@ -103,21 +96,6 @@ bool IsSupportedIncognitoType(StorageType type) {
return type == StorageType::kTemporary || type == StorageType::kPersistent;
}
-std::string StorageTypeEnumToString(StorageType type) {
- switch (type) {
- case StorageType::kTemporary:
- return "temporary";
- case StorageType::kPersistent:
- return "persistent";
- case StorageType::kSyncable:
- return "syncable";
- case StorageType::kQuotaNotManaged:
- return "quota-not-managed";
- case StorageType::kUnknown:
- return "unknown";
- }
-}
-
StorageType GetBlinkStorageType(storage::mojom::StorageType type) {
switch (type) {
case storage::mojom::StorageType::kTemporary:
@@ -152,6 +130,11 @@ void DidGetUsageAndQuotaStripOverride(
} // namespace
+// Heuristics: assuming average cloud server allows a few Gigs storage
+// on the server side and the storage needs to be shared for user data
+// and by multiple apps.
+int64_t QuotaManagerImpl::kSyncableStorageDefaultHostQuota = 500 * kMBytes;
+
constexpr int64_t QuotaManagerImpl::kGBytes;
constexpr int64_t QuotaManagerImpl::kNoLimit;
constexpr int64_t QuotaManagerImpl::kPerHostPersistentQuotaLimit;
@@ -664,11 +647,13 @@ class QuotaManagerImpl::BucketDataDeleter {
QuotaManagerImpl* manager,
const BucketLocator& bucket,
QuotaClientTypes quota_client_types,
+ bool commit_immediately,
base::OnceCallback<void(BucketDataDeleter*,
blink::mojom::QuotaStatusCode)> callback)
: manager_(manager),
bucket_(bucket),
quota_client_types_(std::move(quota_client_types)),
+ commit_immediately_(commit_immediately),
callback_(std::move(callback)) {
DCHECK(manager_);
// TODO(crbug/1292216): Convert back into DCHECKs once issue is resolved.
@@ -754,7 +739,7 @@ class QuotaManagerImpl::BucketDataDeleter {
// types.
if (skipped_clients_ == 0 && error_count_ == 0) {
manager_->DeleteBucketFromDatabase(
- bucket_,
+ bucket_, commit_immediately_,
base::BindOnce(&BucketDataDeleter::DidDeleteBucketFromDatabase,
weak_factory_.GetWeakPtr()));
return;
@@ -786,6 +771,9 @@ class QuotaManagerImpl::BucketDataDeleter {
GUARDED_BY_CONTEXT(sequence_checker_);
const BucketLocator bucket_;
const QuotaClientTypes quota_client_types_;
+ // Whether the update to the database should be committed immediately (if not,
+ // it will be scheduled to be committed as part of a batch).
+ const bool commit_immediately_;
int error_count_ GUARDED_BY_CONTEXT(sequence_checker_) = 0;
size_t remaining_clients_ GUARDED_BY_CONTEXT(sequence_checker_) = 0;
int skipped_clients_ GUARDED_BY_CONTEXT(sequence_checker_) = 0;
@@ -848,14 +836,14 @@ class QuotaManagerImpl::HostDataDeleter {
}
private:
- void DidGetBucketsForHost(QuotaErrorOr<std::set<BucketLocator>> result) {
+ void DidGetBucketsForHost(QuotaErrorOr<std::set<BucketInfo>> result) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!result.ok()) {
Complete(/*success=*/false);
return;
}
- buckets_ = result.value();
+ buckets_ = BucketInfosToBucketLocators(result.value());
if (!buckets_.empty()) {
ScheduleBucketsDeletion();
return;
@@ -871,7 +859,7 @@ class QuotaManagerImpl::HostDataDeleter {
// BucketDataDeleter created here, which guarantees it will only use the
// callback when it's alive.
auto bucket_deleter = std::make_unique<BucketDataDeleter>(
- manager_, bucket, AllQuotaClientTypes(),
+ manager_, bucket, AllQuotaClientTypes(), /*commit_immediately=*/false,
base::BindOnce(&HostDataDeleter::DidDeleteBucketData,
base::Unretained(this)));
auto* bucket_deleter_ptr = bucket_deleter.get();
@@ -1008,12 +996,12 @@ class QuotaManagerImpl::DumpBucketTableHelper {
return;
}
manager->DidDatabaseWork(error != QuotaError::kDatabaseError);
- std::move(callback).Run(entries_);
+ std::move(callback).Run(std::move(entries_));
}
private:
- bool AppendEntry(const BucketTableEntry& entry) {
- entries_.push_back(entry);
+ bool AppendEntry(mojom::BucketTableEntryPtr entry) {
+ entries_.push_back(std::move(entry));
return true;
}
@@ -1209,7 +1197,7 @@ void QuotaManagerImpl::GetStorageKeysForType(blink::mojom::StorageType type,
void QuotaManagerImpl::GetBucketsForType(
blink::mojom::StorageType type,
- base::OnceCallback<void(QuotaErrorOr<std::set<BucketLocator>>)> callback) {
+ base::OnceCallback<void(QuotaErrorOr<std::set<BucketInfo>>)> callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(callback);
EnsureDatabaseOpened();
@@ -1232,7 +1220,7 @@ void QuotaManagerImpl::GetBucketsForType(
void QuotaManagerImpl::GetBucketsForHost(
const std::string& host,
blink::mojom::StorageType type,
- base::OnceCallback<void(QuotaErrorOr<std::set<BucketLocator>>)> callback) {
+ base::OnceCallback<void(QuotaErrorOr<std::set<BucketInfo>>)> callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(callback);
EnsureDatabaseOpened();
@@ -1256,7 +1244,8 @@ void QuotaManagerImpl::GetBucketsForHost(
void QuotaManagerImpl::GetBucketsForStorageKey(
const StorageKey& storage_key,
blink::mojom::StorageType type,
- base::OnceCallback<void(QuotaErrorOr<std::set<BucketLocator>>)> callback) {
+ base::OnceCallback<void(QuotaErrorOr<std::set<BucketInfo>>)> callback,
+ bool delete_expired) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(callback);
EnsureDatabaseOpened();
@@ -1265,6 +1254,16 @@ void QuotaManagerImpl::GetBucketsForStorageKey(
std::move(callback).Run(QuotaError::kDatabaseError);
return;
}
+
+ base::OnceCallback<void(QuotaErrorOr<std::set<BucketInfo>>)> reply;
+ if (delete_expired) {
+ reply = base::BindOnce(&QuotaManagerImpl::DidGetBucketsCheckExpiration,
+ weak_factory_.GetWeakPtr(), std::move(callback));
+ } else {
+ reply = base::BindOnce(&QuotaManagerImpl::DidGetBuckets,
+ weak_factory_.GetWeakPtr(), std::move(callback));
+ }
+
PostTaskAndReplyWithResultForDBThread(
base::BindOnce(
[](const StorageKey& storage_key, StorageType type,
@@ -1273,8 +1272,7 @@ void QuotaManagerImpl::GetBucketsForStorageKey(
return database->GetBucketsForStorageKey(storage_key, type);
},
storage_key, type),
- base::BindOnce(&QuotaManagerImpl::DidGetBuckets,
- weak_factory_.GetWeakPtr(), std::move(callback)));
+ std::move(reply));
}
void QuotaManagerImpl::GetUsageInfo(GetUsageInfoCallback callback) {
@@ -1729,22 +1727,6 @@ void QuotaManagerImpl::GetBucketUsageWithBreakdown(
usage_tracker->GetBucketUsageWithBreakdown(bucket, std::move(callback));
}
-void QuotaManagerImpl::GetHostUsageForInternals(
- const std::string& host,
- storage::mojom::StorageType storage_type,
- GetHostUsageForInternalsCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- EnsureDatabaseOpened();
-
- StorageType type = GetBlinkStorageType(storage_type);
- UsageTracker* usage_tracker = GetUsageTracker(type);
- DCHECK(usage_tracker);
-
- usage_tracker->GetHostUsageWithBreakdown(
- host, base::BindOnce(&QuotaManagerImpl::OnGetHostUsageForInternals,
- weak_factory_.GetWeakPtr(), std::move(callback)));
-}
-
bool QuotaManagerImpl::IsSessionOnly(const StorageKey& storage_key,
StorageType type) const {
return type == StorageType::kTemporary && special_storage_policy_ &&
@@ -1760,7 +1742,7 @@ bool QuotaManagerImpl::IsStorageUnlimited(const StorageKey& storage_key,
// quota must be capped by the server limit).
if (type == StorageType::kSyncable)
return false;
- if (type == StorageType::kQuotaNotManaged)
+ if (type == StorageType::kDeprecatedQuotaNotManaged)
return true;
return special_storage_policy_.get() &&
special_storage_policy_->IsStorageUnlimited(
@@ -1822,7 +1804,7 @@ QuotaManagerImpl::~QuotaManagerImpl() {
proxy_->InvalidateQuotaManagerImpl(base::PassKey<QuotaManagerImpl>());
if (database_)
- db_runner_->DeleteSoon(FROM_HERE, database_.get());
+ db_runner_->DeleteSoon(FROM_HERE, database_.ExtractAsDangling().get());
}
QuotaManagerImpl::EvictionContext::EvictionContext() = default;
@@ -1968,7 +1950,7 @@ UsageTracker* QuotaManagerImpl::GetUsageTracker(StorageType type) const {
return persistent_usage_tracker_.get();
case StorageType::kSyncable:
return syncable_usage_tracker_.get();
- case StorageType::kQuotaNotManaged:
+ case StorageType::kDeprecatedQuotaNotManaged:
return nullptr;
case StorageType::kUnknown:
NOTREACHED();
@@ -1976,16 +1958,6 @@ UsageTracker* QuotaManagerImpl::GetUsageTracker(StorageType type) const {
return nullptr;
}
-void QuotaManagerImpl::OnGetHostUsageForInternals(
- GetHostUsageForInternalsCallback callback,
- int64_t usage,
- blink::mojom::UsageBreakdownPtr usage_breakdown) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK_GE(usage, -1);
-
- std::move(callback).Run(usage);
-}
-
void QuotaManagerImpl::NotifyStorageAccessed(const StorageKey& storage_key,
StorageType type,
base::Time access_time) {
@@ -2121,52 +2093,44 @@ void QuotaManagerImpl::RetrieveBucketsTable(
void QuotaManagerImpl::RetrieveBucketUsageForBucketTable(
RetrieveBucketsTableCallback callback,
- const BucketTableEntries& entries) {
+ BucketTableEntries entries) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- auto* buckets = new std::vector<storage::mojom::BucketTableEntryPtr>;
-
- base::RepeatingClosure barrier = base::BarrierClosure(
- entries.size(),
- base::BindOnce(
- [](RetrieveBucketsTableCallback callback,
- std::vector<storage::mojom::BucketTableEntryPtr>* buckets) {
- std::move(callback).Run(std::move(*buckets));
- },
- std::move(callback), base::Owned(buckets)));
+ base::RepeatingCallback<void(mojom::BucketTableEntryPtr)> barrier =
+ base::BarrierCallback<mojom::BucketTableEntryPtr>(entries.size(),
+ std::move(callback));
for (auto& entry : entries) {
- DCHECK(IsSupportedType(entry.type));
+ StorageType type = static_cast<StorageType>(entry->type);
+ DCHECK(IsSupportedType(type));
+
+ absl::optional<StorageKey> storage_key =
+ StorageKey::Deserialize(entry->storage_key);
+ DCHECK(storage_key.has_value());
+
+ BucketId bucket_id = BucketId(entry->bucket_id);
+
+ BucketLocator bucket_locator =
+ BucketLocator(bucket_id, std::move(storage_key).value(), type,
+ entry->name == kDefaultBucketName);
GetBucketUsageWithBreakdown(
- entry.ToBucketLocator(),
+ bucket_locator,
base::BindOnce(&QuotaManagerImpl::AddBucketTableEntry,
- weak_factory_.GetWeakPtr(), entry, barrier, buckets));
+ weak_factory_.GetWeakPtr(), std::move(entry), barrier));
}
}
void QuotaManagerImpl::AddBucketTableEntry(
- const BucketTableEntry& entry,
- base::OnceClosure barrier_callback,
- std::vector<storage::mojom::BucketTableEntryPtr>* buckets,
+ mojom::BucketTableEntryPtr entry,
+ base::OnceCallback<void(mojom::BucketTableEntryPtr)> barrier_callback,
int64_t usage,
- blink::mojom::UsageBreakdownPtr bucketUsageBreakdown) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
- storage::mojom::BucketTableEntryPtr mojo_entry =
- storage::mojom::BucketTableEntry::New();
- mojo_entry->bucket_id = entry.bucket_id.value();
- mojo_entry->storage_key = entry.storage_key.Serialize();
- mojo_entry->host = entry.storage_key.origin().host();
- mojo_entry->type = StorageTypeEnumToString(entry.type);
- mojo_entry->name = entry.name;
- mojo_entry->use_count = entry.use_count;
- mojo_entry->last_accessed = entry.last_accessed;
- mojo_entry->last_modified = entry.last_modified;
- mojo_entry->usage = usage;
-
- buckets->emplace_back(std::move(mojo_entry));
- std::move(barrier_callback).Run();
+ blink::mojom::UsageBreakdownPtr bucket_usage_breakdown) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ entry->usage = usage;
+
+ std::move(barrier_callback).Run(std::move(entry));
}
void QuotaManagerImpl::StartEviction() {
@@ -2182,6 +2146,7 @@ void QuotaManagerImpl::StartEviction() {
void QuotaManagerImpl::DeleteBucketFromDatabase(
const BucketLocator& bucket,
+ bool commit_immediately,
base::OnceCallback<void(QuotaError)> callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(callback);
@@ -2194,16 +2159,21 @@ void QuotaManagerImpl::DeleteBucketFromDatabase(
PostTaskAndReplyWithResultForDBThread(
base::BindOnce(
- [](const BucketLocator& bucket, QuotaDatabase* database) {
+ [](const BucketLocator& bucket, bool commit_immediately,
+ QuotaDatabase* database) {
DCHECK(database);
- return database->DeleteBucketData(bucket);
+ auto result = database->DeleteBucketData(bucket);
+ if (commit_immediately && result == QuotaError::kNone)
+ database->CommitNow();
+
+ return result;
},
- bucket),
+ bucket, commit_immediately),
std::move(callback));
}
void QuotaManagerImpl::DidBucketDataEvicted(
- QuotaDatabase::BucketTableEntry entry,
+ mojom::BucketTableEntryPtr entry,
blink::mojom::QuotaStatusCode status) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(io_thread_->BelongsToCurrentThread());
@@ -2219,10 +2189,10 @@ void QuotaManagerImpl::DidBucketDataEvicted(
base::Time now = QuotaDatabase::GetNow();
base::UmaHistogramCounts1M(
QuotaManagerImpl::kEvictedBucketAccessedCountHistogram,
- entry.use_count);
+ entry->use_count);
base::UmaHistogramCounts1000(
QuotaManagerImpl::kEvictedBucketDaysSinceAccessHistogram,
- (now - entry.last_accessed).InDays());
+ (now - entry->last_accessed).InDays());
}
std::move(eviction_context_.evict_bucket_data_callback).Run(status);
@@ -2241,7 +2211,7 @@ void QuotaManagerImpl::DeleteBucketDataInternal(
return;
}
auto bucket_deleter = std::make_unique<BucketDataDeleter>(
- this, bucket, std::move(quota_client_types),
+ this, bucket, std::move(quota_client_types), /*commit_immediately=*/true,
base::BindOnce(&QuotaManagerImpl::DidDeleteBucketData,
weak_factory_.GetWeakPtr(), std::move(callback)));
auto* bucket_deleter_ptr = bucket_deleter.get();
@@ -2473,32 +2443,33 @@ void QuotaManagerImpl::DidGetPersistentGlobalUsageForHistogram(
}
void QuotaManagerImpl::DidDumpBucketTableForHistogram(
- const BucketTableEntries& entries) {
+ BucketTableEntries entries) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
std::map<StorageKey, int64_t> usage_map =
GetUsageTracker(StorageType::kTemporary)->GetCachedStorageKeysUsage();
base::Time now = QuotaDatabase::GetNow();
for (const auto& info : entries) {
- if (info.type != StorageType::kTemporary)
+ if (info->type != storage::mojom::StorageType::kTemporary)
continue;
+ absl::optional<StorageKey> storage_key =
+ StorageKey::Deserialize(info->storage_key);
+
// Ignore stale database entries. If there is no map entry, the storage
// key's data has been deleted.
- auto it = usage_map.find(info.storage_key);
+ auto it = usage_map.find(*storage_key);
if (it == usage_map.end() || it->second == 0)
continue;
base::TimeDelta age =
- now - std::max(info.last_accessed, info.last_modified);
+ 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_t{1024}, int64_t{1});
- base::Histogram::FactoryGet(
- "Quota.AgeOfDataInDays", 1, 1000, 50,
- base::HistogramBase::kUmaTargetedHistogramFlag)->
- AddCount(age.InDays(),
- base::saturated_cast<int>(kilobytes));
+ base::Histogram::FactoryGet("Quota.AgeOfDataInDays", 1, 1000, 50,
+ base::HistogramBase::kUmaTargetedHistogramFlag)
+ ->AddCount(age.InDays(), base::saturated_cast<int>(kilobytes));
}
}
@@ -2580,7 +2551,7 @@ void QuotaManagerImpl::EvictBucketData(const BucketLocator& bucket,
void QuotaManagerImpl::DidGetBucketInfoForEviction(
const BucketLocator& bucket,
- QuotaErrorOr<QuotaDatabase::BucketTableEntry> result) {
+ QuotaErrorOr<mojom::BucketTableEntryPtr> result) {
DidDatabaseWork(result.ok() || result.error() != QuotaError::kDatabaseError);
if (!result.ok()) {
@@ -2592,7 +2563,7 @@ void QuotaManagerImpl::DidGetBucketInfoForEviction(
DeleteBucketDataInternal(
bucket, AllQuotaClientTypes(),
base::BindOnce(&QuotaManagerImpl::DidBucketDataEvicted,
- weak_factory_.GetWeakPtr(), result.value()));
+ weak_factory_.GetWeakPtr(), std::move(result.value())));
}
void QuotaManagerImpl::GetEvictionRoundInfo(
@@ -2947,8 +2918,8 @@ void QuotaManagerImpl::DidGetStorageKeys(
}
void QuotaManagerImpl::DidGetBuckets(
- base::OnceCallback<void(QuotaErrorOr<std::set<BucketLocator>>)> callback,
- QuotaErrorOr<std::set<BucketLocator>> result) {
+ base::OnceCallback<void(QuotaErrorOr<std::set<BucketInfo>>)> callback,
+ QuotaErrorOr<std::set<BucketInfo>> result) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(callback);
@@ -2956,6 +2927,48 @@ void QuotaManagerImpl::DidGetBuckets(
std::move(callback).Run(std::move(result));
}
+void QuotaManagerImpl::DidGetBucketsCheckExpiration(
+ base::OnceCallback<void(QuotaErrorOr<std::set<BucketInfo>>)> callback,
+ QuotaErrorOr<std::set<BucketInfo>> result) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(callback);
+
+ DidDatabaseWork(result.ok() || result.error() != QuotaError::kDatabaseError);
+
+ if (!result.ok()) {
+ std::move(callback).Run(std::move(result));
+ return;
+ }
+
+ std::set<BucketInfo> kept_buckets;
+ std::set<BucketInfo> buckets_to_delete;
+ for (const BucketInfo& bucket : result.value()) {
+ if (!bucket.expiration.is_null() &&
+ bucket.expiration <= QuotaDatabase::GetNow()) {
+ buckets_to_delete.insert(bucket);
+ } else {
+ kept_buckets.insert(bucket);
+ }
+ }
+
+ if (buckets_to_delete.empty()) {
+ std::move(callback).Run(kept_buckets);
+ return;
+ }
+
+ base::RepeatingClosure barrier =
+ base::BarrierClosure(buckets_to_delete.size(),
+ base::BindOnce(std::move(callback), kept_buckets));
+ for (const BucketInfo& bucket : buckets_to_delete) {
+ StatusCallback on_delete_done =
+ base::BindOnce([](base::RepeatingClosure barrier,
+ blink::mojom::QuotaStatusCode) { barrier.Run(); },
+ barrier);
+ DeleteBucketDataInternal(bucket.ToBucketLocator(), AllQuotaClientTypes(),
+ std::move(on_delete_done));
+ }
+}
+
void QuotaManagerImpl::DidGetModifiedBetween(
GetBucketsCallback callback,
StorageType type,
@@ -3047,7 +3060,8 @@ std::tuple<int64_t, int64_t> QuotaManagerImpl::CallGetVolumeInfo(
UMA_HISTOGRAM_MBYTES("Quota.TotalDiskSpace", total);
UMA_HISTOGRAM_MBYTES("Quota.AvailableDiskSpace", available);
if (total > 0) {
- UMA_HISTOGRAM_PERCENTAGE("Quota.PercentDiskAvailable",
+ UMA_HISTOGRAM_PERCENTAGE(
+ "Quota.PercentDiskAvailable",
std::min(100, static_cast<int>((available * 100) / total)));
}
return std::make_tuple(total, available);
diff --git a/chromium/storage/browser/quota/quota_manager_impl.h b/chromium/storage/browser/quota/quota_manager_impl.h
index 9ccba1d1577..e15fff7270f 100644
--- a/chromium/storage/browser/quota/quota_manager_impl.h
+++ b/chromium/storage/browser/quota/quota_manager_impl.h
@@ -235,21 +235,23 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl
// Used for retrieving global usage data in the UsageTracker.
void GetBucketsForType(
blink::mojom::StorageType type,
- base::OnceCallback<void(QuotaErrorOr<std::set<BucketLocator>>)> callback);
+ base::OnceCallback<void(QuotaErrorOr<std::set<BucketInfo>>)> 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);
+ base::OnceCallback<void(QuotaErrorOr<std::set<BucketInfo>>)> 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(
+ // table. When `delete_expired` is true, the expired buckets will be filtered
+ // out of the reply and also deleted from disk.
+ virtual void GetBucketsForStorageKey(
const blink::StorageKey& storage_key,
blink::mojom::StorageType type,
- base::OnceCallback<void(QuotaErrorOr<std::set<BucketLocator>>)> callback);
+ base::OnceCallback<void(QuotaErrorOr<std::set<BucketInfo>>)> callback,
+ bool delete_expired = false);
// Called by clients or webapps. Returns usage per host.
void GetUsageInfo(GetUsageInfoCallback callback);
@@ -385,10 +387,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl
GetDiskAvailabilityAndTempPoolSizeCallback callback) override;
void GetStatistics(GetStatisticsCallback callback) override;
void RetrieveBucketsTable(RetrieveBucketsTableCallback callback) override;
- void GetHostUsageForInternals(
- const std::string& host,
- storage::mojom::StorageType storage_type,
- GetHostUsageForInternalsCallback callback) override;
void GetGlobalUsageForInternals(
storage::mojom::StorageType storage_type,
GetGlobalUsageForInternalsCallback callback) override;
@@ -533,15 +531,13 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl
std::set<int> active_override_session_ids;
};
- using BucketTableEntry = QuotaDatabase::BucketTableEntry;
- using BucketTableEntries = std::vector<BucketTableEntry>;
+ using BucketTableEntries = std::vector<mojom::BucketTableEntryPtr>;
using StorageKeysByType =
base::flat_map<blink::mojom::StorageType, std::set<blink::StorageKey>>;
using QuotaSettingsCallback = base::OnceCallback<void(const QuotaSettings&)>;
- using DumpBucketTableCallback =
- base::OnceCallback<void(const BucketTableEntries&)>;
+ using DumpBucketTableCallback = base::OnceCallback<void(BucketTableEntries)>;
// The values returned total_space, available_space.
using StorageCapacityCallback = base::OnceCallback<void(int64_t, int64_t)>;
@@ -582,10 +578,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl
UsageTracker* GetUsageTracker(blink::mojom::StorageType type) const;
void DumpBucketTable(DumpBucketTableCallback callback);
- void OnGetHostUsageForInternals(
- GetHostUsageForInternalsCallback callback,
- int64_t usage,
- blink::mojom::UsageBreakdownPtr usage_breakdown);
void UpdateQuotaInternalsDiskAvailability(base::OnceClosure barrier_callback,
AccumulateQuotaInternalsInfo* info,
int64_t total_space,
@@ -597,13 +589,12 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl
GetDiskAvailabilityAndTempPoolSizeCallback callback,
std::unique_ptr<AccumulateQuotaInternalsInfo> info);
void RetrieveBucketUsageForBucketTable(RetrieveBucketsTableCallback callback,
- const BucketTableEntries& entries);
+ BucketTableEntries entries);
void AddBucketTableEntry(
- const BucketTableEntry& entry,
- base::OnceClosure barrier_callback,
- std::vector<storage::mojom::BucketTableEntryPtr>* buckets,
+ mojom::BucketTableEntryPtr entry,
+ base::OnceCallback<void(mojom::BucketTableEntryPtr)> barrier_callback,
int64_t usage,
- blink::mojom::UsageBreakdownPtr bucketUsageBreakdown);
+ blink::mojom::UsageBreakdownPtr bucket_usage_breakdown);
// Runs BucketDataDeleter which calls QuotaClients to clear data for the
// bucket. Once the task is complete, calls the QuotaDatabase to delete the
@@ -642,9 +633,10 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl
// Methods for eviction logic.
void StartEviction();
void DeleteBucketFromDatabase(const BucketLocator& bucket,
+ bool commit_immediately,
base::OnceCallback<void(QuotaError)> callback);
- void DidBucketDataEvicted(QuotaDatabase::BucketTableEntry entry,
+ void DidBucketDataEvicted(mojom::BucketTableEntryPtr entry,
blink::mojom::QuotaStatusCode status);
void ReportHistogram();
@@ -655,7 +647,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl
int64_t available_space);
void DidGetPersistentGlobalUsageForHistogram(int64_t usage,
int64_t unlimited_usage);
- void DidDumpBucketTableForHistogram(const BucketTableEntries& entries);
+ void DidDumpBucketTableForHistogram(BucketTableEntries entries);
// Returns the list of bucket ids that should be excluded from eviction due to
// consistent errors after multiple attempts.
@@ -672,7 +664,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl
void DidGetBucketInfoForEviction(
const BucketLocator& bucket,
- QuotaErrorOr<QuotaDatabase::BucketTableEntry> result);
+ QuotaErrorOr<mojom::BucketTableEntryPtr> result);
void DidGetEvictionRoundInfo();
@@ -713,8 +705,11 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl
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);
+ base::OnceCallback<void(QuotaErrorOr<std::set<BucketInfo>>)> callback,
+ QuotaErrorOr<std::set<BucketInfo>> result);
+ void DidGetBucketsCheckExpiration(
+ base::OnceCallback<void(QuotaErrorOr<std::set<BucketInfo>>)> callback,
+ QuotaErrorOr<std::set<BucketInfo>> result);
void DidGetModifiedBetween(GetBucketsCallback callback,
blink::mojom::StorageType type,
QuotaErrorOr<std::set<BucketLocator>> result);
diff --git a/chromium/storage/browser/quota/quota_manager_proxy.cc b/chromium/storage/browser/quota/quota_manager_proxy.cc
index 90a46f95420..393d4d1e5ce 100644
--- a/chromium/storage/browser/quota/quota_manager_proxy.cc
+++ b/chromium/storage/browser/quota/quota_manager_proxy.cc
@@ -252,6 +252,37 @@ void QuotaManagerProxy::GetBucket(
std::move(respond));
}
+void QuotaManagerProxy::GetBucketsForStorageKey(
+ const blink::StorageKey& storage_key,
+ blink::mojom::StorageType type,
+ bool delete_expired,
+ scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
+ base::OnceCallback<void(QuotaErrorOr<std::set<BucketInfo>>)> callback) {
+ DCHECK(callback_task_runner);
+ DCHECK(callback);
+
+ if (!quota_manager_impl_task_runner_->RunsTasksInCurrentSequence()) {
+ quota_manager_impl_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&QuotaManagerProxy::GetBucketsForStorageKey, this,
+ storage_key, type, delete_expired,
+ std::move(callback_task_runner), std::move(callback)));
+ return;
+ }
+
+ DCHECK_CALLED_ON_VALID_SEQUENCE(quota_manager_impl_sequence_checker_);
+
+ auto respond =
+ base::BindPostTask(std::move(callback_task_runner), std::move(callback));
+ if (!quota_manager_impl_) {
+ std::move(respond).Run(QuotaError::kUnknownError);
+ return;
+ }
+
+ quota_manager_impl_->GetBucketsForStorageKey(
+ storage_key, type, std::move(respond), delete_expired);
+}
+
void QuotaManagerProxy::GetBucketById(
const BucketId& bucket_id,
scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
diff --git a/chromium/storage/browser/quota/quota_manager_proxy.h b/chromium/storage/browser/quota/quota_manager_proxy.h
index c5ab07ca576..efb9691dd5c 100644
--- a/chromium/storage/browser/quota/quota_manager_proxy.h
+++ b/chromium/storage/browser/quota/quota_manager_proxy.h
@@ -101,7 +101,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerProxy
// quota_manager_impl_task_runner. Additionally, the asychonrous version of
// this method `GetOrCreateBucket` is preferred; only use this synchronous
// version where asynchronous bucket retrieval is not possible.
- QuotaErrorOr<BucketInfo> GetOrCreateBucketSync(
+ virtual QuotaErrorOr<BucketInfo> GetOrCreateBucketSync(
const BucketInitParams& params);
// Same as GetOrCreateBucket but takes in StorageType. This should only be
@@ -145,6 +145,16 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerProxy
scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
base::OnceCallback<void(QuotaErrorOr<BucketInfo>)> callback);
+ // Retrieves all buckets for `storage_key` and `type` that are in the buckets
+ // table. If `delete_expired` is true, expired buckets will be filtered out of
+ // the reply and also deleted from disk.
+ virtual void GetBucketsForStorageKey(
+ const blink::StorageKey& storage_key,
+ blink::mojom::StorageType type,
+ bool delete_expired,
+ scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
+ base::OnceCallback<void(QuotaErrorOr<std::set<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
@@ -183,8 +193,8 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerProxy
// updated. If a `callback` is provided then `callback_task_runner` must
// also be provided. If the quota manager runs on `callback_task_runner`,
// then the `callback` may be invoked synchronously.
- // TODO(crbug.com/1208141): Remove when all usages have updated to use
- // NotifyBucketModified.
+ // TODO(https://crbug.com/1202167): Remove when all usages have updated to use
+ // `NotifyBucketModified()`.
virtual void NotifyStorageModified(
QuotaClientType client_id,
const blink::StorageKey& storage_key,
diff --git a/chromium/storage/browser/quota/quota_manager_proxy_unittest.cc b/chromium/storage/browser/quota/quota_manager_proxy_unittest.cc
index 92394a05604..402365ecfc9 100644
--- a/chromium/storage/browser/quota/quota_manager_proxy_unittest.cc
+++ b/chromium/storage/browser/quota/quota_manager_proxy_unittest.cc
@@ -91,11 +91,14 @@ TEST_F(QuotaManagerProxyTest, GetClientBucketPath) {
bucket->ToBucketLocator(), QuotaClientType::kIndexedDatabase),
expected_path);
- // BackgroundFetch/CacheStorage
- expected_path = bucket_path.AppendASCII("CacheStorage");
+ // BackgroundFetch
+ expected_path = bucket_path.AppendASCII("BackgroundFetch");
EXPECT_EQ(quota_manager_proxy_->GetClientBucketPath(
bucket->ToBucketLocator(), QuotaClientType::kBackgroundFetch),
expected_path);
+
+ // CacheStorage
+ expected_path = bucket_path.AppendASCII("CacheStorage");
EXPECT_EQ(
quota_manager_proxy_->GetClientBucketPath(
bucket->ToBucketLocator(), QuotaClientType::kServiceWorkerCache),
diff --git a/chromium/storage/browser/quota/quota_manager_unittest.cc b/chromium/storage/browser/quota/quota_manager_unittest.cc
index 97d986d3a2d..5464dd6fe96 100644
--- a/chromium/storage/browser/quota/quota_manager_unittest.cc
+++ b/chromium/storage/browser/quota/quota_manager_unittest.cc
@@ -67,6 +67,11 @@ const StorageType kTemp = StorageType::kTemporary;
const StorageType kPerm = StorageType::kPersistent;
const StorageType kSync = StorageType::kSyncable;
+const storage::mojom::StorageType kStorageTemp =
+ storage::mojom::StorageType::kTemporary;
+const storage::mojom::StorageType kStoragePerm =
+ storage::mojom::StorageType::kPersistent;
+
// Values in bytes.
const int64_t kAvailableSpaceForApp = 13377331U;
const int64_t kMustRemainAvailableForSystem = kAvailableSpaceForApp / 2;
@@ -132,10 +137,11 @@ const storage::mojom::BucketTableEntry* FindBucketTableEntry(
}
MATCHER_P3(MatchesBucketTableEntry, storage_key, type, use_count, "") {
- return testing::ExplainMatchResult(storage_key, arg.storage_key,
+ return testing::ExplainMatchResult(storage_key, arg->storage_key,
result_listener) &&
- testing::ExplainMatchResult(type, arg.type, result_listener) &&
- testing::ExplainMatchResult(use_count, arg.use_count, result_listener);
+ testing::ExplainMatchResult(type, arg->type, result_listener) &&
+ testing::ExplainMatchResult(use_count, arg->use_count,
+ result_listener);
}
} // namespace
@@ -257,28 +263,29 @@ class QuotaManagerImplTest : public testing::Test {
return future.Take();
}
- QuotaErrorOr<std::set<BucketLocator>> GetBucketsForType(
+ QuotaErrorOr<std::set<BucketInfo>> GetBucketsForType(
blink::mojom::StorageType storage_type) {
- base::test::TestFuture<QuotaErrorOr<std::set<BucketLocator>>> future;
+ base::test::TestFuture<QuotaErrorOr<std::set<BucketInfo>>> future;
quota_manager_impl_->GetBucketsForType(storage_type, future.GetCallback());
return future.Take();
}
- QuotaErrorOr<std::set<BucketLocator>> GetBucketsForHost(
+ QuotaErrorOr<std::set<BucketInfo>> GetBucketsForHost(
const std::string& host,
blink::mojom::StorageType storage_type) {
- base::test::TestFuture<QuotaErrorOr<std::set<BucketLocator>>> future;
+ base::test::TestFuture<QuotaErrorOr<std::set<BucketInfo>>> future;
quota_manager_impl_->GetBucketsForHost(host, storage_type,
future.GetCallback());
return future.Take();
}
- QuotaErrorOr<std::set<BucketLocator>> GetBucketsForStorageKey(
+ QuotaErrorOr<std::set<BucketInfo>> GetBucketsForStorageKey(
const StorageKey& storage_key,
- blink::mojom::StorageType storage_type) {
- base::test::TestFuture<QuotaErrorOr<std::set<BucketLocator>>> future;
- quota_manager_impl_->GetBucketsForStorageKey(storage_key, storage_type,
- future.GetCallback());
+ blink::mojom::StorageType storage_type,
+ bool delete_expired = false) {
+ base::test::TestFuture<QuotaErrorOr<std::set<BucketInfo>>> future;
+ quota_manager_impl_->GetBucketsForStorageKey(
+ storage_key, storage_type, future.GetCallback(), delete_expired);
return future.Take();
}
@@ -455,9 +462,8 @@ class QuotaManagerImplTest : public testing::Test {
BucketTableEntries DumpBucketTable() {
base::test::TestFuture<BucketTableEntries> future;
- quota_manager_impl_->DumpBucketTable(
- future.GetCallback<const BucketTableEntries&>());
- return future.Get();
+ quota_manager_impl_->DumpBucketTable(future.GetCallback());
+ return future.Take();
}
std::vector<storage::mojom::BucketTableEntryPtr> RetrieveBucketsTable() {
@@ -961,18 +967,18 @@ TEST_F(QuotaManagerImplTest, GetBucketsForType) {
EXPECT_TRUE(bucket.ok());
BucketInfo bucket_c = bucket.value();
- QuotaErrorOr<std::set<BucketLocator>> result = GetBucketsForType(kTemp);
+ QuotaErrorOr<std::set<BucketInfo>> result = GetBucketsForType(kTemp);
EXPECT_TRUE(result.ok());
- std::set<BucketLocator> buckets = result.value();
+ std::set<BucketInfo> buckets = result.value();
EXPECT_EQ(2U, buckets.size());
- EXPECT_THAT(buckets, testing::Contains(bucket_a.ToBucketLocator()));
- EXPECT_THAT(buckets, testing::Contains(bucket_b.ToBucketLocator()));
+ EXPECT_THAT(buckets, testing::Contains(bucket_a));
+ EXPECT_THAT(buckets, testing::Contains(bucket_b));
result = GetBucketsForType(kPerm);
buckets = result.value();
EXPECT_EQ(1U, buckets.size());
- EXPECT_THAT(buckets, testing::Contains(bucket_c.ToBucketLocator()));
+ EXPECT_THAT(buckets, testing::Contains(bucket_c));
}
TEST_F(QuotaManagerImplTest, GetBucketsForHost) {
@@ -994,19 +1000,18 @@ TEST_F(QuotaManagerImplTest, GetBucketsForHost) {
EXPECT_TRUE(bucket.ok());
BucketInfo host_b_bucket = bucket.value();
- QuotaErrorOr<std::set<BucketLocator>> result =
- GetBucketsForHost("a.com", kTemp);
+ QuotaErrorOr<std::set<BucketInfo>> result = GetBucketsForHost("a.com", kTemp);
EXPECT_TRUE(result.ok());
- std::set<BucketLocator> buckets = result.value();
+ std::set<BucketInfo> buckets = result.value();
EXPECT_EQ(2U, buckets.size());
- EXPECT_THAT(buckets, testing::Contains(host_a_bucket_1.ToBucketLocator()));
- EXPECT_THAT(buckets, testing::Contains(host_a_bucket_2.ToBucketLocator()));
+ EXPECT_THAT(buckets, testing::Contains(host_a_bucket_1));
+ EXPECT_THAT(buckets, testing::Contains(host_a_bucket_2));
result = GetBucketsForHost("b.com", kPerm);
buckets = result.value();
EXPECT_EQ(1U, buckets.size());
- EXPECT_THAT(buckets, testing::Contains(host_b_bucket.ToBucketLocator()));
+ EXPECT_THAT(buckets, testing::Contains(host_b_bucket));
}
TEST_F(QuotaManagerImplTest, GetBucketsForStorageKey) {
@@ -1030,14 +1035,14 @@ TEST_F(QuotaManagerImplTest, GetBucketsForStorageKey) {
EXPECT_TRUE(bucket.ok());
BucketInfo bucket_c = bucket.value();
- QuotaErrorOr<std::set<BucketLocator>> result =
+ QuotaErrorOr<std::set<BucketInfo>> result =
GetBucketsForStorageKey(storage_key_a, kTemp);
EXPECT_TRUE(result.ok());
- std::set<BucketLocator> buckets = result.value();
+ std::set<BucketInfo> buckets = result.value();
EXPECT_EQ(2U, buckets.size());
- EXPECT_THAT(buckets, testing::Contains(bucket_a1.ToBucketLocator()));
- EXPECT_THAT(buckets, testing::Contains(bucket_a2.ToBucketLocator()));
+ EXPECT_THAT(buckets, testing::Contains(bucket_a1));
+ EXPECT_THAT(buckets, testing::Contains(bucket_a2));
result = GetBucketsForStorageKey(storage_key_a, kPerm);
EXPECT_TRUE(result.ok());
@@ -1048,7 +1053,43 @@ TEST_F(QuotaManagerImplTest, GetBucketsForStorageKey) {
buckets = result.value();
EXPECT_EQ(1U, buckets.size());
- EXPECT_THAT(buckets, testing::Contains(bucket_c.ToBucketLocator()));
+ EXPECT_THAT(buckets, testing::Contains(bucket_c));
+}
+
+TEST_F(QuotaManagerImplTest, GetBucketsForStorageKey_Expiration) {
+ StorageKey storage_key = ToStorageKey("http://a.com/");
+
+ auto clock = std::make_unique<base::SimpleTestClock>();
+ QuotaDatabase::SetClockForTesting(clock.get());
+ clock->SetNow(base::Time::Now());
+
+ BucketInitParams params(storage_key, "bucket_1");
+ auto bucket = UpdateOrCreateBucket(params);
+ EXPECT_TRUE(bucket.ok());
+ BucketInfo bucket_1 = bucket.value();
+
+ params.name = "bucket_2";
+ params.expiration = clock->Now() + base::Days(1);
+ bucket = UpdateOrCreateBucket(params);
+ EXPECT_TRUE(bucket.ok());
+ BucketInfo bucket_2 = bucket.value();
+
+ params.name = "bucket_3";
+ bucket = UpdateOrCreateBucket(params);
+ EXPECT_TRUE(bucket.ok());
+ BucketInfo bucket_3 = bucket.value();
+
+ clock->Advance(base::Days(2));
+
+ QuotaErrorOr<std::set<BucketInfo>> result =
+ GetBucketsForStorageKey(storage_key, kTemp, /*delete_expired=*/true);
+ EXPECT_TRUE(result.ok());
+
+ std::set<BucketInfo> buckets = result.value();
+ ASSERT_EQ(1U, buckets.size());
+ EXPECT_EQ(*buckets.begin(), bucket_1);
+
+ QuotaDatabase::SetClockForTesting(nullptr);
}
TEST_F(QuotaManagerImplTest, GetUsageAndQuota_Simple) {
@@ -2433,17 +2474,21 @@ TEST_F(QuotaManagerImplTest, DeleteHostDataMultiple) {
const BucketTableEntries& entries = DumpBucketTable();
for (const auto& entry : entries) {
- if (entry.type != kTemp)
+ if (entry->type != kStorageTemp)
continue;
+ absl::optional<StorageKey> storage_key =
+ StorageKey::Deserialize(entry->storage_key);
+ ASSERT_TRUE(storage_key.has_value());
+
EXPECT_NE(std::string("http://foo.com/"),
- entry.storage_key.origin().GetURL().spec());
+ storage_key.value().origin().GetURL().spec());
EXPECT_NE(std::string("http://foo.com:1/"),
- entry.storage_key.origin().GetURL().spec());
+ storage_key.value().origin().GetURL().spec());
EXPECT_NE(std::string("https://foo.com/"),
- entry.storage_key.origin().GetURL().spec());
+ storage_key.value().origin().GetURL().spec());
EXPECT_NE(std::string("http://bar.com/"),
- entry.storage_key.origin().GetURL().spec());
+ std::move(storage_key).value().origin().GetURL().spec());
}
global_usage_result = GetGlobalUsage(kTemp);
@@ -2525,17 +2570,21 @@ TEST_F(QuotaManagerImplTest, DeleteHostDataMultipleClientsDifferentTypes) {
const BucketTableEntries& entries = DumpBucketTable();
for (const auto& entry : entries) {
- if (entry.type != kPerm)
+ if (entry->type != kStoragePerm)
continue;
+ absl::optional<StorageKey> storage_key =
+ StorageKey::Deserialize(entry->storage_key);
+ ASSERT_TRUE(storage_key.has_value());
+
EXPECT_NE(std::string("http://foo.com/"),
- entry.storage_key.origin().GetURL().spec());
+ storage_key.value().origin().GetURL().spec());
EXPECT_NE(std::string("http://foo.com:1/"),
- entry.storage_key.origin().GetURL().spec());
+ storage_key.value().origin().GetURL().spec());
EXPECT_NE(std::string("https://foo.com/"),
- entry.storage_key.origin().GetURL().spec());
+ storage_key.value().origin().GetURL().spec());
EXPECT_NE(std::string("http://bar.com/"),
- entry.storage_key.origin().GetURL().spec());
+ std::move(storage_key).value().origin().GetURL().spec());
}
global_usage_result = GetGlobalUsage(kTemp);
@@ -2891,32 +2940,6 @@ TEST_F(QuotaManagerImplTest, FindAndDeleteBucketDataWithDBError) {
.usage);
}
-TEST_F(QuotaManagerImplTest, GetHostUsageForInternals) {
- static const ClientBucketData kData[] = {
- {"http://example.com/", kDefaultBucketName, kTemp, 400},
- {"http://example.com/", kDefaultBucketName, kPerm, 2},
- };
- MockQuotaClient* client =
- CreateAndRegisterClient(QuotaClientType::kFileSystem, {kTemp, kPerm});
- RegisterClientBucketData(client, kData);
-
- base::test::TestFuture<int64_t> temp_future;
- quota_manager_impl()->GetHostUsageForInternals(
- "example.com", storage::mojom::StorageType::kTemporary,
- temp_future.GetCallback());
- int64_t temp_result = temp_future.Take();
-
- EXPECT_EQ(400, temp_result);
-
- base::test::TestFuture<int64_t> perm_future;
- quota_manager_impl()->GetHostUsageForInternals(
- "example.com", storage::mojom::StorageType::kPersistent,
- perm_future.GetCallback());
- int64_t perm_result = perm_future.Take();
-
- EXPECT_EQ(2, perm_result);
-}
-
TEST_F(QuotaManagerImplTest, GetDiskAvailabilityAndTempPoolSize) {
const int kPoolSize = 1000;
const int kPerHostQuota = kPoolSize / 5;
@@ -3101,9 +3124,11 @@ TEST_F(QuotaManagerImplTest, DumpBucketTable) {
task_environment_.RunUntilIdle();
const BucketTableEntries& entries = DumpBucketTable();
- EXPECT_THAT(entries, testing::UnorderedElementsAre(
- MatchesBucketTableEntry(kStorageKey, kTemp, 1),
- MatchesBucketTableEntry(kStorageKey, kPerm, 2)));
+ EXPECT_THAT(
+ entries,
+ testing::UnorderedElementsAre(
+ MatchesBucketTableEntry(kStorageKey.Serialize(), kStorageTemp, 1),
+ MatchesBucketTableEntry(kStorageKey.Serialize(), kStoragePerm, 2)));
}
TEST_F(QuotaManagerImplTest, RetrieveBucketsTable) {
@@ -3122,18 +3147,7 @@ TEST_F(QuotaManagerImplTest, RetrieveBucketsTable) {
quota_manager_impl()->NotifyStorageAccessed(kStorageKey, kTemp, kAccessTime);
quota_manager_impl()->NotifyStorageAccessed(kStorageKey, kPerm, kAccessTime);
-
- base::RunLoop run_loop;
- base::Time time1 = client->IncrementMockTime();
- client->ModifyStorageKeyAndNotify(ToStorageKey("http://example.com/"), kTemp,
- 10);
- client->ModifyStorageKeyAndNotify(ToStorageKey("http://example.com/"), kPerm,
- 10);
- base::Time time2 = client->IncrementMockTime();
- client->ModifyStorageKeyAndNotify(ToStorageKey("http://example.com/"), kTemp,
- 10, run_loop.QuitClosure());
- base::Time time3 = client->IncrementMockTime();
- run_loop.Run();
+ const base::Time time1 = base::Time::Now();
auto temp_bucket = GetBucket(kStorageKey, kDefaultBucketName, kTemp);
auto perm_bucket = GetBucket(kStorageKey, kDefaultBucketName, kPerm);
@@ -3145,27 +3159,25 @@ TEST_F(QuotaManagerImplTest, RetrieveBucketsTable) {
FindBucketTableEntry(bucket_table_entries, temp_bucket->id);
EXPECT_TRUE(temp_entry);
EXPECT_EQ(temp_entry->storage_key, kSerializedStorageKey);
- EXPECT_EQ(temp_entry->host, "example.com");
- EXPECT_EQ(temp_entry->type, "temporary");
+ EXPECT_EQ(temp_entry->type, kStorageTemp);
EXPECT_EQ(temp_entry->name, kDefaultBucketName);
EXPECT_EQ(temp_entry->use_count, 1);
EXPECT_EQ(temp_entry->last_accessed, kAccessTime);
- EXPECT_GE(temp_entry->last_modified, time2);
- EXPECT_LE(temp_entry->last_modified, time3);
- EXPECT_EQ(temp_entry->usage, 143);
+ EXPECT_GE(temp_entry->last_modified, kAccessTime);
+ EXPECT_LE(temp_entry->last_modified, time1);
+ EXPECT_EQ(temp_entry->usage, 123);
auto* perm_entry =
FindBucketTableEntry(bucket_table_entries, perm_bucket->id);
EXPECT_TRUE(perm_entry);
EXPECT_EQ(perm_entry->storage_key, kSerializedStorageKey);
- EXPECT_EQ(perm_entry->host, "example.com");
- EXPECT_EQ(perm_entry->type, "persistent");
+ EXPECT_EQ(perm_entry->type, kStoragePerm);
EXPECT_EQ(perm_entry->name, kDefaultBucketName);
EXPECT_EQ(perm_entry->use_count, 1);
EXPECT_EQ(perm_entry->last_accessed, kAccessTime);
- EXPECT_GE(perm_entry->last_modified, time1);
- EXPECT_LE(perm_entry->last_modified, time2);
- EXPECT_EQ(perm_entry->usage, 466);
+ EXPECT_GE(temp_entry->last_modified, kAccessTime);
+ EXPECT_LE(temp_entry->last_modified, time1);
+ EXPECT_EQ(perm_entry->usage, 456);
}
TEST_F(QuotaManagerImplTest, QuotaForEmptyHost) {
diff --git a/chromium/storage/browser/quota/quota_settings.cc b/chromium/storage/browser/quota/quota_settings.cc
index c2a5a209635..718e6cf09e4 100644
--- a/chromium/storage/browser/quota/quota_settings.cc
+++ b/chromium/storage/browser/quota/quota_settings.cc
@@ -37,7 +37,7 @@ int64_t RandomizeByPercent(int64_t value, int percent) {
}
QuotaSettings CalculateIncognitoDynamicSettings(
- int64_t physical_memory_amount) {
+ uint64_t physical_memory_amount) {
// The incognito pool size is a fraction of the amount of system memory.
double incognito_pool_size_ratio =
kIncognitoQuotaRatioLowerBound +
diff --git a/chromium/storage/browser/quota/quota_settings_unittest.cc b/chromium/storage/browser/quota/quota_settings_unittest.cc
index ef2bf9a1c64..84e03cb5cd6 100644
--- a/chromium/storage/browser/quota/quota_settings_unittest.cc
+++ b/chromium/storage/browser/quota/quota_settings_unittest.cc
@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/callback.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/numerics/safe_conversions.h"
#include "base/run_loop.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
@@ -22,8 +23,8 @@ using ::testing::_;
namespace {
-constexpr int64_t kLowPhysicalMemory = 1024 * 1024;
-constexpr int64_t kHighPhysicalMemory = 65536 * kLowPhysicalMemory;
+constexpr uint64_t kLowPhysicalMemory = 1024 * 1024;
+constexpr uint64_t kHighPhysicalMemory = 65536 * kLowPhysicalMemory;
} // namespace
@@ -33,7 +34,7 @@ class MockQuotaDeviceInfoHelper : public QuotaDeviceInfoHelper {
public:
MockQuotaDeviceInfoHelper() = default;
MOCK_CONST_METHOD1(AmountOfTotalDiskSpace, int64_t(const base::FilePath&));
- MOCK_CONST_METHOD0(AmountOfPhysicalMemory, int64_t());
+ MOCK_CONST_METHOD0(AmountOfPhysicalMemory, uint64_t());
};
class QuotaSettingsTest : public testing::Test {
@@ -71,23 +72,25 @@ class QuotaSettingsIncognitoTest : public QuotaSettingsTest {
protected:
void SetUpDeviceInfoHelper(const int expected_calls,
- const int64_t physical_memory_amount) {
+ const uint64_t physical_memory_amount) {
ON_CALL(device_info_helper_, AmountOfPhysicalMemory())
.WillByDefault(::testing::Return(physical_memory_amount));
EXPECT_CALL(device_info_helper_, AmountOfPhysicalMemory())
.Times(expected_calls);
}
- void GetAndTestSettings(const int64_t physical_memory_amount) {
+ void GetAndTestSettings(const uint64_t physical_memory_amount) {
absl::optional<QuotaSettings> settings =
GetSettings(true, &device_info_helper_);
ASSERT_TRUE(settings.has_value());
+ const uint64_t pool_size =
+ base::checked_cast<uint64_t>(settings->pool_size);
EXPECT_LE(
physical_memory_amount * GetIncognitoQuotaRatioLowerBound_ForTesting(),
- settings->pool_size);
+ pool_size);
EXPECT_GE(
physical_memory_amount * GetIncognitoQuotaRatioUpperBound_ForTesting(),
- settings->pool_size);
+ pool_size);
}
private:
diff --git a/chromium/storage/browser/quota/special_storage_policy.h b/chromium/storage/browser/quota/special_storage_policy.h
index f59e384cdbc..2d3015e4aed 100644
--- a/chromium/storage/browser/quota/special_storage_policy.h
+++ b/chromium/storage/browser/quota/special_storage_policy.h
@@ -9,7 +9,6 @@
#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
#include "base/sequence_checker.h"
-#include "services/network/public/cpp/session_cookie_delete_predicate.h"
class GURL;
@@ -80,16 +79,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SpecialStoragePolicy
// Returns true if some origins are only allowed session-only storage.
virtual bool HasSessionOnlyOrigins() = 0;
- // Returns a predicate that takes the domain of a cookie and a bool whether
- // the cookie is secure and returns true if the cookie should be deleted on
- // exit.
- // If |HasSessionOnlyOrigins()| is true a non-null callback is returned.
- // It uses domain matching as described in section 5.1.3 of RFC 6265 to
- // identify content setting rules that could have influenced the cookie
- // when it was created.
- virtual network::DeleteCookiePredicate
- CreateDeleteCookieOnExitPredicate() = 0;
-
// Adds/removes an observer, the policy does not take
// ownership of the observer. Should only be called on the IO thread.
void AddObserver(Observer* observer);
diff --git a/chromium/storage/browser/quota/storage_directory_util.cc b/chromium/storage/browser/quota/storage_directory_util.cc
index 3e3837d9c95..e818ca06d04 100644
--- a/chromium/storage/browser/quota/storage_directory_util.cc
+++ b/chromium/storage/browser/quota/storage_directory_util.cc
@@ -25,6 +25,7 @@ base::FilePath CreateClientBucketPath(const base::FilePath& profile_path,
case QuotaClientType::kIndexedDatabase:
return bucket_directory.Append(kIndexedDbDirectory);
case QuotaClientType::kBackgroundFetch:
+ return bucket_directory.Append(kBackgroundFetchDirectory);
case QuotaClientType::kServiceWorkerCache:
return bucket_directory.Append(kCacheStorageDirectory);
case QuotaClientType::kServiceWorker:
diff --git a/chromium/storage/browser/quota/usage_tracker.cc b/chromium/storage/browser/quota/usage_tracker.cc
index bacec98ed25..ddf43af85b1 100644
--- a/chromium/storage/browser/quota/usage_tracker.cc
+++ b/chromium/storage/browser/quota/usage_tracker.cc
@@ -58,22 +58,6 @@ void UsageTracker::GetGlobalUsage(UsageCallback callback) {
weak_factory_.GetWeakPtr()));
}
-void UsageTracker::GetHostUsageWithBreakdown(
- const std::string& host,
- UsageWithBreakdownCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- std::vector<UsageWithBreakdownCallback>& host_callbacks =
- host_usage_callbacks_[host];
- host_callbacks.emplace_back(std::move(callback));
- if (host_callbacks.size() > 1)
- return;
-
- quota_manager_impl_->GetBucketsForHost(
- host, type_,
- base::BindOnce(&UsageTracker::DidGetBucketsForHost,
- weak_factory_.GetWeakPtr(), host));
-}
-
void UsageTracker::GetStorageKeyUsageWithBreakdown(
const blink::StorageKey& storage_key,
UsageWithBreakdownCallback callback) {
@@ -193,7 +177,7 @@ void UsageTracker::SetUsageCacheEnabled(QuotaClientType client_type,
}
void UsageTracker::DidGetBucketsForType(
- QuotaErrorOr<std::set<BucketLocator>> result) {
+ QuotaErrorOr<std::set<BucketInfo>> result) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
auto info = std::make_unique<AccumulateInfo>();
if (!result.ok()) {
@@ -204,12 +188,15 @@ void UsageTracker::DidGetBucketsForType(
return;
}
- const std::set<BucketLocator>& buckets = result.value();
+ const std::set<BucketInfo>& buckets = result.value();
if (buckets.empty()) {
FinallySendGlobalUsage(std::move(info));
return;
}
+ std::set<BucketLocator> bucket_locators =
+ BucketInfosToBucketLocators(buckets);
+
auto* info_ptr = info.get();
base::RepeatingClosure barrier = base::BarrierClosure(
client_tracker_count_,
@@ -219,7 +206,7 @@ void UsageTracker::DidGetBucketsForType(
for (const auto& client_type_and_trackers : client_tracker_map_) {
for (const auto& client_tracker : client_type_and_trackers.second) {
client_tracker->GetBucketsUsage(
- buckets,
+ bucket_locators,
// base::Unretained usage is safe here because BarrierClosure holds
// the std::unque_ptr that keeps AccumulateInfo alive, and the
// BarrierClosure will outlive all the AccumulateClientGlobalUsage
@@ -231,50 +218,9 @@ void UsageTracker::DidGetBucketsForType(
}
}
-void UsageTracker::DidGetBucketsForHost(
- const std::string& host,
- QuotaErrorOr<std::set<BucketLocator>> result) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- auto info = std::make_unique<AccumulateInfo>();
- if (!result.ok()) {
- // Return with invalid values on error.
- info->usage = -1;
- info->unlimited_usage = -1;
- FinallySendHostUsageWithBreakdown(std::move(info), host);
- return;
- }
-
- const std::set<BucketLocator>& buckets = result.value();
- if (buckets.empty()) {
- FinallySendHostUsageWithBreakdown(std::move(info), host);
- return;
- }
-
- auto* info_ptr = info.get();
- base::RepeatingClosure barrier = base::BarrierClosure(
- client_tracker_count_,
- base::BindOnce(&UsageTracker::FinallySendHostUsageWithBreakdown,
- weak_factory_.GetWeakPtr(), std::move(info), host));
-
- for (const auto& client_type_and_trackers : client_tracker_map_) {
- for (const auto& client_tracker : client_type_and_trackers.second) {
- client_tracker->GetBucketsUsage(
- buckets,
- // base::Unretained usage is safe here because BarrierClosure holds
- // the std::unque_ptr that keeps AccumulateInfo alive, and the
- // BarrierClosure will outlive all the AccumulateClientGlobalUsage
- // closures.
- base::BindOnce(&UsageTracker::AccumulateClientUsageWithBreakdown,
- weak_factory_.GetWeakPtr(), barrier,
- base::Unretained(info_ptr),
- client_type_and_trackers.first));
- }
- }
-}
-
void UsageTracker::DidGetBucketsForStorageKey(
const blink::StorageKey& storage_key,
- QuotaErrorOr<std::set<BucketLocator>> result) {
+ QuotaErrorOr<std::set<BucketInfo>> result) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
auto info = std::make_unique<AccumulateInfo>();
if (!result.ok()) {
@@ -285,12 +231,15 @@ void UsageTracker::DidGetBucketsForStorageKey(
return;
}
- const std::set<BucketLocator>& buckets = result.value();
+ const std::set<BucketInfo>& buckets = result.value();
if (buckets.empty()) {
FinallySendStorageKeyUsageWithBreakdown(std::move(info), storage_key);
return;
}
+ std::set<BucketLocator> bucket_locators =
+ BucketInfosToBucketLocators(buckets);
+
auto* info_ptr = info.get();
base::RepeatingClosure barrier = base::BarrierClosure(
client_tracker_count_,
@@ -300,7 +249,7 @@ void UsageTracker::DidGetBucketsForStorageKey(
for (const auto& client_type_and_trackers : client_tracker_map_) {
for (const auto& client_tracker : client_type_and_trackers.second) {
client_tracker->GetBucketsUsage(
- buckets,
+ bucket_locators,
// base::Unretained usage is safe here because BarrierClosure holds
// the std::unque_ptr that keeps AccumulateInfo alive, and the
// BarrierClosure will outlive all the AccumulateClientGlobalUsage
@@ -388,24 +337,6 @@ void UsageTracker::FinallySendGlobalUsage(
std::move(callback).Run(info->usage, info->unlimited_usage);
}
-void UsageTracker::FinallySendHostUsageWithBreakdown(
- std::unique_ptr<AccumulateInfo> info,
- const std::string& host) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- auto it = host_usage_callbacks_.find(host);
- if (it == host_usage_callbacks_.end())
- return;
-
- std::vector<UsageWithBreakdownCallback> pending_callbacks;
- pending_callbacks.swap(it->second);
- DCHECK(pending_callbacks.size() > 0)
- << "host_usage_callbacks_ should only have non-empty callback lists";
- host_usage_callbacks_.erase(it);
-
- for (auto& callback : pending_callbacks)
- std::move(callback).Run(info->usage, info->usage_breakdown->Clone());
-}
-
void UsageTracker::FinallySendStorageKeyUsageWithBreakdown(
std::unique_ptr<AccumulateInfo> info,
const blink::StorageKey& storage_key) {
diff --git a/chromium/storage/browser/quota/usage_tracker.h b/chromium/storage/browser/quota/usage_tracker.h
index 10dc50e1306..5ddf0144af5 100644
--- a/chromium/storage/browser/quota/usage_tracker.h
+++ b/chromium/storage/browser/quota/usage_tracker.h
@@ -64,14 +64,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) UsageTracker
// a bucket.
void GetGlobalUsage(UsageCallback callback);
- // Retrieves all buckets for host from QuotaDatabase and requests bucket usage
- // from each registered client. Returns cached bucket usage if one exists for
- // a bucket.
- // TODO(crbug/1202325): Remove once all usages move to
- // GetStorageKeyUsageWithBreakdown.
- void GetHostUsageWithBreakdown(const std::string& host,
- UsageWithBreakdownCallback callback);
-
// Retrieves all buckets for a `storage_key` from QuotaDatabase and requests
// bucket usage from each registered client. Returns cached bucket usage if
// one exists for a bucket.
@@ -105,11 +97,13 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) UsageTracker
// recording.
std::map<blink::StorageKey, int64_t> GetCachedStorageKeysUsage() const;
- // Checks if there are ongoing tasks to get global or host usage. Used to
- // prevent a UsageTracker reset from happening before a task is complete.
+ // Checks if there are ongoing tasks to get usage. Used to prevent a
+ // UsageTracker reset from happening before a task is complete.
bool IsWorking() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- return !global_usage_callbacks_.empty() || !host_usage_callbacks_.empty();
+ return !global_usage_callbacks_.empty() ||
+ !storage_key_usage_callbacks_.empty() ||
+ !bucket_usage_callbacks_.empty();
}
// Sets if a `storage_key` for `client_type` should / should not be excluded
@@ -122,11 +116,9 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) UsageTracker
struct AccumulateInfo;
friend class ClientUsageTracker;
- void DidGetBucketsForType(QuotaErrorOr<std::set<BucketLocator>> result);
- void DidGetBucketsForHost(const std::string& host,
- QuotaErrorOr<std::set<BucketLocator>> result);
+ void DidGetBucketsForType(QuotaErrorOr<std::set<BucketInfo>> result);
void DidGetBucketsForStorageKey(const blink::StorageKey& storage_key,
- QuotaErrorOr<std::set<BucketLocator>> result);
+ QuotaErrorOr<std::set<BucketInfo>> result);
void DidGetBucketForUsage(QuotaClientType client_type,
int64_t delta,
QuotaErrorOr<BucketInfo> result);
@@ -142,8 +134,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) UsageTracker
int64_t unlimited_usage);
void FinallySendGlobalUsage(std::unique_ptr<AccumulateInfo> info);
- void FinallySendHostUsageWithBreakdown(std::unique_ptr<AccumulateInfo> info,
- const std::string& host);
void FinallySendStorageKeyUsageWithBreakdown(
std::unique_ptr<AccumulateInfo> info,
const blink::StorageKey& storage_key);
@@ -162,8 +152,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) UsageTracker
int client_tracker_count_ = 0;
std::vector<UsageCallback> global_usage_callbacks_;
- std::map<std::string, std::vector<UsageWithBreakdownCallback>>
- host_usage_callbacks_;
std::map<blink::StorageKey, std::vector<UsageWithBreakdownCallback>>
storage_key_usage_callbacks_;
std::map<BucketLocator, std::vector<UsageWithBreakdownCallback>>
diff --git a/chromium/storage/browser/quota/usage_tracker_unittest.cc b/chromium/storage/browser/quota/usage_tracker_unittest.cc
index 1cf26dbc740..054c4b41088 100644
--- a/chromium/storage/browser/quota/usage_tracker_unittest.cc
+++ b/chromium/storage/browser/quota/usage_tracker_unittest.cc
@@ -135,14 +135,6 @@ class UsageTrackerTest : public testing::Test {
*unlimited_usage = future.Get<1>();
}
- std::pair<int64_t, blink::mojom::UsageBreakdownPtr> GetHostUsageWithBreakdown(
- const std::string& host) {
- base::test::TestFuture<int64_t, blink::mojom::UsageBreakdownPtr> future;
- usage_tracker_->GetHostUsageWithBreakdown(host, future.GetCallback());
- return std::make_pair(future.Get<0>(),
- std::move(std::get<1>(future.Take())));
- }
-
std::pair<int64_t, blink::mojom::UsageBreakdownPtr>
GetStorageKeyUsageWithBreakdown(const blink::StorageKey& storage_key) {
base::test::TestFuture<int64_t, blink::mojom::UsageBreakdownPtr> future;
@@ -210,6 +202,8 @@ class UsageTrackerTest : public testing::Test {
quota_manager_->SetBootstrapDisabledForTesting(disable);
}
+ UsageTracker* usage_tracker() { return usage_tracker_.get(); }
+
private:
base::flat_map<mojom::QuotaClient*, QuotaClientType> GetQuotaClientMap() {
base::flat_map<mojom::QuotaClient*, QuotaClientType> client_map;
@@ -231,8 +225,6 @@ class UsageTrackerTest : public testing::Test {
TEST_F(UsageTrackerTest, GrantAndRevokeUnlimitedStorage) {
int64_t usage = 0;
int64_t unlimited_usage = 0;
- blink::mojom::UsageBreakdownPtr host_usage_breakdown_expected =
- blink::mojom::UsageBreakdown::New();
blink::mojom::UsageBreakdownPtr storage_key_usage_breakdown_expected =
blink::mojom::UsageBreakdown::New();
blink::mojom::UsageBreakdownPtr bucket_usage_breakdown_expected =
@@ -243,7 +235,6 @@ TEST_F(UsageTrackerTest, GrantAndRevokeUnlimitedStorage) {
const StorageKey storage_key =
StorageKey::CreateFromStringForTesting("http://example.com");
- const std::string& host = storage_key.origin().host();
BucketLocator bucket = CreateBucket(storage_key, kDefaultBucketName);
@@ -251,11 +242,6 @@ TEST_F(UsageTrackerTest, GrantAndRevokeUnlimitedStorage) {
GetGlobalUsage(&usage, &unlimited_usage);
EXPECT_EQ(100, usage);
EXPECT_EQ(0, unlimited_usage);
- host_usage_breakdown_expected->fileSystem = 100;
- std::pair<int64_t, blink::mojom::UsageBreakdownPtr> host_usage_breakdown =
- GetHostUsageWithBreakdown(host);
- EXPECT_EQ(100, host_usage_breakdown.first);
- EXPECT_EQ(host_usage_breakdown_expected, host_usage_breakdown.second);
storage_key_usage_breakdown_expected->fileSystem = 100;
std::pair<int64_t, blink::mojom::UsageBreakdownPtr>
storage_key_usage_breakdown =
@@ -273,9 +259,6 @@ TEST_F(UsageTrackerTest, GrantAndRevokeUnlimitedStorage) {
GetGlobalUsage(&usage, &unlimited_usage);
EXPECT_EQ(100, usage);
EXPECT_EQ(100, unlimited_usage);
- host_usage_breakdown = GetHostUsageWithBreakdown(host);
- EXPECT_EQ(100, host_usage_breakdown.first);
- EXPECT_EQ(host_usage_breakdown_expected, host_usage_breakdown.second);
storage_key_usage_breakdown = GetStorageKeyUsageWithBreakdown(storage_key);
EXPECT_EQ(100, storage_key_usage_breakdown.first);
EXPECT_EQ(storage_key_usage_breakdown_expected,
@@ -288,9 +271,6 @@ TEST_F(UsageTrackerTest, GrantAndRevokeUnlimitedStorage) {
GetGlobalUsage(&usage, &unlimited_usage);
EXPECT_EQ(100, usage);
EXPECT_EQ(0, unlimited_usage);
- GetHostUsageWithBreakdown(host);
- EXPECT_EQ(100, host_usage_breakdown.first);
- EXPECT_EQ(host_usage_breakdown_expected, host_usage_breakdown.second);
GetStorageKeyUsageWithBreakdown(storage_key);
EXPECT_EQ(100, storage_key_usage_breakdown.first);
EXPECT_EQ(storage_key_usage_breakdown_expected,
@@ -303,8 +283,6 @@ TEST_F(UsageTrackerTest, GrantAndRevokeUnlimitedStorage) {
TEST_F(UsageTrackerTest, CacheDisabledClientTest) {
int64_t usage = 0;
int64_t unlimited_usage = 0;
- blink::mojom::UsageBreakdownPtr host_usage_breakdown_expected =
- blink::mojom::UsageBreakdown::New();
blink::mojom::UsageBreakdownPtr storage_key_usage_breakdown_expected =
blink::mojom::UsageBreakdown::New();
blink::mojom::UsageBreakdownPtr bucket_usage_breakdown_expected =
@@ -312,7 +290,6 @@ TEST_F(UsageTrackerTest, CacheDisabledClientTest) {
const StorageKey storage_key =
StorageKey::CreateFromStringForTesting("http://example.com");
- const std::string& host = storage_key.origin().host();
BucketLocator bucket = CreateBucket(storage_key, kDefaultBucketName);
@@ -320,11 +297,6 @@ TEST_F(UsageTrackerTest, CacheDisabledClientTest) {
GetGlobalUsage(&usage, &unlimited_usage);
EXPECT_EQ(100, usage);
EXPECT_EQ(0, unlimited_usage);
- host_usage_breakdown_expected->fileSystem = 100;
- std::pair<int64_t, blink::mojom::UsageBreakdownPtr> host_usage_breakdown =
- GetHostUsageWithBreakdown(host);
- EXPECT_EQ(100, host_usage_breakdown.first);
- EXPECT_EQ(host_usage_breakdown_expected, host_usage_breakdown.second);
storage_key_usage_breakdown_expected->fileSystem = 100;
std::pair<int64_t, blink::mojom::UsageBreakdownPtr>
storage_key_usage_breakdown =
@@ -342,9 +314,6 @@ TEST_F(UsageTrackerTest, CacheDisabledClientTest) {
GetGlobalUsage(&usage, &unlimited_usage);
EXPECT_EQ(100, usage);
EXPECT_EQ(0, unlimited_usage);
- host_usage_breakdown = GetHostUsageWithBreakdown(host);
- EXPECT_EQ(100, host_usage_breakdown.first);
- EXPECT_EQ(host_usage_breakdown_expected, host_usage_breakdown.second);
storage_key_usage_breakdown = GetStorageKeyUsageWithBreakdown(storage_key);
EXPECT_EQ(100, storage_key_usage_breakdown.first);
EXPECT_EQ(storage_key_usage_breakdown_expected,
@@ -361,10 +330,6 @@ TEST_F(UsageTrackerTest, CacheDisabledClientTest) {
GetGlobalUsage(&usage, &unlimited_usage);
EXPECT_EQ(400, usage);
EXPECT_EQ(400, unlimited_usage);
- host_usage_breakdown = GetHostUsageWithBreakdown(host);
- host_usage_breakdown_expected->fileSystem = 400;
- EXPECT_EQ(400, host_usage_breakdown.first);
- EXPECT_EQ(host_usage_breakdown_expected, host_usage_breakdown.second);
storage_key_usage_breakdown = GetStorageKeyUsageWithBreakdown(storage_key);
storage_key_usage_breakdown_expected->fileSystem = 400;
EXPECT_EQ(400, storage_key_usage_breakdown.first);
@@ -379,15 +344,11 @@ TEST_F(UsageTrackerTest, CacheDisabledClientTest) {
GetGlobalUsage(&usage, &unlimited_usage);
EXPECT_EQ(400, usage);
EXPECT_EQ(0, unlimited_usage);
- host_usage_breakdown = GetHostUsageWithBreakdown(host);
- EXPECT_EQ(400, host_usage_breakdown.first);
- EXPECT_EQ(host_usage_breakdown_expected, host_usage_breakdown.second);
storage_key_usage_breakdown = GetStorageKeyUsageWithBreakdown(storage_key);
EXPECT_EQ(400, storage_key_usage_breakdown.first);
EXPECT_EQ(storage_key_usage_breakdown_expected,
storage_key_usage_breakdown.second);
bucket_usage_breakdown = GetBucketUsageWithBreakdown(bucket);
- EXPECT_EQ(400, host_usage_breakdown.first);
EXPECT_EQ(bucket_usage_breakdown_expected, bucket_usage_breakdown.second);
SetUsageCacheEnabled(storage_key, true);
@@ -396,10 +357,6 @@ TEST_F(UsageTrackerTest, CacheDisabledClientTest) {
GetGlobalUsage(&usage, &unlimited_usage);
EXPECT_EQ(500, usage);
EXPECT_EQ(0, unlimited_usage);
- host_usage_breakdown = GetHostUsageWithBreakdown(host);
- host_usage_breakdown_expected->fileSystem = 500;
- EXPECT_EQ(500, host_usage_breakdown.first);
- EXPECT_EQ(host_usage_breakdown_expected, host_usage_breakdown.second);
storage_key_usage_breakdown = GetStorageKeyUsageWithBreakdown(storage_key);
storage_key_usage_breakdown_expected->fileSystem = 500;
EXPECT_EQ(500, storage_key_usage_breakdown.first);
@@ -577,10 +534,52 @@ TEST_F(UsageTrackerTest, QuotaDatabaseDisabled) {
const StorageKey kStorageKey =
StorageKey::CreateFromStringForTesting("http://example.com");
- std::pair<int64_t, blink::mojom::UsageBreakdownPtr> host_usage_breakdown =
- GetHostUsageWithBreakdown(kStorageKey.origin().host());
- EXPECT_EQ(host_usage_breakdown.first, -1);
- EXPECT_EQ(host_usage_breakdown.second, blink::mojom::UsageBreakdown::New());
+ std::pair<int64_t, blink::mojom::UsageBreakdownPtr>
+ storage_key_usage_breakdown =
+ GetStorageKeyUsageWithBreakdown(kStorageKey);
+ EXPECT_EQ(storage_key_usage_breakdown.first, -1);
+ EXPECT_EQ(storage_key_usage_breakdown.second,
+ blink::mojom::UsageBreakdown::New());
+}
+
+TEST_F(UsageTrackerTest, IsWorking) {
+ const StorageKey kStorageKey =
+ StorageKey::CreateFromStringForTesting("http://example.com");
+ BucketLocator bucket = CreateBucket(kStorageKey, kDefaultBucketName);
+ UpdateUsageWithoutNotification(bucket, 100);
+
+ EXPECT_FALSE(usage_tracker()->IsWorking());
+
+ // UsageTracker::GetBucketUsage task.
+ base::test::TestFuture<int64_t, blink::mojom::UsageBreakdownPtr>
+ bucket_usage_future;
+ usage_tracker()->GetBucketUsageWithBreakdown(
+ bucket, bucket_usage_future.GetCallback());
+
+ EXPECT_TRUE(usage_tracker()->IsWorking());
+
+ ASSERT_TRUE(bucket_usage_future.Wait());
+ EXPECT_FALSE(usage_tracker()->IsWorking());
+
+ // UsageTracker::GetStorageKeyUsage task.
+ base::test::TestFuture<int64_t, blink::mojom::UsageBreakdownPtr>
+ storage_key_usage_future;
+ usage_tracker()->GetStorageKeyUsageWithBreakdown(
+ kStorageKey, storage_key_usage_future.GetCallback());
+
+ EXPECT_TRUE(usage_tracker()->IsWorking());
+
+ ASSERT_TRUE(storage_key_usage_future.Wait());
+ EXPECT_FALSE(usage_tracker()->IsWorking());
+
+ // UsageTracker::GetGlobalUsage task.
+ base::test::TestFuture<int64_t, int64_t> global_usage_future;
+ usage_tracker()->GetGlobalUsage(global_usage_future.GetCallback());
+
+ EXPECT_TRUE(usage_tracker()->IsWorking());
+
+ ASSERT_TRUE(global_usage_future.Wait());
+ EXPECT_FALSE(usage_tracker()->IsWorking());
}
} // namespace storage
diff --git a/chromium/storage/common/file_system/file_system_types.h b/chromium/storage/common/file_system/file_system_types.h
index e5630d1279f..4df4497e1d9 100644
--- a/chromium/storage/common/file_system/file_system_types.h
+++ b/chromium/storage/common/file_system/file_system_types.h
@@ -98,11 +98,6 @@ enum FileSystemType {
// file which must go away when the blob's last reference is dropped.
kFileSystemTypeForTransientFile,
- // Sandboxed private filesystem. This filesystem cannot be opened
- // via regular OpenFileSystem, and provides private filesystem space for
- // given identifier in each origin.
- kFileSystemTypePluginPrivate,
-
// A filesystem that is mounted via the FileSystemProvider API.
kFileSystemTypeProvided,
diff --git a/chromium/storage/common/file_system/file_system_util.cc b/chromium/storage/common/file_system/file_system_util.cc
index 1dd214bda56..bb541ce4612 100644
--- a/chromium/storage/common/file_system/file_system_util.cc
+++ b/chromium/storage/common/file_system/file_system_util.cc
@@ -263,8 +263,6 @@ std::string GetFileSystemTypeString(FileSystemType type) {
return "LocalForPlatformApp";
case kFileSystemTypeForTransientFile:
return "TransientFile";
- case kFileSystemTypePluginPrivate:
- return "PluginPrivate";
case kFileSystemTypeProvided:
return "Provided";
case kFileSystemTypeDeviceMediaAsFileStorage: