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 // TODO(calamity): Use this in the temporary storage eviction path.
73 // An interface for deciding which origin's temporary storage should be evicted
74 // when the quota is exceeded.
75 class STORAGE_EXPORT QuotaEvictionPolicy
{
77 // Returns the next origin to evict. It might return an empty GURL when there
78 // are no evictable origins.
79 virtual void GetEvictionOrigin(
80 const scoped_refptr
<SpecialStoragePolicy
>& special_storage_policy
,
81 const std::map
<GURL
, int64
>& usage_map
,
83 const GetOriginCallback
& callback
) = 0;
86 // An interface called by QuotaTemporaryStorageEvictor.
87 class STORAGE_EXPORT QuotaEvictionHandler
{
89 typedef StatusCallback EvictOriginDataCallback
;
90 typedef base::Callback
<void(QuotaStatusCode status
,
91 const UsageAndQuota
& usage_and_quota
)>
92 UsageAndQuotaCallback
;
94 // Returns next origin to evict. It might return an empty GURL when there are
95 // no evictable origins.
96 virtual void GetEvictionOrigin(StorageType type
,
97 const GetOriginCallback
& callback
) = 0;
99 virtual void EvictOriginData(
102 const EvictOriginDataCallback
& callback
) = 0;
104 virtual void GetUsageAndQuotaForEviction(
105 const UsageAndQuotaCallback
& callback
) = 0;
108 virtual ~QuotaEvictionHandler() {}
112 UsageInfo(const std::string
& host
, StorageType type
, int64 usage
)
121 // The quota manager class. This class is instantiated per profile and
122 // held by the profile. With the exception of the constructor and the
123 // proxy() method, all methods should only be called on the IO thread.
124 class STORAGE_EXPORT QuotaManager
125 : public QuotaTaskObserver
,
126 public QuotaEvictionHandler
,
127 public base::RefCountedThreadSafe
<QuotaManager
, QuotaManagerDeleter
> {
129 typedef base::Callback
<void(QuotaStatusCode
,
132 GetUsageAndQuotaCallback
;
134 static const int64 kIncognitoDefaultQuotaLimit
;
135 static const int64 kNoLimit
;
139 const base::FilePath
& profile_path
,
140 const scoped_refptr
<base::SingleThreadTaskRunner
>& io_thread
,
141 const scoped_refptr
<base::SequencedTaskRunner
>& db_thread
,
142 const scoped_refptr
<SpecialStoragePolicy
>& special_storage_policy
);
144 // Returns a proxy object that can be used on any thread.
145 QuotaManagerProxy
* proxy() { return proxy_
.get(); }
147 // Called by clients or webapps. Returns usage per host.
148 void GetUsageInfo(const GetUsageInfoCallback
& callback
);
150 // Called by Web Apps.
151 // This method is declared as virtual to allow test code to override it.
152 virtual void GetUsageAndQuotaForWebApps(
155 const GetUsageAndQuotaCallback
& callback
);
157 // Called by StorageClients.
158 // This method is declared as virtual to allow test code to override it.
160 // For UnlimitedStorage origins, this version skips usage and quota handling
161 // to avoid extra query cost.
162 // Do not call this method for apps/user-facing code.
163 virtual void GetUsageAndQuota(
166 const GetUsageAndQuotaCallback
& callback
);
168 // Called by clients via proxy.
169 // Client storage should call this method when storage is accessed.
170 // Used to maintain LRU ordering.
171 void NotifyStorageAccessed(QuotaClient::ID client_id
,
175 // Called by clients via proxy.
176 // Client storage must call this method whenever they have made any
177 // modifications that change the amount of data stored in their storage.
178 void NotifyStorageModified(QuotaClient::ID client_id
,
183 // Used to avoid evicting origins with open pages.
184 // A call to NotifyOriginInUse must be balanced by a later call
185 // to NotifyOriginNoLongerInUse.
186 void NotifyOriginInUse(const GURL
& origin
);
187 void NotifyOriginNoLongerInUse(const GURL
& origin
);
188 bool IsOriginInUse(const GURL
& origin
) const {
189 return origins_in_use_
.find(origin
) != origins_in_use_
.end();
192 void SetUsageCacheEnabled(QuotaClient::ID client_id
,
197 // DeleteOriginData and DeleteHostData (surprisingly enough) delete data of a
198 // particular StorageType associated with either a specific origin or set of
199 // origins. Each method additionally requires a |quota_client_mask| which
200 // specifies the types of QuotaClients to delete from the origin. This is
201 // specified by the caller as a bitmask built from QuotaClient::IDs. Setting
202 // the mask to QuotaClient::kAllClientsMask will remove all clients from the
203 // origin, regardless of type.
204 virtual void DeleteOriginData(const GURL
& origin
,
206 int quota_client_mask
,
207 const StatusCallback
& callback
);
208 void DeleteHostData(const std::string
& host
,
210 int quota_client_mask
,
211 const StatusCallback
& callback
);
213 // Called by UI and internal modules.
214 void GetAvailableSpace(const AvailableSpaceCallback
& callback
);
215 void GetTemporaryGlobalQuota(const QuotaCallback
& callback
);
217 // Ok to call with NULL callback.
218 void SetTemporaryGlobalOverrideQuota(int64 new_quota
,
219 const QuotaCallback
& callback
);
221 void GetPersistentHostQuota(const std::string
& host
,
222 const QuotaCallback
& callback
);
223 void SetPersistentHostQuota(const std::string
& host
,
225 const QuotaCallback
& callback
);
226 void GetGlobalUsage(StorageType type
, const GlobalUsageCallback
& callback
);
227 void GetHostUsage(const std::string
& host
, StorageType type
,
228 const UsageCallback
& callback
);
229 void GetHostUsage(const std::string
& host
, StorageType type
,
230 QuotaClient::ID client_id
,
231 const UsageCallback
& callback
);
233 bool IsTrackingHostUsage(StorageType type
, QuotaClient::ID client_id
) const;
235 void GetStatistics(std::map
<std::string
, std::string
>* statistics
);
237 bool IsStorageUnlimited(const GURL
& origin
, StorageType type
) const;
239 bool CanQueryDiskSize(const GURL
& origin
) const {
240 return special_storage_policy_
.get() &&
241 special_storage_policy_
->CanQueryDiskSize(origin
);
244 virtual void GetOriginsModifiedSince(StorageType type
,
245 base::Time modified_since
,
246 const GetOriginsCallback
& callback
);
248 bool ResetUsageTracker(StorageType type
);
250 // Used to register/deregister observers that wish to monitor storage events.
251 void AddStorageObserver(StorageObserver
* observer
,
252 const StorageObserver::MonitorParams
& params
);
253 void RemoveStorageObserver(StorageObserver
* observer
);
254 void RemoveStorageObserverForFilter(StorageObserver
* observer
,
255 const StorageObserver::Filter
& filter
);
257 // Determines the portion of the temp pool that can be
258 // utilized by a single host (ie. 5 for 20%).
259 static const int kPerHostTemporaryPortion
;
261 static const int64 kPerHostPersistentQuotaLimit
;
263 static const char kDatabaseName
[];
265 static const int kThresholdOfErrorsToBeBlacklisted
;
267 static const int kEvictionIntervalInMilliSeconds
;
269 // These are kept non-const so that test code can change the value.
270 // TODO(kinuko): Make this a real const value and add a proper way to set
271 // the quota for syncable storage. (http://crbug.com/155488)
272 static int64 kMinimumPreserveForSystem
;
273 static int64 kSyncableStorageDefaultHostQuota
;
276 ~QuotaManager() override
;
279 friend class base::DeleteHelper
<QuotaManager
>;
280 friend class base::RefCountedThreadSafe
<QuotaManager
, QuotaManagerDeleter
>;
281 friend class content::QuotaManagerTest
;
282 friend class content::StorageMonitorTest
;
283 friend class content::MockQuotaManager
;
284 friend class content::MockStorageClient
;
285 friend class quota_internals::QuotaInternalsProxy
;
286 friend class QuotaManagerProxy
;
287 friend class QuotaTemporaryStorageEvictor
;
288 friend struct QuotaManagerDeleter
;
290 class GetUsageInfoTask
;
292 class OriginDataDeleter
;
293 class HostDataDeleter
;
295 class GetModifiedSinceHelper
;
296 class DumpQuotaTableHelper
;
297 class DumpOriginInfoTableHelper
;
299 typedef QuotaDatabase::QuotaTableEntry QuotaTableEntry
;
300 typedef QuotaDatabase::OriginInfoTableEntry OriginInfoTableEntry
;
301 typedef std::vector
<QuotaTableEntry
> QuotaTableEntries
;
302 typedef std::vector
<OriginInfoTableEntry
> OriginInfoTableEntries
;
304 // Function pointer type used to store the function which returns the
305 // available disk space for the disk containing the given FilePath.
306 typedef int64 (*GetAvailableDiskSpaceFn
)(const base::FilePath
&);
308 typedef base::Callback
<void(const QuotaTableEntries
&)>
309 DumpQuotaTableCallback
;
310 typedef base::Callback
<void(const OriginInfoTableEntries
&)>
311 DumpOriginInfoTableCallback
;
313 typedef CallbackQueue
<base::Closure
> ClosureQueue
;
314 typedef CallbackQueue
<AvailableSpaceCallback
, QuotaStatusCode
, int64
>
315 AvailableSpaceCallbackQueue
;
316 typedef CallbackQueueMap
<QuotaCallback
, std::string
, QuotaStatusCode
, int64
>
317 HostQuotaCallbackMap
;
319 struct EvictionContext
{
321 virtual ~EvictionContext();
323 StorageType evicted_type
;
325 EvictOriginDataCallback evict_origin_data_callback
;
328 typedef QuotaEvictionHandler::UsageAndQuotaCallback
329 UsageAndQuotaDispatcherCallback
;
331 // This initialization method is lazily called on the IO thread
332 // when the first quota manager API is called.
333 // Initialize must be called after all quota clients are added to the
334 // manager by RegisterStorage.
335 void LazyInitialize();
337 // Called by clients via proxy.
338 // Registers a quota client to the manager.
339 // The client must remain valid until OnQuotaManagerDestored is called.
340 void RegisterClient(QuotaClient
* client
);
342 UsageTracker
* GetUsageTracker(StorageType type
) const;
344 // Extract cached origins list from the usage tracker.
345 // (Might return empty list if no origin is tracked by the tracker.)
346 void GetCachedOrigins(StorageType type
, std::set
<GURL
>* origins
);
348 // These internal methods are separately defined mainly for testing.
349 void NotifyStorageAccessedInternal(
350 QuotaClient::ID client_id
,
353 base::Time accessed_time
);
354 void NotifyStorageModifiedInternal(
355 QuotaClient::ID client_id
,
359 base::Time modified_time
);
361 void DumpQuotaTable(const DumpQuotaTableCallback
& callback
);
362 void DumpOriginInfoTable(const DumpOriginInfoTableCallback
& callback
);
364 // Methods for eviction logic.
365 void StartEviction();
366 void DeleteOriginFromDatabase(const GURL
& origin
, StorageType type
);
368 void DidOriginDataEvicted(QuotaStatusCode status
);
370 void ReportHistogram();
371 void DidGetTemporaryGlobalUsageForHistogram(int64 usage
,
372 int64 unlimited_usage
);
373 void DidGetPersistentGlobalUsageForHistogram(int64 usage
,
374 int64 unlimited_usage
);
376 // QuotaEvictionHandler.
377 void GetEvictionOrigin(StorageType type
,
378 const GetOriginCallback
& callback
) override
;
379 void EvictOriginData(const GURL
& origin
,
381 const EvictOriginDataCallback
& callback
) override
;
382 void GetUsageAndQuotaForEviction(
383 const UsageAndQuotaCallback
& callback
) override
;
385 void GetLRUOrigin(StorageType type
, const GetOriginCallback
& callback
);
387 void DidSetTemporaryGlobalOverrideQuota(const QuotaCallback
& callback
,
388 const int64
* new_quota
,
390 void DidGetPersistentHostQuota(const std::string
& host
,
393 void DidSetPersistentHostQuota(const std::string
& host
,
394 const QuotaCallback
& callback
,
395 const int64
* new_quota
,
397 void DidInitialize(int64
* temporary_quota_override
,
398 int64
* desired_available_space
,
400 void DidGetLRUOrigin(const GURL
* origin
,
402 void DidGetInitialTemporaryGlobalQuota(QuotaStatusCode status
,
404 void DidInitializeTemporaryOriginsInfo(bool success
);
405 void DidGetAvailableSpace(int64 space
);
406 void DidDatabaseWork(bool success
);
408 void DeleteOnCorrectThread() const;
410 void PostTaskAndReplyWithResultForDBThread(
411 const tracked_objects::Location
& from_here
,
412 const base::Callback
<bool(QuotaDatabase
*)>& task
,
413 const base::Callback
<void(bool)>& reply
);
415 const bool is_incognito_
;
416 const base::FilePath profile_path_
;
418 scoped_refptr
<QuotaManagerProxy
> proxy_
;
420 bool eviction_disabled_
;
421 scoped_refptr
<base::SingleThreadTaskRunner
> io_thread_
;
422 scoped_refptr
<base::SequencedTaskRunner
> db_thread_
;
423 mutable scoped_ptr
<QuotaDatabase
> database_
;
425 GetOriginCallback lru_origin_callback_
;
426 std::set
<GURL
> access_notified_origins_
;
428 QuotaClientList clients_
;
430 scoped_ptr
<UsageTracker
> temporary_usage_tracker_
;
431 scoped_ptr
<UsageTracker
> persistent_usage_tracker_
;
432 scoped_ptr
<UsageTracker
> syncable_usage_tracker_
;
433 // TODO(michaeln): Need a way to clear the cache, drop and
434 // reinstantiate the trackers when they're not handling requests.
436 scoped_ptr
<QuotaTemporaryStorageEvictor
> temporary_storage_evictor_
;
437 EvictionContext eviction_context_
;
439 ClosureQueue db_initialization_callbacks_
;
440 AvailableSpaceCallbackQueue available_space_callbacks_
;
441 HostQuotaCallbackMap persistent_host_quota_callbacks_
;
443 bool temporary_quota_initialized_
;
444 int64 temporary_quota_override_
;
446 int64 desired_available_space_
;
448 // Map from origin to count.
449 std::map
<GURL
, int> origins_in_use_
;
450 // Map from origin to error count.
451 std::map
<GURL
, int> origins_in_error_
;
453 scoped_refptr
<SpecialStoragePolicy
> special_storage_policy_
;
455 base::RepeatingTimer
<QuotaManager
> histogram_timer_
;
457 // Pointer to the function used to get the available disk space. This is
458 // overwritten by QuotaManagerTest in order to attain a deterministic reported
459 // value. The default value points to base::SysInfo::AmountOfFreeDiskSpace.
460 GetAvailableDiskSpaceFn get_disk_space_fn_
;
462 scoped_ptr
<StorageMonitor
> storage_monitor_
;
464 base::WeakPtrFactory
<QuotaManager
> weak_factory_
;
466 DISALLOW_COPY_AND_ASSIGN(QuotaManager
);
469 struct QuotaManagerDeleter
{
470 static void Destruct(const QuotaManager
* manager
) {
471 manager
->DeleteOnCorrectThread();
475 } // namespace storage
477 #endif // STORAGE_BROWSER_QUOTA_QUOTA_MANAGER_H_