Skip to content

Commit

Permalink
Make the PERSISTENT filesystem use temporary quota.
Browse files Browse the repository at this point in the history
This CL also adds support in BarrierCallback for running done_callbacks
that take a `const std::vector<T>&` of results, rather than a
std::vector<T>; and also adds support for use with RepeatingCallbacks
whose parameter T is a const and/or reference.

Persistent Quota I2D:
https://groups.google.com/u/1/a/chromium.org/g/blink-dev/c/ziTjKMdOqz8

Bug: 1233525
Change-Id: I005b5b9329692f13a7b16f9bdb8e4be462c6fcc4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3052556
Commit-Queue: Chris Fredrickson <cfredric@chromium.org>
Reviewed-by: Marijn Kruisselbrink <mek@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#913064}
  • Loading branch information
cfredric authored and Chromium LUCI CQ committed Aug 18, 2021
1 parent 514cf8b commit dfcd193
Show file tree
Hide file tree
Showing 12 changed files with 294 additions and 124 deletions.
5 changes: 5 additions & 0 deletions chrome/browser/about_flags.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions chrome/browser/flag-metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -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" ],
Expand Down
6 changes: 6 additions & 0 deletions chrome/browser/flag_descriptions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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.";
Expand Down
3 changes: 3 additions & 0 deletions chrome/browser/flag_descriptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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[];

Expand Down
215 changes: 148 additions & 67 deletions storage/browser/file_system/file_system_quota_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@

#include "storage/browser/file_system/file_system_quota_client.h"

#include <numeric>
#include <string>
#include <utility>
#include <vector>

