Avi Drissman | 69b874f | 2022-09-15 19:11:14 | [diff] [blame] | 1 | // Copyright 2013 The Chromium Authors |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 2 | // 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 Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 10 | #include <map> |
| 11 | #include <memory> |
| 12 | #include <set> |
| 13 | #include <string> |
| 14 | #include <tuple> |
| 15 | #include <utility> |
| 16 | #include <vector> |
| 17 | |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 18 | #include "base/component_export.h" |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 19 | #include "base/files/file_path.h" |
Avi Drissman | 2e85357a | 2023-01-12 21:57:32 | [diff] [blame] | 20 | #include "base/functional/callback.h" |
Daniel Cheng | bceeb1f | 2023-05-11 19:19:34 | [diff] [blame] | 21 | #include "base/gtest_prod_util.h" |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 22 | #include "base/memory/ref_counted.h" |
| 23 | #include "base/memory/ref_counted_delete_on_sequence.h" |
| 24 | #include "base/memory/weak_ptr.h" |
Nathan Memmott | 65cacb7 | 2023-03-15 23:29:19 | [diff] [blame] | 25 | #include "base/observer_list_types.h" |
| 26 | #include "base/scoped_observation_traits.h" |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 27 | #include "base/sequence_checker.h" |
| 28 | #include "base/time/time.h" |
| 29 | #include "base/timer/timer.h" |
Ayu Ishii | 71a4d509 | 2021-06-30 21:17:27 | [diff] [blame] | 30 | #include "components/services/storage/public/cpp/buckets/bucket_info.h" |
Evan Stade | ac470f5 | 2022-05-04 18:29:50 | [diff] [blame] | 31 | #include "components/services/storage/public/cpp/buckets/bucket_init_params.h" |
Ayu Ishii | 6576e0e | 2021-10-07 19:33:25 | [diff] [blame] | 32 | #include "components/services/storage/public/cpp/buckets/bucket_locator.h" |
Ayu Ishii | d0010563 | 2021-05-18 16:31:03 | [diff] [blame] | 33 | #include "components/services/storage/public/cpp/quota_error_or.h" |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 34 | #include "components/services/storage/public/mojom/quota_client.mojom.h" |
| 35 | #include "mojo/public/cpp/bindings/pending_remote.h" |
Christine Smith | 0d90bd4e | 2021-12-14 03:24:54 | [diff] [blame] | 36 | #include "mojo/public/cpp/bindings/receiver_set.h" |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 37 | #include "mojo/public/cpp/bindings/remote.h" |
Nathan Memmott | 65cacb7 | 2023-03-15 23:29:19 | [diff] [blame] | 38 | #include "mojo/public/cpp/bindings/remote_set.h" |
Etienne Noel | 25af2e3d | 2022-09-20 02:08:52 | [diff] [blame] | 39 | #include "storage/browser/quota/quota_availability.h" |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 40 | #include "storage/browser/quota/quota_callbacks.h" |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 41 | #include "storage/browser/quota/quota_client_type.h" |
| 42 | #include "storage/browser/quota/quota_database.h" |
Christine Smith | 0d90bd4e | 2021-12-14 03:24:54 | [diff] [blame] | 43 | #include "storage/browser/quota/quota_internals.mojom.h" |
Nathan Memmott | 65cacb7 | 2023-03-15 23:29:19 | [diff] [blame] | 44 | #include "storage/browser/quota/quota_manager_observer.mojom.h" |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 45 | #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 Bikineev | 3ac3d30 | 2021-05-15 17:54:01 | [diff] [blame] | 48 | #include "third_party/abseil-cpp/absl/types/optional.h" |
Ali Beyad | 8e89cdb | 2021-06-18 23:00:43 | [diff] [blame] | 49 | #include "third_party/blink/public/common/storage_key/storage_key.h" |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 50 | #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 Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 52 | |
| 53 | namespace base { |
| 54 | class SequencedTaskRunner; |
| 55 | class SingleThreadTaskRunner; |
| 56 | class TaskRunner; |
| 57 | } // namespace base |
| 58 | |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 59 | namespace storage { |
| 60 | |
| 61 | class QuotaManagerProxy; |
| 62 | class QuotaOverrideHandle; |
| 63 | class QuotaTemporaryStorageEvictor; |
| 64 | class 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. |
| 69 | class 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 Stade | be41d940 | 2022-11-04 00:42:13 | [diff] [blame] | 79 | // Deletes all buckets that have explicit expiration dates which have passed. |
| 80 | virtual void EvictExpiredBuckets(StatusCallback done) = 0; |
| 81 | |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 82 | // 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 Ishii | 33b9e93 | 2021-07-20 17:37:32 | [diff] [blame] | 86 | // Returns the next bucket to evict, or nullopt if there are no evictable |
| 87 | // buckets. |
Evan Stade | 0f1c898 | 2023-05-08 20:18:02 | [diff] [blame] | 88 | virtual void GetEvictionBuckets(int64_t target_usage, |
| 89 | GetBucketsCallback callback) = 0; |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 90 | |
Evan Stade | 0f1c898 | 2023-05-08 20:18:02 | [diff] [blame] | 91 | // 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 Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 95 | |
| 96 | protected: |
| 97 | virtual ~QuotaEvictionHandler() = default; |
| 98 | }; |
| 99 | |
| 100 | struct 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; |
cfredric | 4b571b9 | 2021-08-06 20:48:23 | [diff] [blame] | 106 | |
| 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 Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 117 | }; |
| 118 | |
Christine Smith | 594db88 | 2022-04-28 00:30:05 | [diff] [blame] | 119 | struct AccumulateQuotaInternalsInfo { |
| 120 | int64_t total_space = 0; |
| 121 | int64_t available_space = 0; |
| 122 | int64_t temp_pool_size = 0; |
| 123 | }; |
| 124 | |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 125 | // Entry point into the Quota System |
| 126 | // |
Victor Costan | 5ce6942 | 2021-01-27 20:11:16 | [diff] [blame] | 127 | // Each StoragePartition has exactly one QuotaManagerImpl instance, which |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 128 | // 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 Costan | 5ce6942 | 2021-01-27 20:11:16 | [diff] [blame] | 133 | // QuotaManagerImpl coordinates clients to orchestrate the collection of usage |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 134 | // 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 Costan | 5ce6942 | 2021-01-27 20:11:16 | [diff] [blame] | 138 | class COMPONENT_EXPORT(STORAGE_BROWSER) QuotaManagerImpl |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 139 | : public QuotaTaskObserver, |
| 140 | public QuotaEvictionHandler, |
Christine Smith | 0d90bd4e | 2021-12-14 03:24:54 | [diff] [blame] | 141 | public base::RefCountedDeleteOnSequence<QuotaManagerImpl>, |
| 142 | public storage::mojom::QuotaInternalsHandler { |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 143 | 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 Noel | 25af2e3d | 2022-09-20 02:08:52 | [diff] [blame] | 162 | // The value returned is the QuotaAvailability struct. |
| 163 | using GetVolumeInfoFn = QuotaAvailability (*)(const base::FilePath&); |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 164 | |
| 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 Stade | 00acf18 | 2023-02-07 00:57:37 | [diff] [blame] | 168 | |
| 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 Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 175 | static constexpr int kMinutesInMilliSeconds = 60 * 1000; |
| 176 | |
Victor Costan | 5ce6942 | 2021-01-27 20:11:16 | [diff] [blame] | 177 | 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 Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 185 | |
| 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 Smith | 0d90bd4e | 2021-12-14 03:24:54 | [diff] [blame] | 192 | void BindInternalsHandler( |
| 193 | mojo::PendingReceiver<mojom::QuotaInternalsHandler> receiver); |
Ayu Ishii | 125b5e7 | 2022-01-14 02:02:42 | [diff] [blame] | 194 | |
Evan Stade | 08ebfd8e2 | 2022-05-18 21:42:13 | [diff] [blame] | 195 | // 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 Stade | d415a005 | 2022-05-21 19:07:23 | [diff] [blame] | 200 | // 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 Stade | 08ebfd8e2 | 2022-05-18 21:42:13 | [diff] [blame] | 204 | virtual void UpdateOrCreateBucket( |
Evan Stade | ac470f5 | 2022-05-04 18:29:50 | [diff] [blame] | 205 | const BucketInitParams& bucket_params, |
Brian Begnoche | bf8a005 | 2021-10-05 14:18:41 | [diff] [blame] | 206 | base::OnceCallback<void(QuotaErrorOr<BucketInfo>)>); |
Evan Stade | d415a005 | 2022-05-21 19:07:23 | [diff] [blame] | 207 | // Same as UpdateOrCreateBucket but takes in StorageType. This should only be |
Ayu Ishii | 125b5e7 | 2022-01-14 02:02:42 | [diff] [blame] | 208 | // 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 Stade | 08ebfd8e2 | 2022-05-18 21:42:13 | [diff] [blame] | 212 | const BucketInitParams& bucket_params, |
Ayu Ishii | 125b5e7 | 2022-01-14 02:02:42 | [diff] [blame] | 213 | blink::mojom::StorageType storage_type, |
| 214 | base::OnceCallback<void(QuotaErrorOr<BucketInfo>)>); |
Ayu Ishii | 38f3b6f | 2021-06-24 20:35:33 | [diff] [blame] | 215 | |
| 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 Eliason | 970b7756 | 2022-06-07 12:57:45 | [diff] [blame] | 222 | virtual void CreateBucketForTesting( |
Ayu Ishii | 38f3b6f | 2021-06-24 20:35:33 | [diff] [blame] | 223 | const blink::StorageKey& storage_key, |
| 224 | const std::string& bucket_name, |
| 225 | blink::mojom::StorageType storage_type, |
| 226 | base::OnceCallback<void(QuotaErrorOr<BucketInfo>)>); |
Ayu Ishii | d0010563 | 2021-05-18 16:31:03 | [diff] [blame] | 227 | |
Ali Beyad | 8e89cdb | 2021-06-18 23:00:43 | [diff] [blame] | 228 | // 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 Ishii | 8c0e50e | 2021-06-15 16:06:52 | [diff] [blame] | 230 | // not exist or on operation failure. |
Nathan Memmott | 9bb3c86 | 2023-04-03 22:02:20 | [diff] [blame] | 231 | // This SHOULD NOT be used once you have the ID for a bucket. Prefer |
| 232 | // GetBucketById. |
| 233 | virtual void GetBucketByNameUnsafe( |
Evan Stade | 0498579 | 2022-10-14 17:43:42 | [diff] [blame] | 234 | const blink::StorageKey& storage_key, |
| 235 | const std::string& bucket_name, |
| 236 | blink::mojom::StorageType type, |
| 237 | base::OnceCallback<void(QuotaErrorOr<BucketInfo>)>); |
Ayu Ishii | d0010563 | 2021-05-18 16:31:03 | [diff] [blame] | 238 | |
Ari Chivukula | 836085b | 2022-05-09 21:02:19 | [diff] [blame] | 239 | // 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 Ishii | 2b109c0 | 2021-09-15 18:22:45 | [diff] [blame] | 247 | // Retrieves all storage keys for `type` that are in the buckets table. |
Ayu Ishii | b03dcd7 | 2021-08-04 01:24:45 | [diff] [blame] | 248 | // Used for listing storage keys when showing storage key quota usage. |
| 249 | void GetStorageKeysForType(blink::mojom::StorageType type, |
| 250 | GetStorageKeysCallback callback); |
| 251 | |
Ayu Ishii | 2b109c0 | 2021-09-15 18:22:45 | [diff] [blame] | 252 | // 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 Stade | 9375311 | 2022-06-13 20:21:07 | [diff] [blame] | 256 | base::OnceCallback<void(QuotaErrorOr<std::set<BucketInfo>>)> callback); |
Ayu Ishii | 2b109c0 | 2021-09-15 18:22:45 | [diff] [blame] | 257 | |
| 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 Stade | 9375311 | 2022-06-13 20:21:07 | [diff] [blame] | 263 | base::OnceCallback<void(QuotaErrorOr<std::set<BucketInfo>>)> callback); |
Ayu Ishii | 2b109c0 | 2021-09-15 18:22:45 | [diff] [blame] | 264 | |
| 265 | // Retrieves all buckets for `storage_key` and `type` that are in the buckets |
Evan Stade | d6ceb94 | 2022-06-15 20:11:14 | [diff] [blame] | 266 | // table. When `delete_expired` is true, the expired buckets will be filtered |
| 267 | // out of the reply and also deleted from disk. |
Evan Stade | d5fddb84 | 2022-07-20 16:53:39 | [diff] [blame] | 268 | virtual void GetBucketsForStorageKey( |
Ayu Ishii | 2b109c0 | 2021-09-15 18:22:45 | [diff] [blame] | 269 | const blink::StorageKey& storage_key, |
| 270 | blink::mojom::StorageType type, |
Evan Stade | d6ceb94 | 2022-06-15 20:11:14 | [diff] [blame] | 271 | base::OnceCallback<void(QuotaErrorOr<std::set<BucketInfo>>)> callback, |
| 272 | bool delete_expired = false); |
Ayu Ishii | 2b109c0 | 2021-09-15 18:22:45 | [diff] [blame] | 273 | |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 274 | // 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 Ishii | e0d51be | 2022-11-04 18:43:41 | [diff] [blame] | 279 | void GetUsageAndQuotaForWebApps(const blink::StorageKey& storage_key, |
| 280 | blink::mojom::StorageType type, |
| 281 | UsageAndQuotaCallback callback); |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 282 | |
| 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 Beyad | 8e89cdb | 2021-06-18 23:00:43 | [diff] [blame] | 286 | const blink::StorageKey& storage_key, |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 287 | blink::mojom::StorageType type, |
| 288 | UsageAndQuotaWithBreakdownCallback callback); |
| 289 | |
| 290 | // Called by DevTools. |
| 291 | virtual void GetUsageAndQuotaForDevtools( |
Ali Beyad | 8e89cdb | 2021-06-18 23:00:43 | [diff] [blame] | 292 | const blink::StorageKey& storage_key, |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 293 | blink::mojom::StorageType type, |
| 294 | UsageAndQuotaForDevtoolsCallback callback); |
| 295 | |
| 296 | // Called by storage backends. |
| 297 | // |
Ali Beyad | 8e89cdb | 2021-06-18 23:00:43 | [diff] [blame] | 298 | // 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 Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 301 | // |
| 302 | // This method is declared as virtual to allow test code to override it. |
Ali Beyad | 8e89cdb | 2021-06-18 23:00:43 | [diff] [blame] | 303 | virtual void GetUsageAndQuota(const blink::StorageKey& storage_key, |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 304 | blink::mojom::StorageType type, |
| 305 | UsageAndQuotaCallback callback); |
| 306 | |
| 307 | // Called by storage backends via proxy. |
| 308 | // |
Ayu Ishii | 2709280 | 2021-08-06 16:19:15 | [diff] [blame] | 309 | // Quota-managed storage backends should call this method when a bucket is |
| 310 | // accessed. Used to maintain LRU ordering. |
Evan Stade | dda5c55 | 2022-12-04 23:34:11 | [diff] [blame] | 311 | void NotifyBucketAccessed(const BucketLocator& bucket, |
| 312 | base::Time access_time); |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 313 | |
| 314 | // Called by storage backends via proxy. |
| 315 | // |
Ayu Ishii | 2709280 | 2021-08-06 16:19:15 | [diff] [blame] | 316 | // 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 Stade | 98e04e3 | 2023-10-19 23:28:56 | [diff] [blame] | 318 | // 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 Ishii | 2709280 | 2021-08-06 16:19:15 | [diff] [blame] | 321 | void NotifyBucketModified(QuotaClientType client_id, |
Evan Stade | dda5c55 | 2022-12-04 23:34:11 | [diff] [blame] | 322 | const BucketLocator& bucket, |
Evan Stade | 98e04e3 | 2023-10-19 23:28:56 | [diff] [blame] | 323 | absl::optional<int64_t> delta, |
Ayu Ishii | 2709280 | 2021-08-06 16:19:15 | [diff] [blame] | 324 | base::Time modification_time, |
| 325 | base::OnceClosure callback); |
| 326 | |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 327 | // 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 Stade | b7f3224 | 2023-04-18 18:03:28 | [diff] [blame] | 332 | virtual void OnClientWriteFailed(const blink::StorageKey& storage_key); |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 333 | |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 334 | void SetUsageCacheEnabled(QuotaClientType client_id, |
Ali Beyad | 8e89cdb | 2021-06-18 23:00:43 | [diff] [blame] | 335 | const blink::StorageKey& storage_key, |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 336 | blink::mojom::StorageType type, |
| 337 | bool enabled); |
| 338 | |
Ayu Ishii | ae4a0af | 2022-02-03 18:34:54 | [diff] [blame] | 339 | // Deletes `bucket` data for the specified `quota_client_types`. Pass in |
| 340 | // QuotaClientType::AllClients() to remove bucket data for all quota clients. |
Victor Costan | 9bb7ef8 | 2022-02-14 18:36:58 | [diff] [blame] | 341 | // |
| 342 | // `callback` is always called. If this QuotaManager gets destroyed during |
| 343 | // deletion, `callback` may be called with a kErrorAbort status. |
Ayu Ishii | ce3a0c6 | 2021-10-12 19:11:49 | [diff] [blame] | 344 | virtual void DeleteBucketData(const BucketLocator& bucket, |
Ayu Ishii | b03dcd7 | 2021-08-04 01:24:45 | [diff] [blame] | 345 | QuotaClientTypes quota_client_types, |
| 346 | StatusCallback callback); |
Victor Costan | 9bb7ef8 | 2022-02-14 18:36:58 | [diff] [blame] | 347 | |
Ayu Ishii | ae4a0af | 2022-02-03 18:34:54 | [diff] [blame] | 348 | // Deletes buckets of a particular blink::mojom::StorageType with storage keys |
| 349 | // that match the specified host. |
Victor Costan | 268c325d | 2022-02-14 19:50:47 | [diff] [blame] | 350 | // |
| 351 | // `callback` is always called. If this QuotaManager gets destroyed during |
| 352 | // deletion, `callback` may be called with a kErrorAbort status. |
Evan Stade | 2774fbed | 2023-01-26 00:55:56 | [diff] [blame] | 353 | // TODO(estade): Consider removing the status code from `callback` as it's |
| 354 | // unused outside of tests. |
Theodore Olsauskas-Warren | a36be26 | 2023-07-10 13:21:54 | [diff] [blame] | 355 | // TODO(crbug/1456643): DEPRECATED please prefer using `DeleteStorageKeyData`. |
| 356 | // This should be removed as part of `CookiesTreeModel` deprecation. |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 357 | void DeleteHostData(const std::string& host, |
| 358 | blink::mojom::StorageType type, |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 359 | StatusCallback callback); |
| 360 | |
Theodore Olsauskas-Warren | a36be26 | 2023-07-10 13:21:54 | [diff] [blame] | 361 | // 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 Ishii | f7e0878 | 2021-08-19 23:57:19 | [diff] [blame] | 366 | // 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 Ishii | 24d80db | 2021-11-17 00:57:10 | [diff] [blame] | 371 | virtual void FindAndDeleteBucketData(const blink::StorageKey& storage_key, |
| 372 | const std::string& bucket_name, |
| 373 | StatusCallback callback); |
Ayu Ishii | f7e0878 | 2021-08-19 23:57:19 | [diff] [blame] | 374 | |
Evan Stade | 08ebfd8e2 | 2022-05-18 21:42:13 | [diff] [blame] | 375 | // 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 Stade | 5165253 | 2022-05-25 17:11:12 | [diff] [blame] | 382 | virtual void UpdateBucketPersistence( |
Evan Stade | 08ebfd8e2 | 2022-05-18 21:42:13 | [diff] [blame] | 383 | BucketId bucket, |
| 384 | bool persistent, |
| 385 | base::OnceCallback<void(QuotaErrorOr<BucketInfo>)> callback); |
| 386 | |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 387 | // 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 Smith | 0d90bd4e | 2021-12-14 03:24:54 | [diff] [blame] | 393 | // storage::mojom::QuotaInternalsHandler implementation |
Christine Smith | 594db88 | 2022-04-28 00:30:05 | [diff] [blame] | 394 | void GetDiskAvailabilityAndTempPoolSize( |
| 395 | GetDiskAvailabilityAndTempPoolSizeCallback callback) override; |
Christine Smith | d4b43ff | 2021-12-20 20:56:06 | [diff] [blame] | 396 | void GetStatistics(GetStatisticsCallback callback) override; |
Christine Smith | 735e668 | 2022-03-03 19:40:51 | [diff] [blame] | 397 | void RetrieveBucketsTable(RetrieveBucketsTableCallback callback) override; |
Christine Smith | ba00b12 | 2022-04-11 23:50:16 | [diff] [blame] | 398 | void GetGlobalUsageForInternals( |
Nathan Memmott | 65cacb7 | 2023-03-15 23:29:19 | [diff] [blame] | 399 | blink::mojom::StorageType storage_type, |
Christine Smith | ba00b12 | 2022-04-11 23:50:16 | [diff] [blame] | 400 | GetGlobalUsageForInternalsCallback callback) override; |
Etienne Noel | c324f94 | 2023-02-23 22:32:28 | [diff] [blame] | 401 | // 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 Smith | d4b43ff | 2021-12-20 20:56:06 | [diff] [blame] | 406 | |
Evan Stade | be41d940 | 2022-11-04 00:42:13 | [diff] [blame] | 407 | // QuotaEvictionHandler. |
| 408 | void EvictExpiredBuckets(StatusCallback done) override; |
Evan Stade | 0f1c898 | 2023-05-08 20:18:02 | [diff] [blame] | 409 | 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 Stade | be41d940 | 2022-11-04 00:42:13 | [diff] [blame] | 413 | void GetEvictionRoundInfo(EvictionRoundInfoCallback callback) override; |
| 414 | |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 415 | // Called by UI and internal modules. |
Ayu Ishii | d2770d2 | 2022-01-30 22:38:05 | [diff] [blame] | 416 | void GetGlobalUsage(blink::mojom::StorageType type, UsageCallback callback); |
Marijn Kruisselbrink | cda4166 | 2022-05-13 17:52:35 | [diff] [blame] | 417 | void GetStorageKeyUsageWithBreakdown(const blink::StorageKey& storage_key, |
| 418 | blink::mojom::StorageType type, |
| 419 | UsageWithBreakdownCallback callback); |
Ayu Ishii | 7a7c368 | 2022-05-02 18:57:20 | [diff] [blame] | 420 | void GetBucketUsageWithBreakdown(const BucketLocator& bucket, |
| 421 | UsageWithBreakdownCallback callback); |
Evan Stade | 4def5a7 | 2022-12-06 22:40:43 | [diff] [blame] | 422 | void GetBucketUsageAndQuota(BucketId id, UsageAndQuotaCallback callback); |
Evan Stade | 4b188b5 | 2023-05-01 22:54:06 | [diff] [blame] | 423 | void GetBucketSpaceRemaining( |
| 424 | const BucketLocator& bucket, |
| 425 | base::OnceCallback<void(QuotaErrorOr<int64_t>)> callback); |
Evan Stade | 9e3ae598 | 2022-05-30 23:46:33 | [diff] [blame] | 426 | |
Ali Beyad | 8e89cdb | 2021-06-18 23:00:43 | [diff] [blame] | 427 | bool IsStorageUnlimited(const blink::StorageKey& storage_key, |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 428 | blink::mojom::StorageType type) const; |
| 429 | |
Evan Stade | 00acf18 | 2023-02-07 00:57:37 | [diff] [blame] | 430 | // 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 Stade | 745456c0 | 2023-05-02 21:07:57 | [diff] [blame] | 433 | // Virtual for testing. |
| 434 | virtual int64_t GetQuotaForStorageKey(const blink::StorageKey& storage_key, |
| 435 | blink::mojom::StorageType type, |
| 436 | const QuotaSettings& settings) const; |
Evan Stade | 00acf18 | 2023-02-07 00:57:37 | [diff] [blame] | 437 | |
Ayu Ishii | b03dcd7 | 2021-08-04 01:24:45 | [diff] [blame] | 438 | virtual void GetBucketsModifiedBetween(blink::mojom::StorageType type, |
| 439 | base::Time begin, |
| 440 | base::Time end, |
| 441 | GetBucketsCallback callback); |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 442 | |
| 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 Stade | b7f3224 | 2023-04-18 18:03:28 | [diff] [blame] | 448 | base::RepeatingCallback<void(const blink::StorageKey&)> |
Ali Beyad | 8e89cdb | 2021-06-18 23:00:43 | [diff] [blame] | 449 | storage_pressure_callback); |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 450 | |
| 451 | // DevTools Quota Override methods: |
| 452 | int GetOverrideHandleId(); |
Ali Beyad | 8e89cdb | 2021-06-18 23:00:43 | [diff] [blame] | 453 | void OverrideQuotaForStorageKey(int handle_id, |
| 454 | const blink::StorageKey& storage_key, |
| 455 | absl::optional<int64_t> quota_size); |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 456 | // Called when a DevTools client releases all overrides, however, overrides |
Ali Beyad | 8e89cdb | 2021-06-18 23:00:43 | [diff] [blame] | 457 | // will not be disabled for any storage keys for which there are other |
| 458 | // DevTools clients/QuotaOverrideHandle with an active override. |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 459 | void WithdrawOverridesForHandle(int handle_id); |
| 460 | |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 461 | 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 Beyad | 8e89cdb | 2021-06-18 23:00:43 | [diff] [blame] | 467 | |
Ayu Ishii | 33b9e93 | 2021-07-20 17:37:32 | [diff] [blame] | 468 | static constexpr char kEvictedBucketAccessedCountHistogram[] = |
| 469 | "Quota.EvictedBucketAccessCount"; |
| 470 | static constexpr char kEvictedBucketDaysSinceAccessHistogram[] = |
| 471 | "Quota.EvictedBucketDaysSinceAccess"; |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 472 | |
| 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 Ishii | 802a1ee | 2022-11-30 17:40:19 | [diff] [blame] | 476 | static int64_t kSyncableStorageDefaultStorageKeyQuota; |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 477 | |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 478 | void SetGetVolumeInfoFnForTesting(GetVolumeInfoFn fn) { |
| 479 | get_volume_info_fn_ = fn; |
| 480 | } |
| 481 | |
Ayu Ishii | 5fcdc57 | 2021-08-31 18:18:31 | [diff] [blame] | 482 | void SetEvictionDisabledForTesting(bool disable) { |
| 483 | eviction_disabled_ = disable; |
| 484 | } |
| 485 | |
Victor Costan | 1f62f90 | 2022-03-08 17:13:22 | [diff] [blame] | 486 | // 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 Ishii | 5ef8463 | 2022-01-10 20:55:32 | [diff] [blame] | 501 | void SetBootstrapDisabledForTesting(bool disable) { |
| 502 | bootstrap_disabled_for_testing_ = disable; |
| 503 | } |
| 504 | |
Marijn Kruisselbrink | 17af5558 | 2022-03-15 02:18:53 | [diff] [blame] | 505 | 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 Memmott | 65cacb7 | 2023-03-15 23:29:19 | [diff] [blame] | 511 | void AddObserver( |
| 512 | mojo::PendingRemote<storage::mojom::QuotaManagerObserver> observer); |
| 513 | |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 514 | protected: |
Victor Costan | 5ce6942 | 2021-01-27 20:11:16 | [diff] [blame] | 515 | ~QuotaManagerImpl() override; |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 516 | void SetQuotaChangeCallbackForTesting( |
| 517 | base::RepeatingClosure storage_pressure_event_callback); |
| 518 | |
| 519 | private: |
Victor Costan | 5ce6942 | 2021-01-27 20:11:16 | [diff] [blame] | 520 | friend class base::DeleteHelper<QuotaManagerImpl>; |
| 521 | friend class base::RefCountedDeleteOnSequence<QuotaManagerImpl>; |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 522 | friend class MockQuotaManager; |
| 523 | friend class MockQuotaClient; |
| 524 | friend class QuotaManagerProxy; |
Victor Costan | 5ce6942 | 2021-01-27 20:11:16 | [diff] [blame] | 525 | friend class QuotaManagerImplTest; |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 526 | friend class QuotaTemporaryStorageEvictor; |
Ayu Ishii | d2770d2 | 2022-01-30 22:38:05 | [diff] [blame] | 527 | friend class UsageTrackerTest; |
Evan Stade | d415a005 | 2022-05-21 19:07:23 | [diff] [blame] | 528 | FRIEND_TEST_ALL_PREFIXES(QuotaManagerImplTest, |
| 529 | UpdateOrCreateBucket_Expiration); |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 530 | |
| 531 | class EvictionRoundInfoHelper; |
| 532 | class UsageAndQuotaInfoGatherer; |
| 533 | class GetUsageInfoTask; |
Ayu Ishii | 5ef8463 | 2022-01-10 20:55:32 | [diff] [blame] | 534 | class StorageKeyGathererTask; |
Ayu Ishii | 33b9e93 | 2021-07-20 17:37:32 | [diff] [blame] | 535 | class BucketDataDeleter; |
Evan Stade | be41d940 | 2022-11-04 00:42:13 | [diff] [blame] | 536 | class BucketSetDataDeleter; |
Ayu Ishii | 6470d29 | 2021-05-05 21:24:41 | [diff] [blame] | 537 | class DumpBucketTableHelper; |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 538 | 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 Memmott | fbc8b3c | 2022-07-20 21:16:49 | [diff] [blame] | 553 | using BucketTableEntries = std::vector<mojom::BucketTableEntryPtr>; |
Ayu Ishii | 5ef8463 | 2022-01-10 20:55:32 | [diff] [blame] | 554 | using StorageKeysByType = |
| 555 | base::flat_map<blink::mojom::StorageType, std::set<blink::StorageKey>>; |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 556 | |
| 557 | using QuotaSettingsCallback = base::OnceCallback<void(const QuotaSettings&)>; |
| 558 | |
Nathan Memmott | fbc8b3c | 2022-07-20 21:16:49 | [diff] [blame] | 559 | using DumpBucketTableCallback = base::OnceCallback<void(BucketTableEntries)>; |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 560 | |
| 561 | // The values returned total_space, available_space. |
| 562 | using StorageCapacityCallback = base::OnceCallback<void(int64_t, int64_t)>; |
| 563 | |
Adithya Srinivasan | 52e538c6c | 2021-08-06 18:12:58 | [diff] [blame] | 564 | // Lazily called on the IO thread when the first quota manager API is called. |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 565 | // |
Adithya Srinivasan | 52e538c6c | 2021-08-06 18:12:58 | [diff] [blame] | 566 | // Initialize() must be called after all quota clients are added to the |
| 567 | // manager by RegisterClient(). |
Victor Costan | 96a874b | 2021-08-06 22:40:25 | [diff] [blame] | 568 | void EnsureDatabaseOpened(); |
Ayu Ishii | 5ef8463 | 2022-01-10 20:55:32 | [diff] [blame] | 569 | |
Evan Stade | f86c08fe | 2023-06-22 01:55:17 | [diff] [blame] | 570 | // Bootstraps only if it hasn't already happened. |
| 571 | void MaybeBootstrapDatabase(); |
Ayu Ishii | 5ef8463 | 2022-01-10 20:55:32 | [diff] [blame] | 572 | // 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 Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 584 | |
| 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 Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 592 | UsageTracker* GetUsageTracker(blink::mojom::StorageType type) const; |
| 593 | |
Ayu Ishii | 6470d29 | 2021-05-05 21:24:41 | [diff] [blame] | 594 | void DumpBucketTable(DumpBucketTableCallback callback); |
Christine Smith | 594db88 | 2022-04-28 00:30:05 | [diff] [blame] | 595 | 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 Smith | f52b2ad | 2022-05-20 21:03:42 | [diff] [blame] | 605 | void RetrieveBucketUsageForBucketTable(RetrieveBucketsTableCallback callback, |
Nathan Memmott | fbc8b3c | 2022-07-20 21:16:49 | [diff] [blame] | 606 | BucketTableEntries entries); |
Christine Smith | f52b2ad | 2022-05-20 21:03:42 | [diff] [blame] | 607 | void AddBucketTableEntry( |
Nathan Memmott | fbc8b3c | 2022-07-20 21:16:49 | [diff] [blame] | 608 | mojom::BucketTableEntryPtr entry, |
| 609 | base::OnceCallback<void(mojom::BucketTableEntryPtr)> barrier_callback, |
Christine Smith | f52b2ad | 2022-05-20 21:03:42 | [diff] [blame] | 610 | int64_t usage, |
Nathan Memmott | fbc8b3c | 2022-07-20 21:16:49 | [diff] [blame] | 611 | blink::mojom::UsageBreakdownPtr bucket_usage_breakdown); |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 612 | |
Ayu Ishii | 33b9e93 | 2021-07-20 17:37:32 | [diff] [blame] | 613 | // 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 Stade | 2774fbed | 2023-01-26 00:55:56 | [diff] [blame] | 616 | void DeleteBucketDataInternal( |
| 617 | const BucketLocator& bucket, |
| 618 | QuotaClientTypes quota_client_types, |
| 619 | base::OnceCallback<void(QuotaErrorOr<mojom::BucketTableEntryPtr>)> |
| 620 | callback); |
Victor Costan | 268c325d | 2022-02-14 19:50:47 | [diff] [blame] | 621 | |
Evan Stade | be41d940 | 2022-11-04 00:42:13 | [diff] [blame] | 622 | // Removes the BucketSetDataDeleter that completed its work. |
Victor Costan | 268c325d | 2022-02-14 19:50:47 | [diff] [blame] | 623 | // |
Evan Stade | be41d940 | 2022-11-04 00:42:13 | [diff] [blame] | 624 | // 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 Costan | 9bb7ef8 | 2022-02-14 18:36:58 | [diff] [blame] | 630 | |
| 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 Stade | 2774fbed | 2023-01-26 00:55:56 | [diff] [blame] | 635 | 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 Ishii | 33b9e93 | 2021-07-20 17:37:32 | [diff] [blame] | 641 | |
Evan Stade | d415a005 | 2022-05-21 19:07:23 | [diff] [blame] | 642 | // 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 Stade | 2774fbed | 2023-01-26 00:55:56 | [diff] [blame] | 649 | QuotaErrorOr<mojom::BucketTableEntryPtr> result); |
Evan Stade | d415a005 | 2022-05-21 19:07:23 | [diff] [blame] | 650 | |
Evan Stade | 6c396e9 | 2023-05-10 22:19:37 | [diff] [blame] | 651 | // Called when the quota database encounters an error. |
| 652 | void OnDbError(int error_code); |
| 653 | |
Evan Stade | b7f3224 | 2023-04-18 18:03:28 | [diff] [blame] | 654 | // 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 Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 662 | // Methods for eviction logic. |
| 663 | void StartEviction(); |
Evan Stade | 2774fbed | 2023-01-26 00:55:56 | [diff] [blame] | 664 | void DeleteBucketFromDatabase( |
| 665 | const BucketLocator& bucket, |
| 666 | bool commit_immediately, |
| 667 | base::OnceCallback<void(QuotaErrorOr<mojom::BucketTableEntryPtr>)> |
| 668 | callback); |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 669 | |
Evan Stade | 0f1c898 | 2023-05-08 20:18:02 | [diff] [blame] | 670 | // `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 Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 675 | |
| 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 Memmott | fbc8b3c | 2022-07-20 21:16:49 | [diff] [blame] | 682 | void DidDumpBucketTableForHistogram(BucketTableEntries entries); |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 683 | |
Ayu Ishii | 33b9e93 | 2021-07-20 17:37:32 | [diff] [blame] | 684 | // 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 Stade | 0f1c898 | 2023-05-08 20:18:02 | [diff] [blame] | 687 | void DidGetEvictionBuckets(GetBucketsCallback callback, |
| 688 | const std::set<BucketLocator>& buckets); |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 689 | |
Ayu Ishii | fe61111 | 2021-09-15 17:37:36 | [diff] [blame] | 690 | void DidGetEvictionRoundInfo(); |
| 691 | |
Evan Stade | 0f1c898 | 2023-05-08 20:18:02 | [diff] [blame] | 692 | void GetBucketsForEvictionFromDatabase( |
| 693 | int64_t target_usage, |
| 694 | std::map<BucketLocator, int64_t> usage_map, |
| 695 | GetBucketsCallback callback); |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 696 | |
Evan Stade | 0f1c898 | 2023-05-08 20:18:02 | [diff] [blame] | 697 | void DidGetBucketsForEvictionFromDatabase( |
| 698 | GetBucketsCallback callback, |
| 699 | QuotaErrorOr<std::set<BucketLocator>> result); |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 700 | void GetQuotaSettings(QuotaSettingsCallback callback); |
Anton Bikineev | 3ac3d30 | 2021-05-15 17:54:01 | [diff] [blame] | 701 | void DidGetSettings(absl::optional<QuotaSettings> settings); |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 702 | void GetStorageCapacity(StorageCapacityCallback callback); |
| 703 | void ContinueIncognitoGetStorageCapacity(const QuotaSettings& settings); |
Etienne Noel | 25af2e3d | 2022-09-20 02:08:52 | [diff] [blame] | 704 | void DidGetStorageCapacity(const QuotaAvailability& total_and_available); |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 705 | |
Evan Stade | f86c08fe | 2023-06-22 01:55:17 | [diff] [blame] | 706 | void DidRecoverOrRazeForReBootstrap(bool success); |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 707 | |
Nathan Memmott | 65cacb7 | 2023-03-15 23:29:19 | [diff] [blame] | 708 | 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 Stade | 00acf18 | 2023-02-07 00:57:37 | [diff] [blame] | 714 | void DidGetQuotaSettingsForBucketCreation( |
| 715 | const BucketInitParams& bucket_params, |
| 716 | base::OnceCallback<void(QuotaErrorOr<BucketInfo>)> callback, |
| 717 | const QuotaSettings& settings); |
Nathan Memmott | 65cacb7 | 2023-03-15 23:29:19 | [diff] [blame] | 718 | void DidGetBucket(bool notify_update_bucket, |
| 719 | base::OnceCallback<void(QuotaErrorOr<BucketInfo>)> callback, |
Ayu Ishii | 8c0e50e | 2021-06-15 16:06:52 | [diff] [blame] | 720 | QuotaErrorOr<BucketInfo> result); |
Evan Stade | d415a005 | 2022-05-21 19:07:23 | [diff] [blame] | 721 | void DidGetBucketCheckExpiration( |
| 722 | const BucketInitParams& params, |
| 723 | base::OnceCallback<void(QuotaErrorOr<BucketInfo>)> callback, |
| 724 | QuotaErrorOr<BucketInfo> result); |
Ayu Ishii | f7e0878 | 2021-08-19 23:57:19 | [diff] [blame] | 725 | void DidGetBucketForDeletion(StatusCallback callback, |
| 726 | QuotaErrorOr<BucketInfo> result); |
Evan Stade | 4def5a7 | 2022-12-06 22:40:43 | [diff] [blame] | 727 | void DidGetBucketForUsageAndQuota(UsageAndQuotaCallback callback, |
| 728 | QuotaErrorOr<BucketInfo> result); |
Ayu Ishii | b03dcd7 | 2021-08-04 01:24:45 | [diff] [blame] | 729 | void DidGetStorageKeys(GetStorageKeysCallback callback, |
| 730 | QuotaErrorOr<std::set<blink::StorageKey>> result); |
Ayu Ishii | 2b109c0 | 2021-09-15 18:22:45 | [diff] [blame] | 731 | void DidGetBuckets( |
Evan Stade | 9375311 | 2022-06-13 20:21:07 | [diff] [blame] | 732 | base::OnceCallback<void(QuotaErrorOr<std::set<BucketInfo>>)> callback, |
| 733 | QuotaErrorOr<std::set<BucketInfo>> result); |
Evan Stade | d6ceb94 | 2022-06-15 20:11:14 | [diff] [blame] | 734 | void DidGetBucketsCheckExpiration( |
| 735 | base::OnceCallback<void(QuotaErrorOr<std::set<BucketInfo>>)> callback, |
| 736 | QuotaErrorOr<std::set<BucketInfo>> result); |
Ayu Ishii | b03dcd7 | 2021-08-04 01:24:45 | [diff] [blame] | 737 | void DidGetModifiedBetween(GetBucketsCallback callback, |
Ayu Ishii | ce3a0c6 | 2021-10-12 19:11:49 | [diff] [blame] | 738 | QuotaErrorOr<std::set<BucketLocator>> result); |
Ayu Ishii | d0010563 | 2021-05-18 16:31:03 | [diff] [blame] | 739 | |
Ali Beyad | 8e89cdb | 2021-06-18 23:00:43 | [diff] [blame] | 740 | void MaybeRunStoragePressureCallback(const blink::StorageKey& storage_key, |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 741 | int64_t total_space, |
| 742 | int64_t available_space); |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 743 | |
| 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 Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 749 | void DetermineStoragePressure(int64_t free_space, int64_t total_space); |
| 750 | |
Ali Beyad | 8e89cdb | 2021-06-18 23:00:43 | [diff] [blame] | 751 | absl::optional<int64_t> GetQuotaOverrideForStorageKey( |
| 752 | const blink::StorageKey&); |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 753 | |
Ayu Ishii | d0010563 | 2021-05-18 16:31:03 | [diff] [blame] | 754 | template <typename ValueType> |
| 755 | void PostTaskAndReplyWithResultForDBThread( |
| 756 | base::OnceCallback<QuotaErrorOr<ValueType>(QuotaDatabase*)> task, |
| 757 | base::OnceCallback<void(QuotaErrorOr<ValueType>)> reply, |
Ayu Ishii | 5ef8463 | 2022-01-10 20:55:32 | [diff] [blame] | 758 | const base::Location& from_here = base::Location::Current(), |
| 759 | bool is_bootstrap_task = false); |
Ayu Ishii | d0010563 | 2021-05-18 16:31:03 | [diff] [blame] | 760 | |
Ayu Ishii | 360505d | 2021-11-16 17:17:41 | [diff] [blame] | 761 | void PostTaskAndReplyWithResultForDBThread( |
| 762 | base::OnceCallback<QuotaError(QuotaDatabase*)> task, |
| 763 | base::OnceCallback<void(QuotaError)> reply, |
Ayu Ishii | 5ef8463 | 2022-01-10 20:55:32 | [diff] [blame] | 764 | const base::Location& from_here = base::Location::Current(), |
| 765 | bool is_bootstrap_task = false); |
Ayu Ishii | 360505d | 2021-11-16 17:17:41 | [diff] [blame] | 766 | |
Etienne Noel | 25af2e3d | 2022-09-20 02:08:52 | [diff] [blame] | 767 | static QuotaAvailability CallGetVolumeInfo(GetVolumeInfoFn get_volume_info_fn, |
| 768 | const base::FilePath& path); |
| 769 | static QuotaAvailability GetVolumeInfo(const base::FilePath& path); |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 770 | |
| 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 Ishii | 5fcdc57 | 2021-08-31 18:18:31 | [diff] [blame] | 778 | bool db_disabled_ = false; |
| 779 | bool eviction_disabled_ = false; |
Ayu Ishii | 5ef8463 | 2022-01-10 20:55:32 | [diff] [blame] | 780 | bool bootstrap_disabled_for_testing_ = false; |
| 781 | |
Ali Beyad | 8e89cdb | 2021-06-18 23:00:43 | [diff] [blame] | 782 | absl::optional<blink::StorageKey> |
| 783 | storage_key_for_pending_storage_pressure_callback_; |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 784 | scoped_refptr<base::SingleThreadTaskRunner> io_thread_; |
| 785 | scoped_refptr<base::SequencedTaskRunner> db_runner_; |
Evan Stade | 7c0e03fe | 2022-05-31 18:08:14 | [diff] [blame] | 786 | |
| 787 | // QuotaManagerImpl creates `database_` and later schedules it for deletion on |
| 788 | // `db_runner_`. Thus, `database_` may outlive `this`. |
Arthur Sonzogni | 0a15073 | 2022-11-10 17:22:06 | [diff] [blame] | 789 | std::unique_ptr<QuotaDatabase> database_; |
Evan Stade | 7c0e03fe | 2022-05-31 18:08:14 | [diff] [blame] | 790 | |
Ayu Ishii | 5ef8463 | 2022-01-10 20:55:32 | [diff] [blame] | 791 | 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 Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 795 | |
| 796 | GetQuotaSettingsFunc get_settings_function_; |
| 797 | scoped_refptr<base::TaskRunner> get_settings_task_runner_; |
Evan Stade | b7f3224 | 2023-04-18 18:03:28 | [diff] [blame] | 798 | base::RepeatingCallback<void(const blink::StorageKey&)> |
| 799 | storage_pressure_callback_; |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 800 | 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 Stade | b7f3224 | 2023-04-18 18:03:28 | [diff] [blame] | 810 | // 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 Ishii | 2709280 | 2021-08-06 16:19:15 | [diff] [blame] | 818 | // Buckets that have been notified of access during LRU task to exclude from |
| 819 | // eviction. |
Evan Stade | dda5c55 | 2022-12-04 23:34:11 | [diff] [blame] | 820 | std::set<BucketLocator> access_notified_buckets_; |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 821 | |
Ali Beyad | 8e89cdb | 2021-06-18 23:00:43 | [diff] [blame] | 822 | std::map<blink::StorageKey, QuotaOverride> devtools_overrides_; |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 823 | int next_override_handle_id_ = 0; |
| 824 | |
Christine Smith | 9f687dd | 2022-01-27 18:10:43 | [diff] [blame] | 825 | // Serve mojo connections for chrome://quota-internals pages. |
Christine Smith | 0d90bd4e | 2021-12-14 03:24:54 | [diff] [blame] | 826 | mojo::ReceiverSet<mojom::QuotaInternalsHandler> internals_handlers_receivers_ |
| 827 | GUARDED_BY_CONTEXT(sequence_checker_); |
| 828 | |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 829 | // 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 Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 838 | // 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 Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 842 | base::flat_map<blink::mojom::StorageType, |
Victor Costan | 2200a7a | 2021-06-18 21:39:27 | [diff] [blame] | 843 | base::flat_map<mojom::QuotaClient*, QuotaClientType>> |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 844 | client_types_; |
| 845 | |
| 846 | std::unique_ptr<UsageTracker> temporary_usage_tracker_; |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 847 | 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 Ishii | 33b9e93 | 2021-07-20 17:37:32 | [diff] [blame] | 852 | // Set when there is an eviction task in-flight. |
| 853 | bool is_getting_eviction_bucket_ = false; |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 854 | |
Ayu Ishii | 33b9e93 | 2021-07-20 17:37:32 | [diff] [blame] | 855 | // Map from bucket id to eviction error count. |
| 856 | std::map<BucketId, int> buckets_in_error_; |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 857 | |
| 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 Costan | 5ce6942 | 2021-01-27 20:11:16 | [diff] [blame] | 863 | // overwritten by QuotaManagerImplTest in order to attain deterministic |
| 864 | // reported values. The default value points to |
| 865 | // QuotaManagerImpl::GetVolumeInfo. |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 866 | GetVolumeInfoFn get_volume_info_fn_; |
| 867 | |
Ayu Ishii | fe61111 | 2021-09-15 17:37:36 | [diff] [blame] | 868 | std::unique_ptr<EvictionRoundInfoHelper> eviction_helper_; |
Evan Stade | be41d940 | 2022-11-04 00:42:13 | [diff] [blame] | 869 | std::map<BucketSetDataDeleter*, std::unique_ptr<BucketSetDataDeleter>> |
| 870 | bucket_set_data_deleters_; |
Ayu Ishii | 659f4aa2 | 2022-01-27 01:06:31 | [diff] [blame] | 871 | std::map<BucketDataDeleter*, std::unique_ptr<BucketDataDeleter>> |
| 872 | bucket_data_deleters_; |
Ayu Ishii | 5ef8463 | 2022-01-10 20:55:32 | [diff] [blame] | 873 | std::unique_ptr<StorageKeyGathererTask> storage_key_gatherer_; |
Ayu Ishii | fe61111 | 2021-09-15 17:37:36 | [diff] [blame] | 874 | |
Nathan Memmott | 65cacb7 | 2023-03-15 23:29:19 | [diff] [blame] | 875 | mojo::RemoteSet<storage::mojom::QuotaManagerObserver> observers_; |
| 876 | |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 877 | SEQUENCE_CHECKER(sequence_checker_); |
| 878 | |
Victor Costan | 5ce6942 | 2021-01-27 20:11:16 | [diff] [blame] | 879 | base::WeakPtrFactory<QuotaManagerImpl> weak_factory_{this}; |
Victor Costan | 78dba6a | 2021-01-27 17:08:33 | [diff] [blame] | 880 | }; |
| 881 | |
| 882 | } // namespace storage |
| 883 | |
| 884 | #endif // STORAGE_BROWSER_QUOTA_QUOTA_MANAGER_IMPL_H_ |