[go: nahoru, domu]

blob: 82476fcb3cb14c79947d9d6261db495b3730fef5 [file] [log] [blame]
Avi Drissman69b874f2022-09-15 19:11:141// Copyright 2013 The Chromium Authors
Victor Costan78dba6a2021-01-27 17:08:332// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef STORAGE_BROWSER_QUOTA_QUOTA_MANAGER_IMPL_H_
6#define STORAGE_BROWSER_QUOTA_QUOTA_MANAGER_IMPL_H_
7
8#include <stdint.h>
9
Victor Costan78dba6a2021-01-27 17:08:3310#include <map>
11#include <memory>
12#include <set>
13#include <string>
14#include <tuple>
15#include <utility>
16#include <vector>
17
Victor Costan78dba6a2021-01-27 17:08:3318#include "base/component_export.h"
Victor Costan78dba6a2021-01-27 17:08:3319#include "base/files/file_path.h"
Avi Drissman2e85357a2023-01-12 21:57:3220#include "base/functional/callback.h"
Daniel Chengbceeb1f2023-05-11 19:19:3421#include "base/gtest_prod_util.h"
Victor Costan78dba6a2021-01-27 17:08:3322#include "base/memory/ref_counted.h"
23#include "base/memory/ref_counted_delete_on_sequence.h"
24#include "base/memory/weak_ptr.h"
Nathan Memmott65cacb72023-03-15 23:29:1925#include "base/observer_list_types.h"
26#include "base/scoped_observation_traits.h"
Victor Costan78dba6a2021-01-27 17:08:3327#include "base/sequence_checker.h"
28#include "base/time/time.h"
29#include "base/timer/timer.h"
Ayu Ishii71a4d5092021-06-30 21:17:2730#include "components/services/storage/public/cpp/buckets/bucket_info.h"
Evan Stadeac470f52022-05-04 18:29:5031#include "components/services/storage/public/cpp/buckets/bucket_init_params.h"
Ayu Ishii6576e0e2021-10-07 19:33:2532#include "components/services/storage/public/cpp/buckets/bucket_locator.h"
Ayu Ishiid00105632021-05-18 16:31:0333#include "components/services/storage/public/cpp/quota_error_or.h"
Victor Costan78dba6a2021-01-27 17:08:3334#include "components/services/storage/public/mojom/quota_client.mojom.h"
35#include "mojo/public/cpp/bindings/pending_remote.h"
Christine Smith0d90bd4e2021-12-14 03:24:5436#include "mojo/public/cpp/bindings/receiver_set.h"
Victor Costan78dba6a2021-01-27 17:08:3337#include "mojo/public/cpp/bindings/remote.h"
Nathan Memmott65cacb72023-03-15 23:29:1938#include "mojo/public/cpp/bindings/remote_set.h"
Etienne Noel25af2e3d2022-09-20 02:08:5239#include "storage/browser/quota/quota_availability.h"
Victor Costan78dba6a2021-01-27 17:08:3340#include "storage/browser/quota/quota_callbacks.h"
Victor Costan78dba6a2021-01-27 17:08:3341#include "storage/browser/quota/quota_client_type.h"
42#include "storage/browser/quota/quota_database.h"
Christine Smith0d90bd4e2021-12-14 03:24:5443#include "storage/browser/quota/quota_internals.mojom.h"
Nathan Memmott65cacb72023-03-15 23:29:1944#include "storage/browser/quota/quota_manager_observer.mojom.h"
Victor Costan78dba6a2021-01-27 17:08:3345#include "storage/browser/quota/quota_settings.h"
46#include "storage/browser/quota/quota_task.h"
47#include "storage/browser/quota/special_storage_policy.h"
Anton Bikineev3ac3d302021-05-15 17:54:0148#include "third_party/abseil-cpp/absl/types/optional.h"
Ali Beyad8e89cdb2021-06-18 23:00:4349#include "third_party/blink/public/common/storage_key/storage_key.h"
Victor Costan78dba6a2021-01-27 17:08:3350#include "third_party/blink/public/mojom/quota/quota_types.mojom-forward.h"
51#include "third_party/blink/public/mojom/quota/quota_types.mojom-shared.h"
Victor Costan78dba6a2021-01-27 17:08:3352
53namespace base {
54class SequencedTaskRunner;
55class SingleThreadTaskRunner;
56class TaskRunner;
57} // namespace base
58
Victor Costan78dba6a2021-01-27 17:08:3359namespace storage {
60
61class QuotaManagerProxy;
62class QuotaOverrideHandle;
63class QuotaTemporaryStorageEvictor;
64class UsageTracker;
65
66// An interface called by QuotaTemporaryStorageEvictor. This is a grab bag of
67// methods called by QuotaTemporaryStorageEvictor that need to be stubbed for
68// testing.
69class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaEvictionHandler {
70 public:
71 using EvictionRoundInfoCallback =
72 base::OnceCallback<void(blink::mojom::QuotaStatusCode status,
73 const QuotaSettings& settings,
74 int64_t available_space,
75 int64_t total_space,
76 int64_t global_usage,
77 bool global_usage_is_complete)>;
78
Evan Stadebe41d9402022-11-04 00:42:1379 // Deletes all buckets that have explicit expiration dates which have passed.
80 virtual void EvictExpiredBuckets(StatusCallback done) = 0;
81
Victor Costan78dba6a2021-01-27 17:08:3382 // Called at the beginning of an eviction round to gather the info about
83 // the current settings, capacity, and usage.
84 virtual void GetEvictionRoundInfo(EvictionRoundInfoCallback callback) = 0;
85
Ayu Ishii33b9e932021-07-20 17:37:3286 // Returns the next bucket to evict, or nullopt if there are no evictable
87 // buckets.
Evan Stade0f1c8982023-05-08 20:18:0288 virtual void GetEvictionBuckets(int64_t target_usage,
89 GetBucketsCallback callback) = 0;
Victor Costan78dba6a2021-01-27 17:08:3390
Evan Stade0f1c8982023-05-08 20:18:0291 // Called to evict a set of buckets. The callback will be run with the number
92 // of successfully evicted buckets.
93 virtual void EvictBucketData(const std::set<BucketLocator>& buckets,
94 base::OnceCallback<void(int)> callback) = 0;
Victor Costan78dba6a2021-01-27 17:08:3395
96 protected:
97 virtual ~QuotaEvictionHandler() = default;
98};
99
100struct UsageInfo {
101 UsageInfo(std::string host, blink::mojom::StorageType type, int64_t usage)
102 : host(std::move(host)), type(type), usage(usage) {}
103 const std::string host;
104 const blink::mojom::StorageType type;
105 const int64_t usage;
cfredric4b571b92021-08-06 20:48:23106
107 bool operator==(const UsageInfo& that) const {
108 return std::tie(host, usage, type) ==
109 std::tie(that.host, that.usage, that.type);
110 }
111
112 friend std::ostream& operator<<(std::ostream& os,
113 const UsageInfo& usage_info) {
114 return os << "{\"" << usage_info.host << "\", " << usage_info.type << ", "
115 << usage_info.usage << "}";
116 }
Victor Costan78dba6a2021-01-27 17:08:33117};
118
Christine Smith594db882022-04-28 00:30:05119struct AccumulateQuotaInternalsInfo {
120 int64_t total_space = 0;
121 int64_t available_space = 0;
122 int64_t temp_pool_size = 0;
123};
124
Victor Costan78dba6a2021-01-27 17:08:33125// Entry point into the Quota System
126//
Victor Costan5ce69422021-01-27 20:11:16127// Each StoragePartition has exactly one QuotaManagerImpl instance, which
Victor Costan78dba6a2021-01-27 17:08:33128// coordinates quota across the Web platform features subject to quota.
129// Each storage system interacts with quota via their own implementations of
130// the QuotaClient interface.
131//
132// The class sets limits and defines the parameters of the systems heuristics.
Victor Costan5ce69422021-01-27 20:11:16133// QuotaManagerImpl coordinates clients to orchestrate the collection of usage
Victor Costan78dba6a2021-01-27 17:08:33134// information, enforce quota limits, and evict stale data.
135//
136// The constructor and proxy() methods can be called on any thread. All other
137// methods must be called on the IO thread.
Victor Costan5ce69422021-01-27 20:11:16138class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl
Victor Costan78dba6a2021-01-27 17:08:33139 : public QuotaTaskObserver,
140 public QuotaEvictionHandler,
Christine Smith0d90bd4e2021-12-14 03:24:54141 public base::RefCountedDeleteOnSequence<QuotaManagerImpl>,
142 public storage::mojom::QuotaInternalsHandler {
Victor Costan78dba6a2021-01-27 17:08:33143 public:
144 using UsageAndQuotaCallback = base::OnceCallback<
145 void(blink::mojom::QuotaStatusCode, int64_t usage, int64_t quota)>;
146
147 using UsageAndQuotaWithBreakdownCallback =
148 base::OnceCallback<void(blink::mojom::QuotaStatusCode,
149 int64_t usage,
150 int64_t quota,
151 blink::mojom::UsageBreakdownPtr usage_breakdown)>;
152
153 using UsageAndQuotaForDevtoolsCallback =
154 base::OnceCallback<void(blink::mojom::QuotaStatusCode,
155 int64_t usage,
156 int64_t quota,
157 bool is_override_enabled,
158 blink::mojom::UsageBreakdownPtr usage_breakdown)>;
159
160 // Function pointer type used to store the function which returns
161 // information about the volume containing the given FilePath.
Etienne Noel25af2e3d2022-09-20 02:08:52162 // The value returned is the QuotaAvailability struct.
163 using GetVolumeInfoFn = QuotaAvailability (*)(const base::FilePath&);
Victor Costan78dba6a2021-01-27 17:08:33164
165 static constexpr int64_t kGBytes = 1024 * 1024 * 1024;
166 static constexpr int64_t kNoLimit = INT64_MAX;
167 static constexpr int64_t kMBytes = 1024 * 1024;
Evan Stade00acf182023-02-07 00:57:37168
169 // A "typical" amount of usage expected for a bucket. This is used to
170 // dynamically limit the number of buckets that may be created: the quota for
171 // a site divided by this number is an upper bound for the number of buckets
172 // it's allowed.
173 static constexpr int64_t kTypicalBucketUsage = 20 * kMBytes;
174
Victor Costan78dba6a2021-01-27 17:08:33175 static constexpr int kMinutesInMilliSeconds = 60 * 1000;
176
Victor Costan5ce69422021-01-27 20:11:16177 QuotaManagerImpl(bool is_incognito,
178 const base::FilePath& profile_path,
179 scoped_refptr<base::SingleThreadTaskRunner> io_thread,
180 base::RepeatingClosure quota_change_callback,
181 scoped_refptr<SpecialStoragePolicy> special_storage_policy,
182 const GetQuotaSettingsFunc& get_settings_function);
183 QuotaManagerImpl(const QuotaManagerImpl&) = delete;
184 QuotaManagerImpl& operator=(const QuotaManagerImpl&) = delete;
Victor Costan78dba6a2021-01-27 17:08:33185
186 const QuotaSettings& settings() const { return settings_; }
187 void SetQuotaSettings(const QuotaSettings& settings);
188
189 // Returns a proxy object that can be used on any thread.
190 QuotaManagerProxy* proxy() { return proxy_.get(); }
191
Christine Smith0d90bd4e2021-12-14 03:24:54192 void BindInternalsHandler(
193 mojo::PendingReceiver<mojom::QuotaInternalsHandler> receiver);
Ayu Ishii125b5e72022-01-14 02:02:42194
Evan Stade08ebfd8e22022-05-18 21:42:13195 // Gets the bucket with `bucket_name` for the `storage_key` for
196 // StorageType kTemporary and returns the BucketInfo. This may update
197 // expiration and persistence if the existing attributes don't match those
198 // found in `bucket_params`, and may clobber the bucket and rebuild it if it's
199 // expired. If a bucket doesn't exist, a new bucket is created with the
Evan Staded415a0052022-05-21 19:07:23200 // specified policies. If the existing bucket exists but has expired, it will
201 // be clobbered and recreated. Returns a QuotaError if the operation has
202 // failed. This method is declared as virtual to allow test code to override
203 // it.
Evan Stade08ebfd8e22022-05-18 21:42:13204 virtual void UpdateOrCreateBucket(
Evan Stadeac470f52022-05-04 18:29:50205 const BucketInitParams& bucket_params,
Brian Begnochebf8a0052021-10-05 14:18:41206 base::OnceCallback<void(QuotaErrorOr<BucketInfo>)>);
Evan Staded415a0052022-05-21 19:07:23207 // Same as UpdateOrCreateBucket but takes in StorageType. This should only be
Ayu Ishii125b5e72022-01-14 02:02:42208 // used by FileSystem, and is expected to be removed when
209 // StorageType::kSyncable and StorageType::kPersistent are deprecated.
210 // (crbug.com/1233525, crbug.com/1286964).
211 virtual void GetOrCreateBucketDeprecated(
Evan Stade08ebfd8e22022-05-18 21:42:13212 const BucketInitParams& bucket_params,
Ayu Ishii125b5e72022-01-14 02:02:42213 blink::mojom::StorageType storage_type,
214 base::OnceCallback<void(QuotaErrorOr<BucketInfo>)>);
Ayu Ishii38f3b6f2021-06-24 20:35:33215
216 // Creates a bucket for `origin` with `bucket_name` and returns BucketInfo
217 // to the callback. Will return a QuotaError to the callback on operation
218 // failure.
219 //
220 // TODO(crbug.com/1208141): Remove `storage_type` when the only supported
221 // StorageType is kTemporary.
Nathan Eliason970b77562022-06-07 12:57:45222 virtual void CreateBucketForTesting(
Ayu Ishii38f3b6f2021-06-24 20:35:33223 const blink::StorageKey& storage_key,
224 const std::string& bucket_name,
225 blink::mojom::StorageType storage_type,
226 base::OnceCallback<void(QuotaErrorOr<BucketInfo>)>);
Ayu Ishiid00105632021-05-18 16:31:03227
Ali Beyad8e89cdb2021-06-18 23:00:43228 // Retrieves the BucketInfo of the bucket with `bucket_name` for `storage_key`
229 // and returns it to the callback. Will return a QuotaError if the bucket does
Ayu Ishii8c0e50e2021-06-15 16:06:52230 // not exist or on operation failure.
Nathan Memmott9bb3c862023-04-03 22:02:20231 // This SHOULD NOT be used once you have the ID for a bucket. Prefer
232 // GetBucketById.
233 virtual void GetBucketByNameUnsafe(
Evan Stade04985792022-10-14 17:43:42234 const blink::StorageKey& storage_key,
235 const std::string& bucket_name,
236 blink::mojom::StorageType type,
237 base::OnceCallback<void(QuotaErrorOr<BucketInfo>)>);
Ayu Ishiid00105632021-05-18 16:31:03238
Ari Chivukula836085b2022-05-09 21:02:19239 // Retrieves the BucketInfo of the bucket with `bucket_id` and returns it to
240 // the callback. Will return a QuotaError if the bucket does not exist or on
241 // operation failure. This method is declared as virtual to allow test code
242 // to override it.
243 virtual void GetBucketById(
244 const BucketId& bucket_id,
245 base::OnceCallback<void(QuotaErrorOr<BucketInfo>)>);
246
Ayu Ishii2b109c02021-09-15 18:22:45247 // Retrieves all storage keys for `type` that are in the buckets table.
Ayu Ishiib03dcd72021-08-04 01:24:45248 // Used for listing storage keys when showing storage key quota usage.
249 void GetStorageKeysForType(blink::mojom::StorageType type,
250 GetStorageKeysCallback callback);
251
Ayu Ishii2b109c02021-09-15 18:22:45252 // Retrieves all buckets for `type` that are in the buckets table.
253 // Used for retrieving global usage data in the UsageTracker.
254 void GetBucketsForType(
255 blink::mojom::StorageType type,
Evan Stade93753112022-06-13 20:21:07256 base::OnceCallback<void(QuotaErrorOr<std::set<BucketInfo>>)> callback);
Ayu Ishii2b109c02021-09-15 18:22:45257
258 // Retrieves all buckets for `host` and `type` that are in the buckets table.
259 // Used for retrieving host usage data in the UsageTracker.
260 void GetBucketsForHost(
261 const std::string& host,
262 blink::mojom::StorageType type,
Evan Stade93753112022-06-13 20:21:07263 base::OnceCallback<void(QuotaErrorOr<std::set<BucketInfo>>)> callback);
Ayu Ishii2b109c02021-09-15 18:22:45264
265 // Retrieves all buckets for `storage_key` and `type` that are in the buckets
Evan Staded6ceb942022-06-15 20:11:14266 // table. When `delete_expired` is true, the expired buckets will be filtered
267 // out of the reply and also deleted from disk.
Evan Staded5fddb842022-07-20 16:53:39268 virtual void GetBucketsForStorageKey(
Ayu Ishii2b109c02021-09-15 18:22:45269 const blink::StorageKey& storage_key,
270 blink::mojom::StorageType type,
Evan Staded6ceb942022-06-15 20:11:14271 base::OnceCallback<void(QuotaErrorOr<std::set<BucketInfo>>)> callback,
272 bool delete_expired = false);
Ayu Ishii2b109c02021-09-15 18:22:45273
Victor Costan78dba6a2021-01-27 17:08:33274 // Called by clients or webapps. Returns usage per host.
275 void GetUsageInfo(GetUsageInfoCallback callback);
276
277 // Called by Web Apps (deprecated quota API).
278 // This method is declared as virtual to allow test code to override it.
Ayu Ishiie0d51be2022-11-04 18:43:41279 void GetUsageAndQuotaForWebApps(const blink::StorageKey& storage_key,
280 blink::mojom::StorageType type,
281 UsageAndQuotaCallback callback);
Victor Costan78dba6a2021-01-27 17:08:33282
283 // Called by Web Apps (navigator.storage.estimate())
284 // This method is declared as virtual to allow test code to override it.
285 virtual void GetUsageAndQuotaWithBreakdown(
Ali Beyad8e89cdb2021-06-18 23:00:43286 const blink::StorageKey& storage_key,
Victor Costan78dba6a2021-01-27 17:08:33287 blink::mojom::StorageType type,
288 UsageAndQuotaWithBreakdownCallback callback);
289
290 // Called by DevTools.
291 virtual void GetUsageAndQuotaForDevtools(
Ali Beyad8e89cdb2021-06-18 23:00:43292 const blink::StorageKey& storage_key,
Victor Costan78dba6a2021-01-27 17:08:33293 blink::mojom::StorageType type,
294 UsageAndQuotaForDevtoolsCallback callback);
295
296 // Called by storage backends.
297 //
Ali Beyad8e89cdb2021-06-18 23:00:43298 // For UnlimitedStorage storage keys, this version skips usage and quota
299 // handling to avoid extra query cost. Do not call this method for
300 // apps/user-facing code.
Victor Costan78dba6a2021-01-27 17:08:33301 //
302 // This method is declared as virtual to allow test code to override it.
Ali Beyad8e89cdb2021-06-18 23:00:43303 virtual void GetUsageAndQuota(const blink::StorageKey& storage_key,
Victor Costan78dba6a2021-01-27 17:08:33304 blink::mojom::StorageType type,
305 UsageAndQuotaCallback callback);
306
307 // Called by storage backends via proxy.
308 //
Ayu Ishii27092802021-08-06 16:19:15309 // Quota-managed storage backends should call this method when a bucket is
310 // accessed. Used to maintain LRU ordering.
Evan Stadedda5c552022-12-04 23:34:11311 void NotifyBucketAccessed(const BucketLocator& bucket,
312 base::Time access_time);
Victor Costan78dba6a2021-01-27 17:08:33313
314 // Called by storage backends via proxy.
315 //
Ayu Ishii27092802021-08-06 16:19:15316 // Quota-managed storage backends must call this method when they have made
317 // any modifications that change the amount of data stored in a bucket.
Evan Stade98e04e32023-10-19 23:28:56318 // If `delta` is non-null, the cached usage for the bucket and the give client
319 // type will be updated by that amount. A null `delta` value will cause the
320 // cache to instead be discarded, after which it will be lazily recalculated.
Ayu Ishii27092802021-08-06 16:19:15321 void NotifyBucketModified(QuotaClientType client_id,
Evan Stadedda5c552022-12-04 23:34:11322 const BucketLocator& bucket,
Evan Stade98e04e32023-10-19 23:28:56323 absl::optional<int64_t> delta,
Ayu Ishii27092802021-08-06 16:19:15324 base::Time modification_time,
325 base::OnceClosure callback);
326
Victor Costan78dba6a2021-01-27 17:08:33327 // Client storage must call this method whenever they run into disk
328 // write errors. Used as a hint to determine if the storage partition is out
329 // of space, and trigger actions if deemed appropriate.
330 //
331 // This method is declared as virtual to allow test code to override it.
Evan Stadeb7f32242023-04-18 18:03:28332 virtual void OnClientWriteFailed(const blink::StorageKey& storage_key);
Victor Costan78dba6a2021-01-27 17:08:33333
Victor Costan78dba6a2021-01-27 17:08:33334 void SetUsageCacheEnabled(QuotaClientType client_id,
Ali Beyad8e89cdb2021-06-18 23:00:43335 const blink::StorageKey& storage_key,
Victor Costan78dba6a2021-01-27 17:08:33336 blink::mojom::StorageType type,
337 bool enabled);
338
Ayu Ishiiae4a0af2022-02-03 18:34:54339 // Deletes `bucket` data for the specified `quota_client_types`. Pass in
340 // QuotaClientType::AllClients() to remove bucket data for all quota clients.
Victor Costan9bb7ef82022-02-14 18:36:58341 //
342 // `callback` is always called. If this QuotaManager gets destroyed during
343 // deletion, `callback` may be called with a kErrorAbort status.
Ayu Ishiice3a0c62021-10-12 19:11:49344 virtual void DeleteBucketData(const BucketLocator& bucket,
Ayu Ishiib03dcd72021-08-04 01:24:45345 QuotaClientTypes quota_client_types,
346 StatusCallback callback);
Victor Costan9bb7ef82022-02-14 18:36:58347
Ayu Ishiiae4a0af2022-02-03 18:34:54348 // Deletes buckets of a particular blink::mojom::StorageType with storage keys
349 // that match the specified host.
Victor Costan268c325d2022-02-14 19:50:47350 //
351 // `callback` is always called. If this QuotaManager gets destroyed during
352 // deletion, `callback` may be called with a kErrorAbort status.
Evan Stade2774fbed2023-01-26 00:55:56353 // TODO(estade): Consider removing the status code from `callback` as it's
354 // unused outside of tests.
Theodore Olsauskas-Warrena36be262023-07-10 13:21:54355 // TODO(crbug/1456643): DEPRECATED please prefer using `DeleteStorageKeyData`.
356 // This should be removed as part of `CookiesTreeModel` deprecation.
Victor Costan78dba6a2021-01-27 17:08:33357 void DeleteHostData(const std::string& host,
358 blink::mojom::StorageType type,
Victor Costan78dba6a2021-01-27 17:08:33359 StatusCallback callback);
360
Theodore Olsauskas-Warrena36be262023-07-10 13:21:54361 // Deletes buckets of a particular blink::StorageKey.
362 void DeleteStorageKeyData(const blink::StorageKey& storage_key,
363 blink::mojom::StorageType type,
364 StatusCallback callback);
365
Ayu Ishiif7e08782021-08-19 23:57:19366 // Queries QuotaDatabase for the bucket with `storage_key` and `bucket_name`
367 // for StorageType::kTemporary and deletes bucket data for all clients for the
368 // bucket. Used by the Storage Bucket API for bucket deletion. If no bucket is
369 // found, it will return QuotaStatusCode::kOk since it has no bucket data to
370 // delete.
Ayu Ishii24d80db2021-11-17 00:57:10371 virtual void FindAndDeleteBucketData(const blink::StorageKey& storage_key,
372 const std::string& bucket_name,
373 StatusCallback callback);
Ayu Ishiif7e08782021-08-19 23:57:19374
Evan Stade08ebfd8e22022-05-18 21:42:13375 // Updates the expiration for the given bucket.
376 void UpdateBucketExpiration(
377 BucketId bucket,
378 const base::Time& expiration,
379 base::OnceCallback<void(QuotaErrorOr<BucketInfo>)> callback);
380
381 // Updates the persistence bit for the given bucket.
Evan Stade51652532022-05-25 17:11:12382 virtual void UpdateBucketPersistence(
Evan Stade08ebfd8e22022-05-18 21:42:13383 BucketId bucket,
384 bool persistent,
385 base::OnceCallback<void(QuotaErrorOr<BucketInfo>)> callback);
386
Victor Costan78dba6a2021-01-27 17:08:33387 // Instructs each QuotaClient to remove possible traces of deleted
388 // data on the disk.
389 void PerformStorageCleanup(blink::mojom::StorageType type,
390 QuotaClientTypes quota_client_types,
391 base::OnceClosure callback);
392
Christine Smith0d90bd4e2021-12-14 03:24:54393 // storage::mojom::QuotaInternalsHandler implementation
Christine Smith594db882022-04-28 00:30:05394 void GetDiskAvailabilityAndTempPoolSize(
395 GetDiskAvailabilityAndTempPoolSizeCallback callback) override;
Christine Smithd4b43ff2021-12-20 20:56:06396 void GetStatistics(GetStatisticsCallback callback) override;
Christine Smith735e6682022-03-03 19:40:51397 void RetrieveBucketsTable(RetrieveBucketsTableCallback callback) override;
Christine Smithba00b122022-04-11 23:50:16398 void GetGlobalUsageForInternals(
Nathan Memmott65cacb72023-03-15 23:29:19399 blink::mojom::StorageType storage_type,
Christine Smithba00b122022-04-11 23:50:16400 GetGlobalUsageForInternalsCallback callback) override;
Etienne Noelc324f942023-02-23 22:32:28401 // Used from quota-internals page to test behavior of the storage pressure
402 // callback.
403 void SimulateStoragePressure(const url::Origin& origin_url) override;
404 void IsSimulateStoragePressureAvailable(
405 IsSimulateStoragePressureAvailableCallback callback) override;
Christine Smithd4b43ff2021-12-20 20:56:06406
Evan Stadebe41d9402022-11-04 00:42:13407 // QuotaEvictionHandler.
408 void EvictExpiredBuckets(StatusCallback done) override;
Evan Stade0f1c8982023-05-08 20:18:02409 void GetEvictionBuckets(int64_t target_usage,
410 GetBucketsCallback callback) override;
411 void EvictBucketData(const std::set<BucketLocator>& buckets,
412 base::OnceCallback<void(int)> callback) override;
Evan Stadebe41d9402022-11-04 00:42:13413 void GetEvictionRoundInfo(EvictionRoundInfoCallback callback) override;
414
Victor Costan78dba6a2021-01-27 17:08:33415 // Called by UI and internal modules.
Ayu Ishiid2770d22022-01-30 22:38:05416 void GetGlobalUsage(blink::mojom::StorageType type, UsageCallback callback);
Marijn Kruisselbrinkcda41662022-05-13 17:52:35417 void GetStorageKeyUsageWithBreakdown(const blink::StorageKey& storage_key,
418 blink::mojom::StorageType type,
419 UsageWithBreakdownCallback callback);
Ayu Ishii7a7c3682022-05-02 18:57:20420 void GetBucketUsageWithBreakdown(const BucketLocator& bucket,
421 UsageWithBreakdownCallback callback);
Evan Stade4def5a72022-12-06 22:40:43422 void GetBucketUsageAndQuota(BucketId id, UsageAndQuotaCallback callback);
Evan Stade4b188b52023-05-01 22:54:06423 void GetBucketSpaceRemaining(
424 const BucketLocator& bucket,
425 base::OnceCallback<void(QuotaErrorOr<int64_t>)> callback);
Evan Stade9e3ae5982022-05-30 23:46:33426
Ali Beyad8e89cdb2021-06-18 23:00:43427 bool IsStorageUnlimited(const blink::StorageKey& storage_key,
Victor Costan78dba6a2021-01-27 17:08:33428 blink::mojom::StorageType type) const;
429
Evan Stade00acf182023-02-07 00:57:37430 // Calculates the quota for the given storage key, taking into account whether
431 // the storage should be session only for this key. This will return 0 for
432 // unlimited storage situations.
Evan Stade745456c02023-05-02 21:07:57433 // Virtual for testing.
434 virtual int64_t GetQuotaForStorageKey(const blink::StorageKey& storage_key,
435 blink::mojom::StorageType type,
436 const QuotaSettings& settings) const;
Evan Stade00acf182023-02-07 00:57:37437
Ayu Ishiib03dcd72021-08-04 01:24:45438 virtual void GetBucketsModifiedBetween(blink::mojom::StorageType type,
439 base::Time begin,
440 base::Time end,
441 GetBucketsCallback callback);
Victor Costan78dba6a2021-01-27 17:08:33442
443 bool ResetUsageTracker(blink::mojom::StorageType type);
444
445 // Called when StoragePartition is initialized if embedder has an
446 // implementation of StorageNotificationService.
447 void SetStoragePressureCallback(
Evan Stadeb7f32242023-04-18 18:03:28448 base::RepeatingCallback<void(const blink::StorageKey&)>
Ali Beyad8e89cdb2021-06-18 23:00:43449 storage_pressure_callback);
Victor Costan78dba6a2021-01-27 17:08:33450
451 // DevTools Quota Override methods:
452 int GetOverrideHandleId();
Ali Beyad8e89cdb2021-06-18 23:00:43453 void OverrideQuotaForStorageKey(int handle_id,
454 const blink::StorageKey& storage_key,
455 absl::optional<int64_t> quota_size);
Victor Costan78dba6a2021-01-27 17:08:33456 // Called when a DevTools client releases all overrides, however, overrides
Ali Beyad8e89cdb2021-06-18 23:00:43457 // will not be disabled for any storage keys for which there are other
458 // DevTools clients/QuotaOverrideHandle with an active override.
Victor Costan78dba6a2021-01-27 17:08:33459 void WithdrawOverridesForHandle(int handle_id);
460
Victor Costan78dba6a2021-01-27 17:08:33461 static constexpr int kEvictionIntervalInMilliSeconds =
462 30 * kMinutesInMilliSeconds;
463 static constexpr int kThresholdOfErrorsToBeDenylisted = 3;
464 static constexpr int kThresholdRandomizationPercent = 5;
465
466 static constexpr char kDatabaseName[] = "QuotaManager";
Ali Beyad8e89cdb2021-06-18 23:00:43467
Ayu Ishii33b9e932021-07-20 17:37:32468 static constexpr char kEvictedBucketAccessedCountHistogram[] =
469 "Quota.EvictedBucketAccessCount";
470 static constexpr char kEvictedBucketDaysSinceAccessHistogram[] =
471 "Quota.EvictedBucketDaysSinceAccess";
Victor Costan78dba6a2021-01-27 17:08:33472
473 // Kept non-const so that test code can change the value.
474 // TODO(kinuko): Make this a real const value and add a proper way to set
475 // the quota for syncable storage. (http://crbug.com/155488)
Ayu Ishii802a1ee2022-11-30 17:40:19476 static int64_t kSyncableStorageDefaultStorageKeyQuota;
Victor Costan78dba6a2021-01-27 17:08:33477
Victor Costan78dba6a2021-01-27 17:08:33478 void SetGetVolumeInfoFnForTesting(GetVolumeInfoFn fn) {
479 get_volume_info_fn_ = fn;
480 }
481
Ayu Ishii5fcdc572021-08-31 18:18:31482 void SetEvictionDisabledForTesting(bool disable) {
483 eviction_disabled_ = disable;
484 }
485
Victor Costan1f62f902022-03-08 17:13:22486 // Testing support for handling corruption in the underlying database.
487 //
488 // Runs `corrupter` on the same sequence used to do database I/O,
489 // guaranteeing that no other database operation is performed at the same
490 // time. `corrupter` receives the path to the underlying SQLite database as an
491 // argument. The underlying SQLite database is closed while `corrupter` runs,
492 // and reopened afterwards.
493 //
494 // `callback` is called with QuotaError::kNone if the database was
495 // successfully reopened after `corrupter` was run, or with
496 // QuotaError::kDatabaseError otherwise.
497 void CorruptDatabaseForTesting(
498 base::OnceCallback<void(const base::FilePath&)> corrupter,
499 base::OnceCallback<void(QuotaError)> callback);
500
Ayu Ishii5ef84632022-01-10 20:55:32501 void SetBootstrapDisabledForTesting(bool disable) {
502 bootstrap_disabled_for_testing_ = disable;
503 }
504
Marijn Kruisselbrink17af55582022-03-15 02:18:53505 bool is_bootstrapping_database_for_testing() {
506 return is_bootstrapping_database_;
507 }
508
509 bool is_db_disabled_for_testing() { return db_disabled_; }
510
Nathan Memmott65cacb72023-03-15 23:29:19511 void AddObserver(
512 mojo::PendingRemote<storage::mojom::QuotaManagerObserver> observer);
513
Victor Costan78dba6a2021-01-27 17:08:33514 protected:
Victor Costan5ce69422021-01-27 20:11:16515 ~QuotaManagerImpl() override;
Victor Costan78dba6a2021-01-27 17:08:33516 void SetQuotaChangeCallbackForTesting(
517 base::RepeatingClosure storage_pressure_event_callback);
518
519 private:
Victor Costan5ce69422021-01-27 20:11:16520 friend class base::DeleteHelper<QuotaManagerImpl>;
521 friend class base::RefCountedDeleteOnSequence<QuotaManagerImpl>;
Victor Costan78dba6a2021-01-27 17:08:33522 friend class MockQuotaManager;
523 friend class MockQuotaClient;
524 friend class QuotaManagerProxy;
Victor Costan5ce69422021-01-27 20:11:16525 friend class QuotaManagerImplTest;
Victor Costan78dba6a2021-01-27 17:08:33526 friend class QuotaTemporaryStorageEvictor;
Ayu Ishiid2770d22022-01-30 22:38:05527 friend class UsageTrackerTest;
Evan Staded415a0052022-05-21 19:07:23528 FRIEND_TEST_ALL_PREFIXES(QuotaManagerImplTest,
529 UpdateOrCreateBucket_Expiration);
Victor Costan78dba6a2021-01-27 17:08:33530
531 class EvictionRoundInfoHelper;
532 class UsageAndQuotaInfoGatherer;
533 class GetUsageInfoTask;
Ayu Ishii5ef84632022-01-10 20:55:32534 class StorageKeyGathererTask;
Ayu Ishii33b9e932021-07-20 17:37:32535 class BucketDataDeleter;
Evan Stadebe41d9402022-11-04 00:42:13536 class BucketSetDataDeleter;
Ayu Ishii6470d292021-05-05 21:24:41537 class DumpBucketTableHelper;
Victor Costan78dba6a2021-01-27 17:08:33538 class StorageCleanupHelper;
539
540 struct QuotaOverride {
541 QuotaOverride();
542 ~QuotaOverride();
543
544 QuotaOverride(const QuotaOverride& quota_override) = delete;
545 QuotaOverride& operator=(const QuotaOverride&) = delete;
546
547 int64_t quota_size;
548
549 // Keeps track of the DevTools clients that have an active override.
550 std::set<int> active_override_session_ids;
551 };
552
Nathan Memmottfbc8b3c2022-07-20 21:16:49553 using BucketTableEntries = std::vector<mojom::BucketTableEntryPtr>;
Ayu Ishii5ef84632022-01-10 20:55:32554 using StorageKeysByType =
555 base::flat_map<blink::mojom::StorageType, std::set<blink::StorageKey>>;
Victor Costan78dba6a2021-01-27 17:08:33556
557 using QuotaSettingsCallback = base::OnceCallback<void(const QuotaSettings&)>;
558
Nathan Memmottfbc8b3c2022-07-20 21:16:49559 using DumpBucketTableCallback = base::OnceCallback<void(BucketTableEntries)>;
Victor Costan78dba6a2021-01-27 17:08:33560
561 // The values returned total_space, available_space.
562 using StorageCapacityCallback = base::OnceCallback<void(int64_t, int64_t)>;
563
Adithya Srinivasan52e538c6c2021-08-06 18:12:58564 // Lazily called on the IO thread when the first quota manager API is called.
Victor Costan78dba6a2021-01-27 17:08:33565 //
Adithya Srinivasan52e538c6c2021-08-06 18:12:58566 // Initialize() must be called after all quota clients are added to the
567 // manager by RegisterClient().
Victor Costan96a874b2021-08-06 22:40:25568 void EnsureDatabaseOpened();
Ayu Ishii5ef84632022-01-10 20:55:32569
Evan Stadef86c08fe2023-06-22 01:55:17570 // Bootstraps only if it hasn't already happened.
571 void MaybeBootstrapDatabase();
Ayu Ishii5ef84632022-01-10 20:55:32572 // Bootstraps database with storage keys that may not have been registered.
573 // Bootstrapping ensures that there is a bucket entry in the buckets table for
574 // all storage keys that have stored data by quota managed Storage APIs. Will
575 // queue calls to QuotaDatabase during bootstrap to be run after bootstrapping
576 // is complete.
577 void BootstrapDatabase();
578 void DidGetBootstrapFlag(bool is_database_bootstrapped);
579 void DidGetStorageKeysForBootstrap(StorageKeysByType storage_keys_by_type);
580 void DidBootstrapDatabase(QuotaError error);
581 void DidSetDatabaseBootstrapped(QuotaError error);
582 // Runs all callbacks to QuotaDatabase that have been queued during bootstrap.
583 void RunDatabaseCallbacks();
Victor Costan78dba6a2021-01-27 17:08:33584
585 // Called by clients via proxy.
586 // Registers a quota client to the manager.
587 void RegisterClient(
588 mojo::PendingRemote<mojom::QuotaClient> client,
589 QuotaClientType client_type,
590 const std::vector<blink::mojom::StorageType>& storage_types);
591
Victor Costan78dba6a2021-01-27 17:08:33592 UsageTracker* GetUsageTracker(blink::mojom::StorageType type) const;
593
Ayu Ishii6470d292021-05-05 21:24:41594 void DumpBucketTable(DumpBucketTableCallback callback);
Christine Smith594db882022-04-28 00:30:05595 void UpdateQuotaInternalsDiskAvailability(base::OnceClosure barrier_callback,
596 AccumulateQuotaInternalsInfo* info,
597 int64_t total_space,
598 int64_t available_space);
599 void UpdateQuotaInternalsTempPoolSpace(base::OnceClosure barrier_callback,
600 AccumulateQuotaInternalsInfo* info,
601 const QuotaSettings& settings);
602 void FinallySendDiskAvailabilityAndTempPoolSize(
603 GetDiskAvailabilityAndTempPoolSizeCallback callback,
604 std::unique_ptr<AccumulateQuotaInternalsInfo> info);
Christine Smithf52b2ad2022-05-20 21:03:42605 void RetrieveBucketUsageForBucketTable(RetrieveBucketsTableCallback callback,
Nathan Memmottfbc8b3c2022-07-20 21:16:49606 BucketTableEntries entries);
Christine Smithf52b2ad2022-05-20 21:03:42607 void AddBucketTableEntry(
Nathan Memmottfbc8b3c2022-07-20 21:16:49608 mojom::BucketTableEntryPtr entry,
609 base::OnceCallback<void(mojom::BucketTableEntryPtr)> barrier_callback,
Christine Smithf52b2ad2022-05-20 21:03:42610 int64_t usage,
Nathan Memmottfbc8b3c2022-07-20 21:16:49611 blink::mojom::UsageBreakdownPtr bucket_usage_breakdown);
Victor Costan78dba6a2021-01-27 17:08:33612
Ayu Ishii33b9e932021-07-20 17:37:32613 // Runs BucketDataDeleter which calls QuotaClients to clear data for the
614 // bucket. Once the task is complete, calls the QuotaDatabase to delete the
615 // bucket from the bucket table.
Evan Stade2774fbed2023-01-26 00:55:56616 void DeleteBucketDataInternal(
617 const BucketLocator& bucket,
618 QuotaClientTypes quota_client_types,
619 base::OnceCallback<void(QuotaErrorOr<mojom::BucketTableEntryPtr>)>
620 callback);
Victor Costan268c325d2022-02-14 19:50:47621
Evan Stadebe41d9402022-11-04 00:42:13622 // Removes the BucketSetDataDeleter that completed its work.
Victor Costan268c325d2022-02-14 19:50:47623 //
Evan Stadebe41d9402022-11-04 00:42:13624 // This method is static because it must call `callback` even if the
625 // QuotaManagerImpl was destroyed.
626 static void DidDeleteBuckets(base::WeakPtr<QuotaManagerImpl> quota_manager,
627 StatusCallback callback,
628 BucketSetDataDeleter* deleter,
629 blink::mojom::QuotaStatusCode status_code);
Victor Costan9bb7ef82022-02-14 18:36:58630
631 // Removes the BucketDataDeleter that completed its work.
632 //
633 // This method is static because it must call `delete_bucket_data_callback`
634 // even if the QuotaManagerImpl was destroyed.
Evan Stade2774fbed2023-01-26 00:55:56635 static void DidDeleteBucketData(
636 base::WeakPtr<QuotaManagerImpl> quota_manager,
637 base::OnceCallback<void(QuotaErrorOr<mojom::BucketTableEntryPtr>)>
638 callback,
639 BucketDataDeleter* deleter,
640 QuotaErrorOr<mojom::BucketTableEntryPtr> result);
Ayu Ishii33b9e932021-07-20 17:37:32641
Evan Staded415a0052022-05-21 19:07:23642 // Called after bucket data has been deleted from clients as well as the
643 // database due to bucket expiration. This will recreate the bucket in the
644 // database and pass it to `callback`.
645 void DidDeleteBucketForRecreation(
646 const BucketInitParams& params,
647 base::OnceCallback<void(QuotaErrorOr<BucketInfo>)> callback,
648 BucketInfo bucket_info,
Evan Stade2774fbed2023-01-26 00:55:56649 QuotaErrorOr<mojom::BucketTableEntryPtr> result);
Evan Staded415a0052022-05-21 19:07:23650
Evan Stade6c396e92023-05-10 22:19:37651 // Called when the quota database encounters an error.
652 void OnDbError(int error_code);
653
Evan Stadeb7f32242023-04-18 18:03:28654 // Called when the quota database or a quota client run into low disk space
655 // errors.
656 void OnFullDiskError(absl::optional<blink::StorageKey> storage_key);
657
658 // Notifies the embedder that space is too low. This ends up showing a
659 // user-facing dialog in Chrome.
660 void NotifyWriteFailed(const blink::StorageKey& storage_key);
661
Victor Costan78dba6a2021-01-27 17:08:33662 // Methods for eviction logic.
663 void StartEviction();
Evan Stade2774fbed2023-01-26 00:55:56664 void DeleteBucketFromDatabase(
665 const BucketLocator& bucket,
666 bool commit_immediately,
667 base::OnceCallback<void(QuotaErrorOr<mojom::BucketTableEntryPtr>)>
668 callback);
Victor Costan78dba6a2021-01-27 17:08:33669
Evan Stade0f1c8982023-05-08 20:18:02670 // `barrier` should be called with true for a successful eviction or false if
671 // there's an error.
672 void DidEvictBucketData(BucketId evicted_bucket_id,
673 base::RepeatingCallback<void(bool)> barrier,
674 QuotaErrorOr<mojom::BucketTableEntryPtr> entry);
Victor Costan78dba6a2021-01-27 17:08:33675
676 void ReportHistogram();
677 void DidGetTemporaryGlobalUsageForHistogram(int64_t usage,
678 int64_t unlimited_usage);
679 void DidGetStorageCapacityForHistogram(int64_t usage,
680 int64_t total_space,
681 int64_t available_space);
Nathan Memmottfbc8b3c2022-07-20 21:16:49682 void DidDumpBucketTableForHistogram(BucketTableEntries entries);
Victor Costan78dba6a2021-01-27 17:08:33683
Ayu Ishii33b9e932021-07-20 17:37:32684 // Returns the list of bucket ids that should be excluded from eviction due to
685 // consistent errors after multiple attempts.
686 std::set<BucketId> GetEvictionBucketExceptions();
Evan Stade0f1c8982023-05-08 20:18:02687 void DidGetEvictionBuckets(GetBucketsCallback callback,
688 const std::set<BucketLocator>& buckets);
Victor Costan78dba6a2021-01-27 17:08:33689
Ayu Ishiife611112021-09-15 17:37:36690 void DidGetEvictionRoundInfo();
691
Evan Stade0f1c8982023-05-08 20:18:02692 void GetBucketsForEvictionFromDatabase(
693 int64_t target_usage,
694 std::map<BucketLocator, int64_t> usage_map,
695 GetBucketsCallback callback);
Victor Costan78dba6a2021-01-27 17:08:33696
Evan Stade0f1c8982023-05-08 20:18:02697 void DidGetBucketsForEvictionFromDatabase(
698 GetBucketsCallback callback,
699 QuotaErrorOr<std::set<BucketLocator>> result);
Victor Costan78dba6a2021-01-27 17:08:33700 void GetQuotaSettings(QuotaSettingsCallback callback);
Anton Bikineev3ac3d302021-05-15 17:54:01701 void DidGetSettings(absl::optional<QuotaSettings> settings);
Victor Costan78dba6a2021-01-27 17:08:33702 void GetStorageCapacity(StorageCapacityCallback callback);
703 void ContinueIncognitoGetStorageCapacity(const QuotaSettings& settings);
Etienne Noel25af2e3d2022-09-20 02:08:52704 void DidGetStorageCapacity(const QuotaAvailability& total_and_available);
Victor Costan78dba6a2021-01-27 17:08:33705
Evan Stadef86c08fe2023-06-22 01:55:17706 void DidRecoverOrRazeForReBootstrap(bool success);
Victor Costan78dba6a2021-01-27 17:08:33707
Nathan Memmott65cacb72023-03-15 23:29:19708 void NotifyUpdatedBucket(const QuotaErrorOr<BucketInfo>& result);
709 void OnBucketDeleted(
710 base::OnceCallback<void(QuotaErrorOr<mojom::BucketTableEntryPtr>)>
711 callback,
712 QuotaErrorOr<mojom::BucketTableEntryPtr> result);
713
Evan Stade00acf182023-02-07 00:57:37714 void DidGetQuotaSettingsForBucketCreation(
715 const BucketInitParams& bucket_params,
716 base::OnceCallback<void(QuotaErrorOr<BucketInfo>)> callback,
717 const QuotaSettings& settings);
Nathan Memmott65cacb72023-03-15 23:29:19718 void DidGetBucket(bool notify_update_bucket,
719 base::OnceCallback<void(QuotaErrorOr<BucketInfo>)> callback,
Ayu Ishii8c0e50e2021-06-15 16:06:52720 QuotaErrorOr<BucketInfo> result);
Evan Staded415a0052022-05-21 19:07:23721 void DidGetBucketCheckExpiration(
722 const BucketInitParams& params,
723 base::OnceCallback<void(QuotaErrorOr<BucketInfo>)> callback,
724 QuotaErrorOr<BucketInfo> result);
Ayu Ishiif7e08782021-08-19 23:57:19725 void DidGetBucketForDeletion(StatusCallback callback,
726 QuotaErrorOr<BucketInfo> result);
Evan Stade4def5a72022-12-06 22:40:43727 void DidGetBucketForUsageAndQuota(UsageAndQuotaCallback callback,
728 QuotaErrorOr<BucketInfo> result);
Ayu Ishiib03dcd72021-08-04 01:24:45729 void DidGetStorageKeys(GetStorageKeysCallback callback,
730 QuotaErrorOr<std::set<blink::StorageKey>> result);
Ayu Ishii2b109c02021-09-15 18:22:45731 void DidGetBuckets(
Evan Stade93753112022-06-13 20:21:07732 base::OnceCallback<void(QuotaErrorOr<std::set<BucketInfo>>)> callback,
733 QuotaErrorOr<std::set<BucketInfo>> result);
Evan Staded6ceb942022-06-15 20:11:14734 void DidGetBucketsCheckExpiration(
735 base::OnceCallback<void(QuotaErrorOr<std::set<BucketInfo>>)> callback,
736 QuotaErrorOr<std::set<BucketInfo>> result);
Ayu Ishiib03dcd72021-08-04 01:24:45737 void DidGetModifiedBetween(GetBucketsCallback callback,
Ayu Ishiice3a0c62021-10-12 19:11:49738 QuotaErrorOr<std::set<BucketLocator>> result);
Ayu Ishiid00105632021-05-18 16:31:03739
Ali Beyad8e89cdb2021-06-18 23:00:43740 void MaybeRunStoragePressureCallback(const blink::StorageKey& storage_key,
Victor Costan78dba6a2021-01-27 17:08:33741 int64_t total_space,
742 int64_t available_space);
Victor Costan78dba6a2021-01-27 17:08:33743
744 // Evaluates disk statistics to identify storage pressure
745 // (low disk space availability) and starts the storage
746 // pressure event dispatch if appropriate.
747 // TODO(crbug.com/1088004): Implement UsageAndQuotaInfoGatherer::Completed()
748 // to use DetermineStoragePressure().
Victor Costan78dba6a2021-01-27 17:08:33749 void DetermineStoragePressure(int64_t free_space, int64_t total_space);
750
Ali Beyad8e89cdb2021-06-18 23:00:43751 absl::optional<int64_t> GetQuotaOverrideForStorageKey(
752 const blink::StorageKey&);
Victor Costan78dba6a2021-01-27 17:08:33753
Ayu Ishiid00105632021-05-18 16:31:03754 template <typename ValueType>
755 void PostTaskAndReplyWithResultForDBThread(
756 base::OnceCallback<QuotaErrorOr<ValueType>(QuotaDatabase*)> task,
757 base::OnceCallback<void(QuotaErrorOr<ValueType>)> reply,
Ayu Ishii5ef84632022-01-10 20:55:32758 const base::Location& from_here = base::Location::Current(),
759 bool is_bootstrap_task = false);
Ayu Ishiid00105632021-05-18 16:31:03760
Ayu Ishii360505d2021-11-16 17:17:41761 void PostTaskAndReplyWithResultForDBThread(
762 base::OnceCallback<QuotaError(QuotaDatabase*)> task,
763 base::OnceCallback<void(QuotaError)> reply,
Ayu Ishii5ef84632022-01-10 20:55:32764 const base::Location& from_here = base::Location::Current(),
765 bool is_bootstrap_task = false);
Ayu Ishii360505d2021-11-16 17:17:41766
Etienne Noel25af2e3d2022-09-20 02:08:52767 static QuotaAvailability CallGetVolumeInfo(GetVolumeInfoFn get_volume_info_fn,
768 const base::FilePath& path);
769 static QuotaAvailability GetVolumeInfo(const base::FilePath& path);
Victor Costan78dba6a2021-01-27 17:08:33770
771 const bool is_incognito_;
772 const base::FilePath profile_path_;
773
774 // This member is thread-safe. The scoped_refptr is immutable (the object it
775 // points to never changes), and the underlying object is thread-safe.
776 const scoped_refptr<QuotaManagerProxy> proxy_;
777
Ayu Ishii5fcdc572021-08-31 18:18:31778 bool db_disabled_ = false;
779 bool eviction_disabled_ = false;
Ayu Ishii5ef84632022-01-10 20:55:32780 bool bootstrap_disabled_for_testing_ = false;
781
Ali Beyad8e89cdb2021-06-18 23:00:43782 absl::optional<blink::StorageKey>
783 storage_key_for_pending_storage_pressure_callback_;
Victor Costan78dba6a2021-01-27 17:08:33784 scoped_refptr<base::SingleThreadTaskRunner> io_thread_;
785 scoped_refptr<base::SequencedTaskRunner> db_runner_;
Evan Stade7c0e03fe2022-05-31 18:08:14786
787 // QuotaManagerImpl creates `database_` and later schedules it for deletion on
788 // `db_runner_`. Thus, `database_` may outlive `this`.
Arthur Sonzogni0a150732022-11-10 17:22:06789 std::unique_ptr<QuotaDatabase> database_;
Evan Stade7c0e03fe2022-05-31 18:08:14790
Ayu Ishii5ef84632022-01-10 20:55:32791 bool is_bootstrapping_database_ = false;
792 // Queued callbacks to QuotaDatabase that will run after database bootstrap is
793 // complete.
794 std::vector<base::OnceClosure> database_callbacks_;
Victor Costan78dba6a2021-01-27 17:08:33795
796 GetQuotaSettingsFunc get_settings_function_;
797 scoped_refptr<base::TaskRunner> get_settings_task_runner_;
Evan Stadeb7f32242023-04-18 18:03:28798 base::RepeatingCallback<void(const blink::StorageKey&)>
799 storage_pressure_callback_;
Victor Costan78dba6a2021-01-27 17:08:33800 base::RepeatingClosure quota_change_callback_;
801 QuotaSettings settings_;
802 base::TimeTicks settings_timestamp_;
803 std::tuple<base::TimeTicks, int64_t, int64_t>
804 cached_disk_stats_for_storage_pressure_;
805 CallbackQueue<QuotaSettingsCallback, const QuotaSettings&>
806 settings_callbacks_;
807 CallbackQueue<StorageCapacityCallback, int64_t, int64_t>
808 storage_capacity_callbacks_;
809
Evan Stadeb7f32242023-04-18 18:03:28810 // The storage key for the last time a bucket was opened. This is used as an
811 // imperfect estimate of which site may have encountered the last quota
812 // database full disk error.
813 absl::optional<blink::StorageKey> last_opened_bucket_site_;
814
815 // The last time that an eviction round was started due to a full disk error.
816 base::TimeTicks last_full_disk_eviction_time_;
817
Ayu Ishii27092802021-08-06 16:19:15818 // Buckets that have been notified of access during LRU task to exclude from
819 // eviction.
Evan Stadedda5c552022-12-04 23:34:11820 std::set<BucketLocator> access_notified_buckets_;
Victor Costan78dba6a2021-01-27 17:08:33821
Ali Beyad8e89cdb2021-06-18 23:00:43822 std::map<blink::StorageKey, QuotaOverride> devtools_overrides_;
Victor Costan78dba6a2021-01-27 17:08:33823 int next_override_handle_id_ = 0;
824
Christine Smith9f687dd2022-01-27 18:10:43825 // Serve mojo connections for chrome://quota-internals pages.
Christine Smith0d90bd4e2021-12-14 03:24:54826 mojo::ReceiverSet<mojom::QuotaInternalsHandler> internals_handlers_receivers_
827 GUARDED_BY_CONTEXT(sequence_checker_);
828
Victor Costan78dba6a2021-01-27 17:08:33829 // Owns the QuotaClient remotes registered via RegisterClient().
830 //
831 // Iterating over this list is almost always incorrect. Most algorithms should
832 // iterate over an entry in |client_types_|.
833 //
834 // TODO(crbug.com/1016065): Handle Storage Service crashes. Will likely entail
835 // using a mojo::RemoteSet here.
836 std::vector<mojo::Remote<mojom::QuotaClient>> clients_for_ownership_;
837
Victor Costan78dba6a2021-01-27 17:08:33838 // Maps QuotaClient instances to client types.
839 //
840 // The QuotaClient instances pointed to by the map keys are guaranteed to be
841 // alive, because they are owned by `legacy_clients_for_ownership_`.
Victor Costan78dba6a2021-01-27 17:08:33842 base::flat_map<blink::mojom::StorageType,
Victor Costan2200a7a2021-06-18 21:39:27843 base::flat_map<mojom::QuotaClient*, QuotaClientType>>
Victor Costan78dba6a2021-01-27 17:08:33844 client_types_;
845
846 std::unique_ptr<UsageTracker> temporary_usage_tracker_;
Victor Costan78dba6a2021-01-27 17:08:33847 std::unique_ptr<UsageTracker> syncable_usage_tracker_;
848 // TODO(michaeln): Need a way to clear the cache, drop and
849 // reinstantiate the trackers when they're not handling requests.
850
851 std::unique_ptr<QuotaTemporaryStorageEvictor> temporary_storage_evictor_;
Ayu Ishii33b9e932021-07-20 17:37:32852 // Set when there is an eviction task in-flight.
853 bool is_getting_eviction_bucket_ = false;
Victor Costan78dba6a2021-01-27 17:08:33854
Ayu Ishii33b9e932021-07-20 17:37:32855 // Map from bucket id to eviction error count.
856 std::map<BucketId, int> buckets_in_error_;
Victor Costan78dba6a2021-01-27 17:08:33857
858 scoped_refptr<SpecialStoragePolicy> special_storage_policy_;
859
860 base::RepeatingTimer histogram_timer_;
861
862 // Pointer to the function used to get volume information. This is
Victor Costan5ce69422021-01-27 20:11:16863 // overwritten by QuotaManagerImplTest in order to attain deterministic
864 // reported values. The default value points to
865 // QuotaManagerImpl::GetVolumeInfo.
Victor Costan78dba6a2021-01-27 17:08:33866 GetVolumeInfoFn get_volume_info_fn_;
867
Ayu Ishiife611112021-09-15 17:37:36868 std::unique_ptr<EvictionRoundInfoHelper> eviction_helper_;
Evan Stadebe41d9402022-11-04 00:42:13869 std::map<BucketSetDataDeleter*, std::unique_ptr<BucketSetDataDeleter>>
870 bucket_set_data_deleters_;
Ayu Ishii659f4aa22022-01-27 01:06:31871 std::map<BucketDataDeleter*, std::unique_ptr<BucketDataDeleter>>
872 bucket_data_deleters_;
Ayu Ishii5ef84632022-01-10 20:55:32873 std::unique_ptr<StorageKeyGathererTask> storage_key_gatherer_;
Ayu Ishiife611112021-09-15 17:37:36874
Nathan Memmott65cacb72023-03-15 23:29:19875 mojo::RemoteSet<storage::mojom::QuotaManagerObserver> observers_;
876
Victor Costan78dba6a2021-01-27 17:08:33877 SEQUENCE_CHECKER(sequence_checker_);
878
Victor Costan5ce69422021-01-27 20:11:16879 base::WeakPtrFactory<QuotaManagerImpl> weak_factory_{this};
Victor Costan78dba6a2021-01-27 17:08:33880};
881
882} // namespace storage
883
884#endif // STORAGE_BROWSER_QUOTA_QUOTA_MANAGER_IMPL_H_