diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 6d08dbd85c87d0..909ab9555458a4 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc @@ -7480,6 +7480,11 @@ const FeatureEntry kFeatureEntries[] = { flag_descriptions::kExtensionsMenuAccessControlDescription, kOsDesktop, FEATURE_VALUE_TYPE(features::kExtensionsMenuAccessControl)}, + {"persistent-quota-is-temporary-quota", + flag_descriptions::kPersistentQuotaIsTemporaryQuotaName, + flag_descriptions::kPersistentQuotaIsTemporaryQuotaDescription, kOsAll, + FEATURE_VALUE_TYPE(blink::features::kPersistentQuotaIsTemporaryQuota)}, + // NOTE: Adding a new flag requires adding a corresponding entry to enum // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag // Histograms" in tools/metrics/histograms/README.md (run the diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 042ef3fcbb9d0b..69235ac69b5f02 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json @@ -4421,6 +4421,11 @@ "owners": [ "elklm", "engedy"], "expiry_milestone": 100 }, + { + "name": "persistent-quota-is-temporary-quota", + "owners": [ "mek", "cfredric" ], + "expiry_milestone": 100 + }, { "name": "photo-picker-video-support", "owners": [ "finnur" ], diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index dd5edbb92f9a5e..8f16c480151d11 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc @@ -2038,6 +2038,12 @@ const char kPermissionQuietChipDescription[] = "prompts. Requires chrome://flags/#quiet-notification-prompts to be " "enabled."; +const char kPersistentQuotaIsTemporaryQuotaName[] = + "window.PERSISTENT is temporary quota."; +const char kPersistentQuotaIsTemporaryQuotaDescription[] = + "Causes the window.PERSISTENT quota type to have the same semantics as " + "window.TEMPORARY."; + const char kPlaybackSpeedButtonName[] = "Playback Speed Button"; const char kPlaybackSpeedButtonDescription[] = "Enable the playback speed button on the media controls."; diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index c5107a62ac67d8..b50f698b725e17 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h @@ -1160,6 +1160,9 @@ extern const char kPermissionPredictionsDescription[]; extern const char kPermissionQuietChipName[]; extern const char kPermissionQuietChipDescription[]; +extern const char kPersistentQuotaIsTemporaryQuotaName[]; +extern const char kPersistentQuotaIsTemporaryQuotaDescription[]; + extern const char kPlaybackSpeedButtonName[]; extern const char kPlaybackSpeedButtonDescription[]; diff --git a/storage/browser/file_system/file_system_quota_client.cc b/storage/browser/file_system/file_system_quota_client.cc index 0e6e601ec18e16..195e2112faa9d8 100644 --- a/storage/browser/file_system/file_system_quota_client.cc +++ b/storage/browser/file_system/file_system_quota_client.cc @@ -4,12 +4,17 @@ #include "storage/browser/file_system/file_system_quota_client.h" +#include #include #include #include +#include "base/barrier_callback.h" +#include "base/barrier_closure.h" #include "base/bind.h" #include "base/check.h" +#include "base/containers/span.h" +#include "base/feature_list.h" #include "base/files/file.h" #include "base/location.h" #include "base/sequence_checker.h" @@ -18,6 +23,7 @@ #include "storage/browser/file_system/file_system_context.h" #include "storage/common/file_system/file_system_types.h" #include "storage/common/file_system/file_system_util.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/blink/public/mojom/quota/quota_types.mojom.h" #include "url/origin.h" @@ -26,6 +32,14 @@ namespace storage { namespace { +static const FileSystemType kTemporaryAndPersistent[] = { + kFileSystemTypeTemporary, + kFileSystemTypePersistent, +}; +static const FileSystemType kTemporary[] = {kFileSystemTypeTemporary}; +static const FileSystemType kPersistent[] = {kFileSystemTypePersistent}; +static const FileSystemType kSyncable[] = {kFileSystemTypeSyncable}; + std::vector ToStorageKeys( const std::vector& origins) { std::vector storage_keys; @@ -35,13 +49,53 @@ std::vector ToStorageKeys( return storage_keys; } -std::vector GetStorageKeysForTypeOnFileTaskRunner( - FileSystemContext* context, +template +std::vector MergeWithoutDuplicates(const std::vector>& tss) { + if (tss.size() == 1) { + // We assume that each vector contains no duplicates, already. + return tss[0]; + } + std::vector merged; + merged.reserve(std::accumulate( + tss.begin(), tss.end(), 0U, + [](size_t acc, const std::vector& ts) { return acc + ts.size(); })); + for (const auto& ts : tss) { + merged.insert(merged.end(), ts.begin(), ts.end()); + } + base::ranges::sort(merged); + merged.erase(base::ranges::unique(merged), merged.end()); + return merged; +} + +// Converts StorageType to the FileSystemTypes that are used for that quota +// type. +base::span QuotaStorageTypeToFileSystemTypes( blink::mojom::StorageType storage_type) { - FileSystemType type = - FileSystemQuotaClient::QuotaStorageTypeToFileSystemType(storage_type); - DCHECK(type != kFileSystemTypeUnknown); + using StorageType = blink::mojom::StorageType; + + if (base::FeatureList::IsEnabled( + blink::features::kPersistentQuotaIsTemporaryQuota)) { + DCHECK_NE(storage_type, StorageType::kPersistent); + if (storage_type == StorageType::kTemporary) + return kTemporaryAndPersistent; + } + switch (storage_type) { + case StorageType::kTemporary: + return kTemporary; + case StorageType::kPersistent: + return kPersistent; + case StorageType::kSyncable: + return kSyncable; + case StorageType::kQuotaNotManaged: + case StorageType::kUnknown: + NOTREACHED(); + return {}; + } +} +std::vector GetStorageKeysForTypeOnFileTaskRunner( + FileSystemContext* context, + FileSystemType type) { FileSystemQuotaUtil* quota_util = context->GetQuotaUtil(type); if (!quota_util) return {}; @@ -50,12 +104,8 @@ std::vector GetStorageKeysForTypeOnFileTaskRunner( std::vector GetStorageKeysForHostOnFileTaskRunner( FileSystemContext* context, - blink::mojom::StorageType storage_type, + FileSystemType type, const std::string& host) { - FileSystemType type = - FileSystemQuotaClient::QuotaStorageTypeToFileSystemType(storage_type); - DCHECK(type != kFileSystemTypeUnknown); - FileSystemQuotaUtil* quota_util = context->GetQuotaUtil(type); if (!quota_util) return {}; @@ -107,24 +157,31 @@ void FileSystemQuotaClient::GetStorageKeyUsage( DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!callback.is_null()); - FileSystemType type = - FileSystemQuotaClient::QuotaStorageTypeToFileSystemType(storage_type); - DCHECK(type != kFileSystemTypeUnknown); + base::span types = + QuotaStorageTypeToFileSystemTypes(storage_type); - FileSystemQuotaUtil* quota_util = file_system_context_->GetQuotaUtil(type); - if (!quota_util) { - std::move(callback).Run(0); - return; - } + base::RepeatingCallback barrier = + base::BarrierCallback( + types.size(), base::BindOnce([](std::vector usages) { + return std::accumulate(usages.begin(), usages.end(), + 0U); + }).Then(std::move(callback))); - file_task_runner()->PostTaskAndReplyWithResult( - FROM_HERE, - // It is safe to pass Unretained(quota_util) since context owns it. - base::BindOnce(&FileSystemQuotaUtil::GetOriginUsageOnFileTaskRunner, - base::Unretained(quota_util), - base::RetainedRef(file_system_context_), - storage_key.origin(), type), - std::move(callback)); + for (auto type : types) { + FileSystemQuotaUtil* quota_util = file_system_context_->GetQuotaUtil(type); + if (quota_util) { + file_task_runner()->PostTaskAndReplyWithResult( + FROM_HERE, + // It is safe to pass Unretained(quota_util) since context owns it. + base::BindOnce(&FileSystemQuotaUtil::GetOriginUsageOnFileTaskRunner, + base::Unretained(quota_util), + base::RetainedRef(file_system_context_), + storage_key.origin(), type), + barrier); + } else { + barrier.Run(0); + } + } } void FileSystemQuotaClient::GetStorageKeysForType( @@ -133,11 +190,22 @@ void FileSystemQuotaClient::GetStorageKeysForType( DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!callback.is_null()); - file_task_runner()->PostTaskAndReplyWithResult( - FROM_HERE, - base::BindOnce(&GetStorageKeysForTypeOnFileTaskRunner, - base::RetainedRef(file_system_context_), storage_type), - std::move(callback)); + base::span types = + QuotaStorageTypeToFileSystemTypes(storage_type); + + base::RepeatingCallback)> barrier = + base::BarrierCallback>( + types.size(), + base::BindOnce(&MergeWithoutDuplicates) + .Then(std::move(callback))); + + for (auto type : types) { + file_task_runner()->PostTaskAndReplyWithResult( + FROM_HERE, + base::BindOnce(&GetStorageKeysForTypeOnFileTaskRunner, + base::RetainedRef(file_system_context_), type), + barrier); + } } void FileSystemQuotaClient::GetStorageKeysForHost( @@ -147,12 +215,22 @@ void FileSystemQuotaClient::GetStorageKeysForHost( DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!callback.is_null()); - file_task_runner()->PostTaskAndReplyWithResult( - FROM_HERE, - base::BindOnce(&GetStorageKeysForHostOnFileTaskRunner, - base::RetainedRef(file_system_context_), storage_type, - host), - std::move(callback)); + base::span types = + QuotaStorageTypeToFileSystemTypes(storage_type); + + base::RepeatingCallback)> barrier = + base::BarrierCallback>( + types.size(), + base::BindOnce(&MergeWithoutDuplicates) + .Then(std::move(callback))); + + for (auto type : types) { + file_task_runner()->PostTaskAndReplyWithResult( + FROM_HERE, + base::BindOnce(&GetStorageKeysForHostOnFileTaskRunner, + base::RetainedRef(file_system_context_), type, host), + barrier); + } } void FileSystemQuotaClient::DeleteStorageKeyData( @@ -162,15 +240,29 @@ void FileSystemQuotaClient::DeleteStorageKeyData( DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!callback.is_null()); - FileSystemType fs_type = QuotaStorageTypeToFileSystemType(type); - DCHECK(fs_type != kFileSystemTypeUnknown); + base::span fs_types = + QuotaStorageTypeToFileSystemTypes(type); - file_task_runner()->PostTaskAndReplyWithResult( - FROM_HERE, - base::BindOnce(&DeleteStorageKeyOnFileTaskRunner, - base::RetainedRef(file_system_context_), storage_key, - fs_type), - std::move(callback)); + base::RepeatingCallback barrier = + base::BarrierCallback( + fs_types.size(), + base::BindOnce([](const std::vector& + statuses) { + for (auto status : statuses) { + if (status != blink::mojom::QuotaStatusCode::kOk) + return status; + } + return blink::mojom::QuotaStatusCode::kOk; + }).Then(std::move(callback))); + + for (const auto fs_type : fs_types) { + file_task_runner()->PostTaskAndReplyWithResult( + FROM_HERE, + base::BindOnce(&DeleteStorageKeyOnFileTaskRunner, + base::RetainedRef(file_system_context_), storage_key, + fs_type), + barrier); + } } void FileSystemQuotaClient::PerformStorageCleanup( @@ -179,30 +271,19 @@ void FileSystemQuotaClient::PerformStorageCleanup( DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!callback.is_null()); - FileSystemType fs_type = QuotaStorageTypeToFileSystemType(type); - DCHECK(fs_type != kFileSystemTypeUnknown); - file_task_runner()->PostTaskAndReply( - FROM_HERE, - base::BindOnce(&PerformStorageCleanupOnFileTaskRunner, - base::RetainedRef(file_system_context_), fs_type), - std::move(callback)); -} + base::span fs_types = + QuotaStorageTypeToFileSystemTypes(type); -// static -FileSystemType FileSystemQuotaClient::QuotaStorageTypeToFileSystemType( - blink::mojom::StorageType storage_type) { - switch (storage_type) { - case blink::mojom::StorageType::kTemporary: - return kFileSystemTypeTemporary; - case blink::mojom::StorageType::kPersistent: - return kFileSystemTypePersistent; - case blink::mojom::StorageType::kSyncable: - return kFileSystemTypeSyncable; - case blink::mojom::StorageType::kQuotaNotManaged: - case blink::mojom::StorageType::kUnknown: - return kFileSystemTypeUnknown; + base::RepeatingClosure barrier = + base::BarrierClosure(fs_types.size(), std::move(callback)); + + for (auto fs_type : fs_types) { + file_task_runner()->PostTaskAndReply( + FROM_HERE, + base::BindOnce(&PerformStorageCleanupOnFileTaskRunner, + base::RetainedRef(file_system_context_), fs_type), + barrier); } - return kFileSystemTypeUnknown; } base::SequencedTaskRunner* FileSystemQuotaClient::file_task_runner() const { diff --git a/storage/browser/file_system/file_system_quota_client.h b/storage/browser/file_system/file_system_quota_client.h index fee07e696b2406..f686c0ee10e123 100644 --- a/storage/browser/file_system/file_system_quota_client.h +++ b/storage/browser/file_system/file_system_quota_client.h @@ -55,14 +55,6 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemQuotaClient void PerformStorageCleanup(blink::mojom::StorageType type, PerformStorageCleanupCallback callback) override; - // Converts FileSystemType `type` to/from the StorageType `storage_type` that - // is used for the unified quota system. - // (Basically this naively maps TEMPORARY storage type to TEMPORARY filesystem - // type, PERSISTENT storage type to PERSISTENT filesystem type and vice - // versa.) - static FileSystemType QuotaStorageTypeToFileSystemType( - blink::mojom::StorageType storage_type); - private: base::SequencedTaskRunner* file_task_runner() const; diff --git a/storage/browser/file_system/file_system_quota_client_unittest.cc b/storage/browser/file_system/file_system_quota_client_unittest.cc index cb8bdfd5088b74..e5c2086ce43730 100644 --- a/storage/browser/file_system/file_system_quota_client_unittest.cc +++ b/storage/browser/file_system/file_system_quota_client_unittest.cc @@ -13,6 +13,7 @@ #include "base/files/scoped_temp_dir.h" #include "base/macros.h" #include "base/run_loop.h" +#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "components/services/storage/public/mojom/quota_client.mojom.h" #include "storage/browser/file_system/file_system_context.h" @@ -27,6 +28,7 @@ #include "storage/common/file_system/file_system_util.h" #include "testing/gmock/include/gmock/gmock-matchers.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/blink/public/mojom/quota/quota_types.mojom.h" #include "url/gurl.h" @@ -48,17 +50,26 @@ const StorageType kPersistent = StorageType::kPersistent; } // namespace -class FileSystemQuotaClientTest : public testing::Test { +class FileSystemQuotaClientTest : public testing::TestWithParam { public: FileSystemQuotaClientTest() = default; ~FileSystemQuotaClientTest() override = default; void SetUp() override { + if (persistent_quota_is_temporary_quota()) { + feature_list_.InitAndEnableFeature( + blink::features::kPersistentQuotaIsTemporaryQuota); + } else { + feature_list_.InitAndDisableFeature( + blink::features::kPersistentQuotaIsTemporaryQuota); + } ASSERT_TRUE(data_dir_.CreateUniqueTempDir()); file_system_context_ = CreateFileSystemContextForTesting( /*quota_manager_proxy=*/nullptr, data_dir_.GetPath()); } + bool persistent_quota_is_temporary_quota() const { return GetParam(); } + struct TestFile { bool isDirectory; const char* name; @@ -169,9 +180,8 @@ class FileSystemQuotaClientTest : public testing::Test { // create it later, this will fail due to a quota mismatch. If we // call this before we create the root, it succeeds, but hasn't // actually created the cache. - ASSERT_EQ(0, GetStorageKeyUsage( - quota_client, file.origin_url, - FileSystemTypeToQuotaStorageType(file.type))); + GetStorageKeyUsage(quota_client, file.origin_url, + FileSystemTypeToQuotaStorageType(file.type)); } } else { ASSERT_TRUE( @@ -232,6 +242,7 @@ class FileSystemQuotaClientTest : public testing::Test { deletion_status_ = status; } + base::test::ScopedFeatureList feature_list_; base::ScopedTempDir data_dir_; base::test::TaskEnvironment task_environment_; scoped_refptr file_system_context_; @@ -243,13 +254,13 @@ class FileSystemQuotaClientTest : public testing::Test { base::WeakPtrFactory weak_factory_{this}; }; -TEST_F(FileSystemQuotaClientTest, NoFileSystemTest) { +TEST_P(FileSystemQuotaClientTest, NoFileSystemTest) { FileSystemQuotaClient quota_client(GetFileSystemContext()); EXPECT_EQ(0, GetStorageKeyUsage(quota_client, kDummyURL1, kTemporary)); } -TEST_F(FileSystemQuotaClientTest, NoFileTest) { +TEST_P(FileSystemQuotaClientTest, NoFileTest) { FileSystemQuotaClient quota_client(GetFileSystemContext()); InitializeOriginFiles(quota_client, @@ -260,7 +271,7 @@ TEST_F(FileSystemQuotaClientTest, NoFileTest) { } } -TEST_F(FileSystemQuotaClientTest, OneFileTest) { +TEST_P(FileSystemQuotaClientTest, OneFileTest) { FileSystemQuotaClient quota_client(GetFileSystemContext()); const std::vector kFiles = { {true, "", 0, kDummyURL1, kFileSystemTypeTemporary}, @@ -276,7 +287,7 @@ TEST_F(FileSystemQuotaClientTest, OneFileTest) { } } -TEST_F(FileSystemQuotaClientTest, TwoFilesTest) { +TEST_P(FileSystemQuotaClientTest, TwoFilesTest) { FileSystemQuotaClient quota_client(GetFileSystemContext()); const std::vector kFiles = { {true, "", 0, kDummyURL1, kFileSystemTypeTemporary}, @@ -293,7 +304,7 @@ TEST_F(FileSystemQuotaClientTest, TwoFilesTest) { } } -TEST_F(FileSystemQuotaClientTest, EmptyFilesTest) { +TEST_P(FileSystemQuotaClientTest, EmptyFilesTest) { FileSystemQuotaClient quota_client(GetFileSystemContext()); const std::vector kFiles = { {true, "", 0, kDummyURL1, kFileSystemTypeTemporary}, @@ -311,7 +322,7 @@ TEST_F(FileSystemQuotaClientTest, EmptyFilesTest) { } } -TEST_F(FileSystemQuotaClientTest, SubDirectoryTest) { +TEST_P(FileSystemQuotaClientTest, SubDirectoryTest) { FileSystemQuotaClient quota_client(GetFileSystemContext()); const std::vector kFiles = { {true, "", 0, kDummyURL1, kFileSystemTypeTemporary}, @@ -329,7 +340,7 @@ TEST_F(FileSystemQuotaClientTest, SubDirectoryTest) { } } -TEST_F(FileSystemQuotaClientTest, MultiTypeTest) { +TEST_P(FileSystemQuotaClientTest, MultiTypeTest) { FileSystemQuotaClient quota_client(GetFileSystemContext()); const std::vector kFiles = { {true, "", 0, kDummyURL1, kFileSystemTypeTemporary}, @@ -350,14 +361,20 @@ TEST_F(FileSystemQuotaClientTest, MultiTypeTest) { kFileSystemTypePersistent); for (int i = 0; i < 2; i++) { - EXPECT_EQ(133 + 14 + file_paths_cost_temporary, - GetStorageKeyUsage(quota_client, kDummyURL1, kTemporary)); - EXPECT_EQ(193 + 9 + file_paths_cost_persistent, - GetStorageKeyUsage(quota_client, kDummyURL1, kPersistent)); + if (persistent_quota_is_temporary_quota()) { + EXPECT_EQ(133 + 14 + file_paths_cost_temporary + 193 + 9 + + file_paths_cost_persistent, + GetStorageKeyUsage(quota_client, kDummyURL1, kTemporary)); + } else { + EXPECT_EQ(133 + 14 + file_paths_cost_temporary, + GetStorageKeyUsage(quota_client, kDummyURL1, kTemporary)); + EXPECT_EQ(193 + 9 + file_paths_cost_persistent, + GetStorageKeyUsage(quota_client, kDummyURL1, kPersistent)); + } } } -TEST_F(FileSystemQuotaClientTest, MultiDomainTest) { +TEST_P(FileSystemQuotaClientTest, MultiDomainTest) { FileSystemQuotaClient quota_client(GetFileSystemContext()); const std::vector kFiles = { {true, "", 0, kDummyURL1, kFileSystemTypeTemporary}, @@ -392,18 +409,27 @@ TEST_F(FileSystemQuotaClientTest, MultiDomainTest) { kFileSystemTypePersistent); for (int i = 0; i < 2; i++) { - EXPECT_EQ(1331 + 134 + file_paths_cost_temporary1, - GetStorageKeyUsage(quota_client, kDummyURL1, kTemporary)); - EXPECT_EQ(1903 + 19 + file_paths_cost_persistent1, - GetStorageKeyUsage(quota_client, kDummyURL1, kPersistent)); - EXPECT_EQ(1319 + 113 + file_paths_cost_temporary2, - GetStorageKeyUsage(quota_client, kDummyURL2, kTemporary)); - EXPECT_EQ(2013 + 18 + file_paths_cost_persistent2, - GetStorageKeyUsage(quota_client, kDummyURL2, kPersistent)); + if (persistent_quota_is_temporary_quota()) { + EXPECT_EQ(1331 + 134 + file_paths_cost_temporary1 + 1903 + 19 + + file_paths_cost_persistent1, + GetStorageKeyUsage(quota_client, kDummyURL1, kTemporary)); + EXPECT_EQ(1319 + 113 + file_paths_cost_temporary2 + 2013 + 18 + + file_paths_cost_persistent2, + GetStorageKeyUsage(quota_client, kDummyURL2, kTemporary)); + } else { + EXPECT_EQ(1331 + 134 + file_paths_cost_temporary1, + GetStorageKeyUsage(quota_client, kDummyURL1, kTemporary)); + EXPECT_EQ(1903 + 19 + file_paths_cost_persistent1, + GetStorageKeyUsage(quota_client, kDummyURL1, kPersistent)); + EXPECT_EQ(1319 + 113 + file_paths_cost_temporary2, + GetStorageKeyUsage(quota_client, kDummyURL2, kTemporary)); + EXPECT_EQ(2013 + 18 + file_paths_cost_persistent2, + GetStorageKeyUsage(quota_client, kDummyURL2, kPersistent)); + } } } -TEST_F(FileSystemQuotaClientTest, GetUsage_MultipleTasks) { +TEST_P(FileSystemQuotaClientTest, GetUsage_MultipleTasks) { FileSystemQuotaClient quota_client(GetFileSystemContext()); const std::vector kFiles = { {true, "", 0, kDummyURL1, kFileSystemTypeTemporary}, @@ -433,7 +459,7 @@ TEST_F(FileSystemQuotaClientTest, GetUsage_MultipleTasks) { EXPECT_EQ(2, additional_callback_count()); } -TEST_F(FileSystemQuotaClientTest, GetStorageKeysForType) { +TEST_P(FileSystemQuotaClientTest, GetStorageKeysForType) { FileSystemQuotaClient quota_client(GetFileSystemContext()); InitializeOriginFiles( quota_client, { @@ -442,13 +468,21 @@ TEST_F(FileSystemQuotaClientTest, GetStorageKeysForType) { {true, "", 0, kDummyURL3, kFileSystemTypePersistent}, }); - EXPECT_THAT(GetStorageKeysForType(quota_client, kTemporary), - testing::UnorderedElementsAre( - StorageKey::CreateFromStringForTesting(kDummyURL1), - StorageKey::CreateFromStringForTesting(kDummyURL2))); + if (persistent_quota_is_temporary_quota()) { + EXPECT_THAT(GetStorageKeysForType(quota_client, kTemporary), + testing::UnorderedElementsAre( + StorageKey::CreateFromStringForTesting(kDummyURL1), + StorageKey::CreateFromStringForTesting(kDummyURL2), + StorageKey::CreateFromStringForTesting(kDummyURL3))); + } else { + EXPECT_THAT(GetStorageKeysForType(quota_client, kTemporary), + testing::UnorderedElementsAre( + StorageKey::CreateFromStringForTesting(kDummyURL1), + StorageKey::CreateFromStringForTesting(kDummyURL2))); + } } -TEST_F(FileSystemQuotaClientTest, GetStorageKeysForHost) { +TEST_P(FileSystemQuotaClientTest, GetStorageKeysForHost) { FileSystemQuotaClient quota_client(GetFileSystemContext()); const char* kURL1 = "http://foo.com/"; const char* kURL2 = "https://foo.com/"; @@ -464,14 +498,23 @@ TEST_F(FileSystemQuotaClientTest, GetStorageKeysForHost) { {true, "", 0, kURL5, kFileSystemTypePersistent}, }); - EXPECT_THAT(GetStorageKeysForHost(quota_client, kTemporary, "foo.com"), - testing::UnorderedElementsAre( - StorageKey::CreateFromStringForTesting(kURL1), - StorageKey::CreateFromStringForTesting(kURL2), - StorageKey::CreateFromStringForTesting(kURL3))); + if (persistent_quota_is_temporary_quota()) { + EXPECT_THAT(GetStorageKeysForHost(quota_client, kTemporary, "foo.com"), + testing::UnorderedElementsAre( + StorageKey::CreateFromStringForTesting(kURL1), + StorageKey::CreateFromStringForTesting(kURL2), + StorageKey::CreateFromStringForTesting(kURL3), + StorageKey::CreateFromStringForTesting(kURL5))); + } else { + EXPECT_THAT(GetStorageKeysForHost(quota_client, kTemporary, "foo.com"), + testing::UnorderedElementsAre( + StorageKey::CreateFromStringForTesting(kURL1), + StorageKey::CreateFromStringForTesting(kURL2), + StorageKey::CreateFromStringForTesting(kURL3))); + } } -TEST_F(FileSystemQuotaClientTest, DeleteOriginTest) { +TEST_P(FileSystemQuotaClientTest, DeleteOriginTest) { FileSystemQuotaClient quota_client(GetFileSystemContext()); const std::vector kFiles = { {true, "", 0, "http://foo.com/", kFileSystemTypeTemporary}, @@ -499,6 +542,9 @@ TEST_F(FileSystemQuotaClientTest, DeleteOriginTest) { const int64_t file_paths_cost_temporary_bar = ComputeFilePathsCostForOriginAndType(kFiles, "http://bar.com/", kFileSystemTypeTemporary); + const int64_t file_paths_cost_persistent_bar = + ComputeFilePathsCostForOriginAndType(kFiles, "http://bar.com/", + kFileSystemTypePersistent); const int64_t file_paths_cost_temporary_bar_https = ComputeFilePathsCostForOriginAndType(kFiles, "https://bar.com/", kFileSystemTypeTemporary); @@ -510,29 +556,44 @@ TEST_F(FileSystemQuotaClientTest, DeleteOriginTest) { base::RunLoop().RunUntilIdle(); EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk, status()); - DeleteStorageKeyData("a_client, "http://bar.com/", kPersistent); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk, status()); + if (!persistent_quota_is_temporary_quota()) { + DeleteStorageKeyData("a_client, "http://bar.com/", kPersistent); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk, status()); + } DeleteStorageKeyData("a_client, "http://buz.com/", kTemporary); base::RunLoop().RunUntilIdle(); EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk, status()); EXPECT_EQ(0, GetStorageKeyUsage(quota_client, "http://foo.com/", kTemporary)); - EXPECT_EQ(0, - GetStorageKeyUsage(quota_client, "http://bar.com/", kPersistent)); EXPECT_EQ(0, GetStorageKeyUsage(quota_client, "http://buz.com/", kTemporary)); - EXPECT_EQ(2 + file_paths_cost_temporary_foo_https, GetStorageKeyUsage(quota_client, "https://foo.com/", kTemporary)); - EXPECT_EQ(4 + file_paths_cost_persistent_foo, - GetStorageKeyUsage(quota_client, "http://foo.com/", kPersistent)); - EXPECT_EQ(8 + file_paths_cost_temporary_bar, + EXPECT_EQ(8 + file_paths_cost_temporary_bar + + (persistent_quota_is_temporary_quota() + ? 16 + file_paths_cost_persistent_bar + : 0), GetStorageKeyUsage(quota_client, "http://bar.com/", kTemporary)); - EXPECT_EQ(32 + file_paths_cost_persistent_bar_https, - GetStorageKeyUsage(quota_client, "https://bar.com/", kPersistent)); - EXPECT_EQ(64 + file_paths_cost_temporary_bar_https, + EXPECT_EQ(64 + file_paths_cost_temporary_bar_https + + (persistent_quota_is_temporary_quota() + ? 32 + file_paths_cost_persistent_bar_https + : 0), GetStorageKeyUsage(quota_client, "https://bar.com/", kTemporary)); + + if (!persistent_quota_is_temporary_quota()) { + EXPECT_EQ(0, + GetStorageKeyUsage(quota_client, "http://bar.com/", kPersistent)); + EXPECT_EQ(4 + file_paths_cost_persistent_foo, + GetStorageKeyUsage(quota_client, "http://foo.com/", kPersistent)); + EXPECT_EQ( + 32 + file_paths_cost_persistent_bar_https, + GetStorageKeyUsage(quota_client, "https://bar.com/", kPersistent)); + } } +INSTANTIATE_TEST_SUITE_P(FileSystemQuotaClientTests, + FileSystemQuotaClientTest, + testing::Bool()); + } // namespace storage diff --git a/storage/browser/file_system/file_system_util.cc b/storage/browser/file_system/file_system_util.cc index 95b190f68b323c..a32a53f267682a 100644 --- a/storage/browser/file_system/file_system_util.cc +++ b/storage/browser/file_system/file_system_util.cc @@ -4,13 +4,20 @@ #include "storage/browser/file_system/file_system_util.h" +#include "base/feature_list.h" #include "storage/common/file_system/file_system_types.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/mojom/quota/quota_types.mojom.h" namespace storage { blink::mojom::StorageType FileSystemTypeToQuotaStorageType( FileSystemType type) { + if (base::FeatureList::IsEnabled( + blink::features::kPersistentQuotaIsTemporaryQuota) && + (type == kFileSystemTypeTemporary || type == kFileSystemTypePersistent)) { + return blink::mojom::StorageType::kTemporary; + } switch (type) { case kFileSystemTypeTemporary: return blink::mojom::StorageType::kTemporary; diff --git a/storage/browser/quota/quota_features.cc b/storage/browser/quota/quota_features.cc index cfb874fbd0f7be..04985ab9fc0a70 100644 --- a/storage/browser/quota/quota_features.cc +++ b/storage/browser/quota/quota_features.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "storage/browser/quota/quota_features.h" +#include "base/feature_list.h" namespace storage { diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index 7878b143acc232..45905c38073246 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc @@ -1028,5 +1028,8 @@ const base::Feature kDeprecateThirdPartyContextWebSQL{ const base::Feature kSyncLoadDataUrlFonts{"SyncLoadDataUrlFonts", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kPersistentQuotaIsTemporaryQuota{ + "PersistentQuotaIsTemporaryQuota", base::FEATURE_DISABLED_BY_DEFAULT}; + } // namespace features } // namespace blink diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h index c332d6aaf7fa5a..0bb61b65cbf77d 100644 --- a/third_party/blink/public/common/features.h +++ b/third_party/blink/public/common/features.h @@ -446,6 +446,10 @@ BLINK_COMMON_EXPORT extern const base::Feature // Synchronously load web fonts inlined as data urls. See crbug.com/1236283 BLINK_COMMON_EXPORT extern const base::Feature kSyncLoadDataUrlFonts; +// Makes Persistent quota the same as Temporary quota. +BLINK_COMMON_EXPORT +extern const base::Feature kPersistentQuotaIsTemporaryQuota; + } // namespace features } // namespace blink diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index ff289d337d6517..d31712b87241c8 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml @@ -49116,6 +49116,7 @@ from previous Chrome versions. + @@ -49726,6 +49727,7 @@ from previous Chrome versions. +