1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef STORAGE_BROWSER_QUOTA_QUOTA_MANAGER_H_
6 #define STORAGE_BROWSER_QUOTA_QUOTA_MANAGER_H_
16 #include "base/basictypes.h"
17 #include "base/callback.h"
18 #include "base/files/file_path.h"
19 #include "base/memory/ref_counted.h"
20 #include "base/memory/scoped_ptr.h"
21 #include "base/memory/weak_ptr.h"
22 #include "base/sequenced_task_runner_helpers.h"
23 #include "storage/browser/quota/quota_callbacks.h"
24 #include "storage/browser/quota/quota_client.h"
25 #include "storage/browser/quota/quota_database.h"
26 #include "storage/browser/quota/quota_task.h"
27 #include "storage/browser/quota/special_storage_policy.h"
28 #include "storage/browser/quota/storage_observer.h"
29 #include "storage/browser/storage_browser_export.h"
33 class SequencedTaskRunner;
34 class SingleThreadTaskRunner;
37 namespace quota_internals {
38 class QuotaInternalsProxy;
42 class MockQuotaManager;
43 class MockStorageClient;
44 class QuotaManagerTest;
45 class StorageMonitorTest;
52 class QuotaManagerProxy;
53 class QuotaTemporaryStorageEvictor;
57 struct QuotaManagerDeleter;
59 struct STORAGE_EXPORT UsageAndQuota {
61 int64 global_limited_usage;
63 int64 available_disk_space;
66 UsageAndQuota(int64 usage,
67 int64 global_limited_usage,
69 int64 available_disk_space);
72 // An interface called by QuotaTemporaryStorageEvictor.
73 class STORAGE_EXPORT QuotaEvictionHandler {
75 typedef base::Callback<void(const GURL&)> GetLRUOriginCallback;
76 typedef StatusCallback EvictOriginDataCallback;
77 typedef base::Callback<void(QuotaStatusCode status,
78 const UsageAndQuota& usage_and_quota)>
79 UsageAndQuotaCallback;
81 // Returns the least recently used origin. It might return empty
82 // GURL when there are no evictable origins.
83 virtual void GetLRUOrigin(
85 const GetLRUOriginCallback& callback) = 0;
87 virtual void EvictOriginData(
90 const EvictOriginDataCallback& callback) = 0;
92 virtual void GetUsageAndQuotaForEviction(
93 const UsageAndQuotaCallback& callback) = 0;
96 virtual ~QuotaEvictionHandler() {}
100 UsageInfo(const std::string& host, StorageType type, int64 usage)
109 // The quota manager class. This class is instantiated per profile and
110 // held by the profile. With the exception of the constructor and the
111 // proxy() method, all methods should only be called on the IO thread.
112 class STORAGE_EXPORT QuotaManager
113 : public QuotaTaskObserver,
114 public QuotaEvictionHandler,
115 public base::RefCountedThreadSafe<QuotaManager, QuotaManagerDeleter> {
117 typedef base::Callback<void(QuotaStatusCode,
120 GetUsageAndQuotaCallback;
122 static const int64 kIncognitoDefaultQuotaLimit;
123 static const int64 kNoLimit;
127 const base::FilePath& profile_path,
128 const scoped_refptr<base::SingleThreadTaskRunner>& io_thread,
129 const scoped_refptr<base::SequencedTaskRunner>& db_thread,
130 const scoped_refptr<SpecialStoragePolicy>& special_storage_policy);
132 // Returns a proxy object that can be used on any thread.
133 QuotaManagerProxy* proxy() { return proxy_.get(); }
135 // Called by clients or webapps. Returns usage per host.
136 void GetUsageInfo(const GetUsageInfoCallback& callback);
138 // Called by Web Apps.
139 // This method is declared as virtual to allow test code to override it.
140 virtual void GetUsageAndQuotaForWebApps(
143 const GetUsageAndQuotaCallback& callback);
145 // Called by StorageClients.
146 // This method is declared as virtual to allow test code to override it.
148 // For UnlimitedStorage origins, this version skips usage and quota handling
149 // to avoid extra query cost.
150 // Do not call this method for apps/user-facing code.
151 virtual void GetUsageAndQuota(
154 const GetUsageAndQuotaCallback& callback);
156 // Called by clients via proxy.
157 // Client storage should call this method when storage is accessed.
158 // Used to maintain LRU ordering.
159 void NotifyStorageAccessed(QuotaClient::ID client_id,
163 // Called by clients via proxy.
164 // Client storage must call this method whenever they have made any
165 // modifications that change the amount of data stored in their storage.
166 void NotifyStorageModified(QuotaClient::ID client_id,
171 // Used to avoid evicting origins with open pages.
172 // A call to NotifyOriginInUse must be balanced by a later call
173 // to NotifyOriginNoLongerInUse.
174 void NotifyOriginInUse(const GURL& origin);
175 void NotifyOriginNoLongerInUse(const GURL& origin);
176 bool IsOriginInUse(const GURL& origin) const {
177 return origins_in_use_.find(origin) != origins_in_use_.end();
180 void SetUsageCacheEnabled(QuotaClient::ID client_id,
185 // DeleteOriginData and DeleteHostData (surprisingly enough) delete data of a
186 // particular StorageType associated with either a specific origin or set of
187 // origins. Each method additionally requires a |quota_client_mask| which
188 // specifies the types of QuotaClients to delete from the origin. This is
189 // specified by the caller as a bitmask built from QuotaClient::IDs. Setting
190 // the mask to QuotaClient::kAllClientsMask will remove all clients from the
191 // origin, regardless of type.
192 virtual void DeleteOriginData(const GURL& origin,
194 int quota_client_mask,
195 const StatusCallback& callback);
196 void DeleteHostData(const std::string& host,
198 int quota_client_mask,
199 const StatusCallback& callback);
201 // Called by UI and internal modules.
202 void GetAvailableSpace(const AvailableSpaceCallback& callback);
203 void GetTemporaryGlobalQuota(const QuotaCallback& callback);
205 // Ok to call with NULL callback.
206 void SetTemporaryGlobalOverrideQuota(int64 new_quota,
207 const QuotaCallback& callback);
209 void GetPersistentHostQuota(const std::string& host,
210 const QuotaCallback& callback);
211 void SetPersistentHostQuota(const std::string& host,
213 const QuotaCallback& callback);
214 void GetGlobalUsage(StorageType type, const GlobalUsageCallback& callback);
215 void GetHostUsage(const std::string& host, StorageType type,
216 const UsageCallback& callback);
217 void GetHostUsage(const std::string& host, StorageType type,
218 QuotaClient::ID client_id,
219 const UsageCallback& callback);
221 bool IsTrackingHostUsage(StorageType type, QuotaClient::ID client_id) const;
223 void GetStatistics(std::map<std::string, std::string>* statistics);
225 bool IsStorageUnlimited(const GURL& origin, StorageType type) const;
227 bool CanQueryDiskSize(const GURL& origin) const {
228 return special_storage_policy_.get() &&
229 special_storage_policy_->CanQueryDiskSize(origin);
232 virtual void GetOriginsModifiedSince(StorageType type,
233 base::Time modified_since,
234 const GetOriginsCallback& callback);
236 bool ResetUsageTracker(StorageType type);
238 // Used to register/deregister observers that wish to monitor storage events.
239 void AddStorageObserver(StorageObserver* observer,
240 const StorageObserver::MonitorParams& params);
241 void RemoveStorageObserver(StorageObserver* observer);
242 void RemoveStorageObserverForFilter(StorageObserver* observer,
243 const StorageObserver::Filter& filter);
245 // Determines the portion of the temp pool that can be
246 // utilized by a single host (ie. 5 for 20%).
247 static const int kPerHostTemporaryPortion;
249 static const int64 kPerHostPersistentQuotaLimit;
251 static const char kDatabaseName[];
253 static const int kThresholdOfErrorsToBeBlacklisted;
255 static const int kEvictionIntervalInMilliSeconds;
257 // These are kept non-const so that test code can change the value.
258 // TODO(kinuko): Make this a real const value and add a proper way to set
259 // the quota for syncable storage. (http://crbug.com/155488)
260 static int64 kMinimumPreserveForSystem;
261 static int64 kSyncableStorageDefaultHostQuota;
264 virtual ~QuotaManager();
267 friend class base::DeleteHelper<QuotaManager>;
268 friend class base::RefCountedThreadSafe<QuotaManager, QuotaManagerDeleter>;
269 friend class content::QuotaManagerTest;
270 friend class content::StorageMonitorTest;
271 friend class content::MockQuotaManager;
272 friend class content::MockStorageClient;
273 friend class quota_internals::QuotaInternalsProxy;
274 friend class QuotaManagerProxy;
275 friend class QuotaTemporaryStorageEvictor;
276 friend struct QuotaManagerDeleter;
278 class GetUsageInfoTask;
280 class OriginDataDeleter;
281 class HostDataDeleter;
283 class GetModifiedSinceHelper;
284 class DumpQuotaTableHelper;
285 class DumpOriginInfoTableHelper;
287 typedef QuotaDatabase::QuotaTableEntry QuotaTableEntry;
288 typedef QuotaDatabase::OriginInfoTableEntry OriginInfoTableEntry;
289 typedef std::vector<QuotaTableEntry> QuotaTableEntries;
290 typedef std::vector<OriginInfoTableEntry> OriginInfoTableEntries;
292 // Function pointer type used to store the function which returns the
293 // available disk space for the disk containing the given FilePath.
294 typedef int64 (*GetAvailableDiskSpaceFn)(const base::FilePath&);
296 typedef base::Callback<void(const QuotaTableEntries&)>
297 DumpQuotaTableCallback;
298 typedef base::Callback<void(const OriginInfoTableEntries&)>
299 DumpOriginInfoTableCallback;
301 struct EvictionContext {
303 virtual ~EvictionContext();
305 StorageType evicted_type;
307 EvictOriginDataCallback evict_origin_data_callback;
310 typedef QuotaEvictionHandler::UsageAndQuotaCallback
311 UsageAndQuotaDispatcherCallback;
313 // This initialization method is lazily called on the IO thread
314 // when the first quota manager API is called.
315 // Initialize must be called after all quota clients are added to the
316 // manager by RegisterStorage.
317 void LazyInitialize();
319 // Called by clients via proxy.
320 // Registers a quota client to the manager.
321 // The client must remain valid until OnQuotaManagerDestored is called.
322 void RegisterClient(QuotaClient* client);
324 UsageTracker* GetUsageTracker(StorageType type) const;
326 // Extract cached origins list from the usage tracker.
327 // (Might return empty list if no origin is tracked by the tracker.)
328 void GetCachedOrigins(StorageType type, std::set<GURL>* origins);
330 // These internal methods are separately defined mainly for testing.
331 void NotifyStorageAccessedInternal(
332 QuotaClient::ID client_id,
335 base::Time accessed_time);
336 void NotifyStorageModifiedInternal(
337 QuotaClient::ID client_id,
341 base::Time modified_time);
343 void DumpQuotaTable(const DumpQuotaTableCallback& callback);
344 void DumpOriginInfoTable(const DumpOriginInfoTableCallback& callback);
346 // Methods for eviction logic.
347 void StartEviction();
348 void DeleteOriginFromDatabase(const GURL& origin, StorageType type);
350 void DidOriginDataEvicted(QuotaStatusCode status);
352 void ReportHistogram();
353 void DidGetTemporaryGlobalUsageForHistogram(int64 usage,
354 int64 unlimited_usage);
355 void DidGetPersistentGlobalUsageForHistogram(int64 usage,
356 int64 unlimited_usage);
358 // QuotaEvictionHandler.
359 virtual void GetLRUOrigin(
361 const GetLRUOriginCallback& callback) OVERRIDE;
362 virtual void EvictOriginData(
365 const EvictOriginDataCallback& callback) OVERRIDE;
366 virtual void GetUsageAndQuotaForEviction(
367 const UsageAndQuotaCallback& callback) OVERRIDE;
369 void DidSetTemporaryGlobalOverrideQuota(const QuotaCallback& callback,
370 const int64* new_quota,
372 void DidGetPersistentHostQuota(const std::string& host,
375 void DidSetPersistentHostQuota(const std::string& host,
376 const QuotaCallback& callback,
377 const int64* new_quota,
379 void DidInitialize(int64* temporary_quota_override,
380 int64* desired_available_space,
382 void DidGetLRUOrigin(const GURL* origin,
384 void DidGetInitialTemporaryGlobalQuota(QuotaStatusCode status,
386 void DidInitializeTemporaryOriginsInfo(bool success);
387 void DidGetAvailableSpace(int64 space);
388 void DidDatabaseWork(bool success);
390 void DeleteOnCorrectThread() const;
392 void PostTaskAndReplyWithResultForDBThread(
393 const tracked_objects::Location& from_here,
394 const base::Callback<bool(QuotaDatabase*)>& task,
395 const base::Callback<void(bool)>& reply);
397 const bool is_incognito_;
398 const base::FilePath profile_path_;
400 scoped_refptr<QuotaManagerProxy> proxy_;
402 bool eviction_disabled_;
403 scoped_refptr<base::SingleThreadTaskRunner> io_thread_;
404 scoped_refptr<base::SequencedTaskRunner> db_thread_;
405 mutable scoped_ptr<QuotaDatabase> database_;
407 GetLRUOriginCallback lru_origin_callback_;
408 std::set<GURL> access_notified_origins_;
410 QuotaClientList clients_;
412 scoped_ptr<UsageTracker> temporary_usage_tracker_;
413 scoped_ptr<UsageTracker> persistent_usage_tracker_;
414 scoped_ptr<UsageTracker> syncable_usage_tracker_;
415 // TODO(michaeln): Need a way to clear the cache, drop and
416 // reinstantiate the trackers when they're not handling requests.
418 scoped_ptr<QuotaTemporaryStorageEvictor> temporary_storage_evictor_;
419 EvictionContext eviction_context_;
421 ClosureQueue db_initialization_callbacks_;
422 AvailableSpaceCallbackQueue available_space_callbacks_;
423 GlobalQuotaCallbackQueue temporary_global_quota_callbacks_;
424 HostQuotaCallbackMap persistent_host_quota_callbacks_;
426 bool temporary_quota_initialized_;
427 int64 temporary_quota_override_;
429 int64 desired_available_space_;
431 // Map from origin to count.
432 std::map<GURL, int> origins_in_use_;
433 // Map from origin to error count.
434 std::map<GURL, int> origins_in_error_;
436 scoped_refptr<SpecialStoragePolicy> special_storage_policy_;
438 base::RepeatingTimer<QuotaManager> histogram_timer_;
440 // Pointer to the function used to get the available disk space. This is
441 // overwritten by QuotaManagerTest in order to attain a deterministic reported
442 // value. The default value points to base::SysInfo::AmountOfFreeDiskSpace.
443 GetAvailableDiskSpaceFn get_disk_space_fn_;
445 scoped_ptr<StorageMonitor> storage_monitor_;
447 base::WeakPtrFactory<QuotaManager> weak_factory_;
449 DISALLOW_COPY_AND_ASSIGN(QuotaManager);
452 struct QuotaManagerDeleter {
453 static void Destruct(const QuotaManager* manager) {
454 manager->DeleteOnCorrectThread();
458 } // namespace storage
460 #endif // STORAGE_BROWSER_QUOTA_QUOTA_MANAGER_H_