Skip to content

Commit

Permalink
Add a QuotaManager observer
Browse files Browse the repository at this point in the history
Adds a QuotaManager observer interface which can be implemented to
listen for quota manager changes. Currently only listens for buckets
being created, updated, or deleted. A mojom version of the interface
has also been added for observers that exist on separate
sequences/processes.

Bug: 1406017
Change-Id: I4d36c74b0be890aa1257ec0127da7b6a603d92e4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4193281
Reviewed-by: Will Harris <wfh@chromium.org>
Reviewed-by: Evan Stade <estade@chromium.org>
Commit-Queue: Nathan Memmott <memmott@chromium.org>
Reviewed-by: Ayu Ishii <ayui@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1117829}
  • Loading branch information
Nathan Memmott authored and Chromium LUCI CQ committed Mar 15, 2023
1 parent 87362ae commit 65cacb7
Show file tree
Hide file tree
Showing 19 changed files with 552 additions and 93 deletions.
1 change: 1 addition & 0 deletions components/services/storage/public/mojom/BUILD.gn
Expand Up @@ -64,6 +64,7 @@ source_set("tests") {
testonly = true
sources = [
"buckets/bucket_id_mojom_traits_unittest.cc",
"buckets/bucket_info_mojom_traits_unittest.cc",
"buckets/bucket_locator_mojom_traits_unittest.cc",
]
deps = [
Expand Down
13 changes: 11 additions & 2 deletions components/services/storage/public/mojom/buckets/BUILD.gn
Expand Up @@ -7,6 +7,7 @@ import("//mojo/public/tools/bindings/mojom.gni")
mojom("buckets") {
sources = [
"bucket_id.mojom",
"bucket_info.mojom",
"bucket_locator.mojom",
]
public_deps = [
Expand All @@ -28,21 +29,29 @@ mojom("buckets") {
nullable_is_same_type = true
copyable_pass_by_value = true
},
{
mojom = "storage.mojom.BucketInfo"
cpp = "::storage::BucketInfo"
},
{
mojom = "storage.mojom.BucketLocator"
cpp = "::storage::BucketLocator"
},
]
traits_headers = [
"bucket_id_mojom_traits.h",
"bucket_info_mojom_traits.h",
"bucket_locator_mojom_traits.h",
]
traits_sources = [
"bucket_id_mojom_traits.cc",
"bucket_info_mojom_traits.cc",
"bucket_locator_mojom_traits.cc",
]
traits_public_deps =
[ "//components/services/storage/public/cpp/buckets" ]
traits_public_deps = [
"//components/services/storage/public/cpp/buckets",
"//third_party/blink/public/mojom/storage_key",
]
},
]

Expand Down
25 changes: 25 additions & 0 deletions components/services/storage/public/mojom/buckets/bucket_info.mojom
@@ -0,0 +1,25 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

module storage.mojom;

import "mojo/public/mojom/base/time.mojom";
import "third_party/blink/public/mojom/storage_key/storage_key.mojom";
import "third_party/blink/public/mojom/quota/quota_types.mojom";

// Snapshot of a bucket's information in the quota database.
//
// Properties that can be updated by the Storage Buckets API, like
// `expiration` and `quota`, may get out of sync with the database. The
// database is the source of truth.
struct BucketInfo {
int64 id;
blink.mojom.StorageKey storage_key;
blink.mojom.StorageType type;
string name;
mojo_base.mojom.Time expiration;
uint64 quota;
bool persistent;
blink.mojom.BucketDurability durability;
};
@@ -0,0 +1,33 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/services/storage/public/mojom/buckets/bucket_info_mojom_traits.h"

#include "third_party/blink/public/common/storage_key/storage_key_mojom_traits.h"

namespace mojo {

// static
bool StructTraits<storage::mojom::BucketInfoDataView, storage::BucketInfo>::
Read(storage::mojom::BucketInfoDataView data, storage::BucketInfo* out) {
blink::StorageKey storage_key;
if (!data.ReadStorageKey(&storage_key)) {
return false;
}
std::string name;
if (!data.ReadName(&name)) {
return false;
}
base::Time expiration;
if (!data.ReadExpiration(&expiration)) {
return false;
}

*out = storage::BucketInfo(storage::BucketId(data.id()), storage_key,
data.type(), name, expiration, data.quota(),
data.persistent(), data.durability());
return true;
}

} // namespace mojo
@@ -0,0 +1,50 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_SERVICES_STORAGE_PUBLIC_MOJOM_BUCKETS_BUCKET_INFO_MOJOM_TRAITS_H_
#define COMPONENTS_SERVICES_STORAGE_PUBLIC_MOJOM_BUCKETS_BUCKET_INFO_MOJOM_TRAITS_H_

#include "components/services/storage/public/cpp/buckets/bucket_info.h"
#include "components/services/storage/public/mojom/buckets/bucket_info.mojom-shared.h"
#include "mojo/public/cpp/bindings/struct_traits.h"

namespace mojo {

template <>
class StructTraits<storage::mojom::BucketInfoDataView, storage::BucketInfo> {
public:
static int64_t id(const storage::BucketInfo& bucket) {
return bucket.id.value();
}
static const blink::StorageKey& storage_key(
const storage::BucketInfo& bucket) {
return bucket.storage_key;
}
static blink::mojom::StorageType type(const storage::BucketInfo& bucket) {
return bucket.type;
}
static base::StringPiece name(const storage::BucketInfo& bucket) {
return base::StringPiece(bucket.name.c_str(), bucket.name.length());
}
static const base::Time& expiration(const storage::BucketInfo& bucket) {
return bucket.expiration;
}
static uint64_t quota(const storage::BucketInfo& bucket) {
return bucket.quota;
}
static bool persistent(const storage::BucketInfo& bucket) {
return bucket.persistent;
}
static blink::mojom::BucketDurability durability(
const storage::BucketInfo& bucket) {
return bucket.durability;
}

static bool Read(storage::mojom::BucketInfoDataView data,
storage::BucketInfo* out);
};

} // namespace mojo

#endif // COMPONENTS_SERVICES_STORAGE_PUBLIC_MOJOM_BUCKETS_BUCKET_INFO_MOJOM_TRAITS_H_
@@ -0,0 +1,48 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/services/storage/public/mojom/buckets/bucket_info_mojom_traits.h"

#include "components/services/storage/public/cpp/buckets/bucket_id.h"
#include "components/services/storage/public/cpp/buckets/bucket_info.h"
#include "components/services/storage/public/cpp/buckets/constants.h"
#include "components/services/storage/public/mojom/buckets/bucket_info.mojom.h"
#include "mojo/public/cpp/test_support/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"

namespace storage {
namespace {

TEST(BucketInfoMojomTraitsTest, SerializeAndDeserialize) {
BucketInfo test_keys[] = {
BucketInfo(
BucketId(1),
blink::StorageKey::CreateFromStringForTesting("http://example/"),
blink::mojom::StorageType::kTemporary, "default", base::Time(), 0,
true, blink::mojom::BucketDurability::kRelaxed),
BucketInfo(
BucketId(123),
blink::StorageKey::CreateFromStringForTesting("http://google.com/"),
blink::mojom::StorageType::kTemporary, "inbox",
base::Time::Now() + base::Days(1), 100, true,
blink::mojom::BucketDurability::kStrict),
BucketInfo(
BucketId(1000),
blink::StorageKey::CreateFromStringForTesting("http://test.com/"),
blink::mojom::StorageType::kTemporary, "drafts",
base::Time::Now() - base::Days(1), 1234, false,
blink::mojom::BucketDurability::kStrict),
};

for (auto& original : test_keys) {
BucketInfo copied;
EXPECT_TRUE(mojo::test::SerializeAndDeserialize<mojom::BucketInfo>(original,
copied));
EXPECT_EQ(original, copied);
}
}

} // namespace
} // namespace storage
11 changes: 8 additions & 3 deletions content/browser/resources/quota/BUILD.gn
Expand Up @@ -17,9 +17,14 @@ build_webui("build") {
"quota_internals_browser_proxy.ts",
]

mojo_files_deps = [ "//storage/browser/quota:mojo_bindings_ts__generator" ]
mojo_files =
[ "$root_gen_dir/storage/browser/quota/quota_internals.mojom-webui.ts" ]
mojo_files_deps = [
"//storage/browser/quota:mojo_bindings_ts__generator",
"//third_party/blink/public/mojom/quota:quota_ts__generator",
]
mojo_files = [
"$root_gen_dir/storage/browser/quota/quota_internals.mojom-webui.ts",
"$root_gen_dir/third_party/blink/public/mojom/quota/quota_types.mojom-webui.ts",
]

ts_tsconfig_base = "tsconfig_base.json"
ts_deps = [
Expand Down
11 changes: 9 additions & 2 deletions storage/browser/quota/BUILD.gn
Expand Up @@ -5,11 +5,18 @@
import("//mojo/public/tools/bindings/mojom.gni")

mojom("mojo_bindings") {
sources = [ "quota_internals.mojom" ]
sources = [
"quota_internals.mojom",
"quota_manager_observer.mojom",
]
webui_module_path = "/"
use_typescript_sources = true

public_deps = [ "//url/mojom:url_mojom_origin" ]
public_deps = [
"//components/services/storage/public/mojom/buckets",
"//third_party/blink/public/mojom/quota",
"//url/mojom:url_mojom_origin",
]

disable_variants = true

Expand Down
3 changes: 1 addition & 2 deletions storage/browser/quota/quota_database.cc
Expand Up @@ -115,8 +115,7 @@ mojom::BucketTableEntryPtr BucketTableEntryFromSqlStatement(
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->type = static_cast<blink::mojom::StorageType>(statement.ColumnInt(2));
entry->name = statement.ColumnString(3);
entry->use_count = statement.ColumnInt(4);
entry->last_accessed = statement.ColumnTime(5);
Expand Down
8 changes: 4 additions & 4 deletions storage/browser/quota/quota_database_unittest.cc
Expand Up @@ -51,10 +51,10 @@ static const blink::mojom::StorageType kTemp =
static const blink::mojom::StorageType kSync =
blink::mojom::StorageType::kSyncable;

static const storage::mojom::StorageType kStorageTemp =
storage::mojom::StorageType::kTemporary;
static const storage::mojom::StorageType kStorageSync =
storage::mojom::StorageType::kSyncable;
static const blink::mojom::StorageType kStorageTemp =
blink::mojom::StorageType::kTemporary;
static const blink::mojom::StorageType kStorageSync =
blink::mojom::StorageType::kSyncable;

static constexpr char kDatabaseName[] = "QuotaManager";

Expand Down
13 changes: 3 additions & 10 deletions storage/browser/quota/quota_internals.mojom
Expand Up @@ -6,27 +6,20 @@ module storage.mojom;

import "mojo/public/mojom/base/time.mojom";
import "url/mojom/origin.mojom";
import "third_party/blink/public/mojom/quota/quota_types.mojom";

// Represents a single Storage Bucket entry.
struct BucketTableEntry {
int64 bucket_id;
string storage_key;
StorageType type;
blink.mojom.StorageType type;
string name;
int64 usage = -1;
int64 use_count;
mojo_base.mojom.Time last_accessed;
mojo_base.mojom.Time last_modified;
};

// Represents the Storage Type for a given host.
// This is a subset of blink::mojom::StorageType.
enum StorageType {
kTemporary = 0,
// kPersistent = 1, DEPRECATED
kSyncable = 2,
};

// Interface for controlling Quota Internals.
// Hosted on "chrome://quota-internals" for WebUI content::QuotaInternalsUI.
interface QuotaInternalsHandler {
Expand All @@ -49,7 +42,7 @@ interface QuotaInternalsHandler {
RetrieveBucketsTable() => (array<BucketTableEntry> entries);

// Returns the global usage and unlimited usage for a given storage type.
GetGlobalUsageForInternals(StorageType storage_type) =>
GetGlobalUsageForInternals(blink.mojom.StorageType storage_type) =>
(int64 usage, int64 unlimited_usage);

// Returns whether simulate storage pressure is available.
Expand Down

0 comments on commit 65cacb7

Please sign in to comment.