#include "base/barrier_callback.h"
#include "base/barrier_closure.h"
#include "base/bind.h"
#include "base/check.h"
#include "base/containers/span.h"
#include "base/feature_list.h"
#include "base/files/file.h"
#include "base/location.h"
#include "base/sequence_checker.h"
Expand All @@ -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"
Expand All @@ -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<blink::StorageKey> ToStorageKeys(
const std::vector<url::Origin>& origins) {
std::vector<blink::StorageKey> storage_keys;
Expand All @@ -35,13 +49,53 @@ std::vector<blink::StorageKey> ToStorageKeys(
return storage_keys;
}

std::vector<blink::StorageKey> GetStorageKeysForTypeOnFileTaskRunner(
FileSystemContext* context,
template <typename T>
std::vector<T> MergeWithoutDuplicates(const std::vector<std::vector<T>>& tss) {
if (tss.size() == 1) {
// We assume that each vector contains no duplicates, already.
return tss[0];
}
std::vector<T> merged;
merged.reserve(std::accumulate(
tss.begin(), tss.end(), 0U,
[](size_t acc, const std::vector<T>& ts) { return acc + ts.size(); }));
for (const auto& ts : tss) {
merged.insert(merged.end(), ts.begin(), ts.end());
}
base::ranges::sort(merged);
merged.erase(base::ranges::unique(merged), merged.end());
return merged;
}

// Converts StorageType to the FileSystemTypes that are used for that quota
// type.
base::span<const FileSystemType> QuotaStorageTypeToFileSystemTypes(
blink::mojom::StorageType storage_type) {
FileSystemType type =
FileSystemQuotaClient::QuotaStorageTypeToFileSystemType(storage_type);
DCHECK(type != kFileSystemTypeUnknown);
using StorageType = blink::mojom::StorageType;

if (base::FeatureList::IsEnabled(
blink::features::kPersistentQuotaIsTemporaryQuota)) {
DCHECK_NE(storage_type, StorageType::kPersistent);
if (storage_type == StorageType::kTemporary)
return kTemporaryAndPersistent;
}
switch (storage_type) {
case StorageType::kTemporary:
return kTemporary;
case StorageType::kPersistent:
return kPersistent;
case StorageType::kSyncable:
return kSyncable;
case StorageType::kQuotaNotManaged:
case StorageType::kUnknown:
NOTREACHED();
return {};
}
}

std::vector<blink::StorageKey> GetStorageKeysForTypeOnFileTaskRunner(
FileSystemContext* context,
FileSystemType type) {
FileSystemQuotaUtil* quota_util = context->GetQuotaUtil(type);
if (!quota_util)
return {};
Expand All @@ -50,12 +104,8 @@ std::vector<blink::StorageKey> GetStorageKeysForTypeOnFileTaskRunner(

std::vector<blink::StorageKey> GetStorageKeysForHostOnFileTaskRunner(
FileSystemContext* context,
blink::mojom::StorageType storage_type,
FileSystemType type,
const std::string& host) {
FileSystemType type =
FileSystemQuotaClient::QuotaStorageTypeToFileSystemType(storage_type);
DCHECK(type != kFileSystemTypeUnknown);

FileSystemQuotaUtil* quota_util = context->GetQuotaUtil(type);
if (!quota_util)
return {};
Expand Down Expand Up @@ -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<const FileSystemType> types =
QuotaStorageTypeToFileSystemTypes(storage_type);

FileSystemQuotaUtil* quota_util = file_system_context_->GetQuotaUtil(type);
if (!quota_util) {
std::move(callback).Run(0);
return;
}
base::RepeatingCallback<void(int64_t)> barrier =
base::BarrierCallback<int64_t>(
types.size(), base::BindOnce([](std::vector<int64_t> usages) {
return std::accumulate(usages.begin(), usages.end(),
0U);
}).Then(std::move(callback)));

file_task_runner()->PostTaskAndReplyWithResult(
FROM_HERE,
// It is safe to pass Unretained(quota_util) since context owns it.
base::BindOnce(&FileSystemQuotaUtil::GetOriginUsageOnFileTaskRunner,
base::Unretained(quota_util),
base::RetainedRef(file_system_context_),
storage_key.origin(), type),
std::move(callback));
for (auto type : types) {
FileSystemQuotaUtil* quota_util = file_system_context_->GetQuotaUtil(type);
if (quota_util) {
file_task_runner()->PostTaskAndReplyWithResult(
FROM_HERE,
// It is safe to pass Unretained(quota_util) since context owns it.
base::BindOnce(&FileSystemQuotaUtil::GetOriginUsageOnFileTaskRunner,
base::Unretained(quota_util),
base::RetainedRef(file_system_context_),
storage_key.origin(), type),
barrier);
} else {
barrier.Run(0);
}
}
}

void FileSystemQuotaClient::GetStorageKeysForType(
Expand All @@ -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<const FileSystemType> types =
QuotaStorageTypeToFileSystemTypes(storage_type);

base::RepeatingCallback<void(std::vector<blink::StorageKey>)> barrier =
base::BarrierCallback<std::vector<blink::StorageKey>>(
types.size(),
base::BindOnce(&MergeWithoutDuplicates<blink::StorageKey>)
.Then(std::move(callback)));

for (auto type : types) {
file_task_runner()->PostTaskAndReplyWithResult(
FROM_HERE,
base::BindOnce(&GetStorageKeysForTypeOnFileTaskRunner,
base::RetainedRef(file_system_context_), type),
barrier);
}
}

void FileSystemQuotaClient::GetStorageKeysForHost(
Expand All @@ -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<const FileSystemType> types =
QuotaStorageTypeToFileSystemTypes(storage_type);

base::RepeatingCallback<void(std::vector<blink::StorageKey>)> barrier =
base::BarrierCallback<std::vector<blink::StorageKey>>(
types.size(),
base::BindOnce(&MergeWithoutDuplicates<blink::StorageKey>)
.Then(std::move(callback)));

for (auto type : types) {
file_task_runner()->PostTaskAndReplyWithResult(
FROM_HERE,
base::BindOnce(&GetStorageKeysForHostOnFileTaskRunner,
base::RetainedRef(file_system_context_), type, host),
barrier);
}
}

void FileSystemQuotaClient::DeleteStorageKeyData(
Expand All @@ -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<const FileSystemType> 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<void(blink::mojom::QuotaStatusCode)> barrier =
base::BarrierCallback<blink::mojom::QuotaStatusCode>(
fs_types.size(),
base::BindOnce([](const std::vector<blink::mojom::QuotaStatusCode>&
statuses) {
for (auto status : statuses) {
if (status != blink::mojom::QuotaStatusCode::kOk)
return status;
}
return blink::mojom::QuotaStatusCode::kOk;
}).Then(std::move(callback)));

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(
Expand All @@ -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<const FileSystemType> fs_types =
QuotaStorageTypeToFileSystemTypes(type);

// static
FileSystemType FileSystemQuotaClient::QuotaStorageTypeToFileSystemType(
blink::mojom::StorageType storage_type) {
switch (storage_type) {
case blink::mojom::StorageType::kTemporary:
return kFileSystemTypeTemporary;
case blink::mojom::StorageType::kPersistent:
return kFileSystemTypePersistent;
case blink::mojom::StorageType::kSyncable:
return kFileSystemTypeSyncable;
case blink::mojom::StorageType::kQuotaNotManaged:
case blink::mojom::StorageType::kUnknown:
return kFileSystemTypeUnknown;
base::RepeatingClosure barrier =
base::BarrierClosure(fs_types.size(), std::move(callback));

for (auto fs_type : fs_types) {
file_task_runner()->PostTaskAndReply(
FROM_HERE,
base::BindOnce(&PerformStorageCleanupOnFileTaskRunner,
base::RetainedRef(file_system_context_), fs_type),
barrier);
}
return kFileSystemTypeUnknown;
}

base::SequencedTaskRunner* FileSystemQuotaClient::file_task_runner() const {
Expand Down
8 changes: 0 additions & 8 deletions storage/browser/file_system/file_system_quota_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
Loading

0 comments on commit dfcd193

Please sign in to comment.