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 ~QuotaManager() override
;
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 typedef CallbackQueue
<base::Closure
> ClosureQueue
;
302 typedef CallbackQueue
<AvailableSpaceCallback
, QuotaStatusCode
, int64
>
303 AvailableSpaceCallbackQueue
;
304 typedef CallbackQueueMap
<QuotaCallback
, std::string
, QuotaStatusCode
, int64
>
305 HostQuotaCallbackMap
;
307 struct EvictionContext
{
309 virtual ~EvictionContext();
311 StorageType evicted_type
;
313 EvictOriginDataCallback evict_origin_data_callback
;
316 typedef QuotaEvictionHandler::UsageAndQuotaCallback
317 UsageAndQuotaDispatcherCallback
;
319 // This initialization method is lazily called on the IO thread
320 // when the first quota manager API is called.
321 // Initialize must be called after all quota clients are added to the
322 // manager by RegisterStorage.
323 void LazyInitialize();
325 // Called by clients via proxy.
326 // Registers a quota client to the manager.
327 // The client must remain valid until OnQuotaManagerDestored is called.
328 void RegisterClient(QuotaClient
* client
);
330 UsageTracker
* GetUsageTracker(StorageType type
) const;
332 // Extract cached origins list from the usage tracker.
333 // (Might return empty list if no origin is tracked by the tracker.)
334 void GetCachedOrigins(StorageType type
, std::set
<GURL
>* origins
);
336 // These internal methods are separately defined mainly for testing.
337 void NotifyStorageAccessedInternal(
338 QuotaClient::ID client_id
,
341 base::Time accessed_time
);
342 void NotifyStorageModifiedInternal(
343 QuotaClient::ID client_id
,
347 base::Time modified_time
);
349 void DumpQuotaTable(const DumpQuotaTableCallback
& callback
);
350 void DumpOriginInfoTable(const DumpOriginInfoTableCallback
& callback
);
352 // Methods for eviction logic.
353 void StartEviction();
354 void DeleteOriginFromDatabase(const GURL
& origin
, StorageType type
);
356 void DidOriginDataEvicted(QuotaStatusCode status
);
358 void ReportHistogram();
359 void DidGetTemporaryGlobalUsageForHistogram(int64 usage
,
360 int64 unlimited_usage
);
361 void DidGetPersistentGlobalUsageForHistogram(int64 usage
,
362 int64 unlimited_usage
);
364 // QuotaEvictionHandler.
365 void GetLRUOrigin(StorageType type
,
366 const GetLRUOriginCallback
& callback
) override
;
367 void EvictOriginData(const GURL
& origin
,
369 const EvictOriginDataCallback
& callback
) override
;
370 void GetUsageAndQuotaForEviction(
371 const UsageAndQuotaCallback
& callback
) override
;
373 void DidSetTemporaryGlobalOverrideQuota(const QuotaCallback
& callback
,
374 const int64
* new_quota
,
376 void DidGetPersistentHostQuota(const std::string
& host
,
379 void DidSetPersistentHostQuota(const std::string
& host
,
380 const QuotaCallback
& callback
,
381 const int64
* new_quota
,
383 void DidInitialize(int64
* temporary_quota_override
,
384 int64
* desired_available_space
,
386 void DidGetLRUOrigin(const GURL
* origin
,
388 void DidGetInitialTemporaryGlobalQuota(QuotaStatusCode status
,
390 void DidInitializeTemporaryOriginsInfo(bool success
);
391 void DidGetAvailableSpace(int64 space
);
392 void DidDatabaseWork(bool success
);
394 void DeleteOnCorrectThread() const;
396 void PostTaskAndReplyWithResultForDBThread(
397 const tracked_objects::Location
& from_here
,
398 const base::Callback
<bool(QuotaDatabase
*)>& task
,
399 const base::Callback
<void(bool)>& reply
);
401 const bool is_incognito_
;
402 const base::FilePath profile_path_
;
404 scoped_refptr
<QuotaManagerProxy
> proxy_
;
406 bool eviction_disabled_
;
407 scoped_refptr
<base::SingleThreadTaskRunner
> io_thread_
;
408 scoped_refptr
<base::SequencedTaskRunner
> db_thread_
;
409 mutable scoped_ptr
<QuotaDatabase
> database_
;
411 GetLRUOriginCallback lru_origin_callback_
;
412 std::set
<GURL
> access_notified_origins_
;
414 QuotaClientList clients_
;
416 scoped_ptr
<UsageTracker
> temporary_usage_tracker_
;
417 scoped_ptr
<UsageTracker
> persistent_usage_tracker_
;
418 scoped_ptr
<UsageTracker
> syncable_usage_tracker_
;
419 // TODO(michaeln): Need a way to clear the cache, drop and
420 // reinstantiate the trackers when they're not handling requests.
422 scoped_ptr
<QuotaTemporaryStorageEvictor
> temporary_storage_evictor_
;
423 EvictionContext eviction_context_
;
425 ClosureQueue db_initialization_callbacks_
;
426 AvailableSpaceCallbackQueue available_space_callbacks_
;
427 HostQuotaCallbackMap persistent_host_quota_callbacks_
;
429 bool temporary_quota_initialized_
;
430 int64 temporary_quota_override_
;
432 int64 desired_available_space_
;
434 // Map from origin to count.
435 std::map
<GURL
, int> origins_in_use_
;
436 // Map from origin to error count.
437 std::map
<GURL
, int> origins_in_error_
;
439 scoped_refptr
<SpecialStoragePolicy
> special_storage_policy_
;
441 base::RepeatingTimer
<QuotaManager
> histogram_timer_
;
443 // Pointer to the function used to get the available disk space. This is
444 // overwritten by QuotaManagerTest in order to attain a deterministic reported
445 // value. The default value points to base::SysInfo::AmountOfFreeDiskSpace.
446 GetAvailableDiskSpaceFn get_disk_space_fn_
;
448 scoped_ptr
<StorageMonitor
> storage_monitor_
;
450 base::WeakPtrFactory
<QuotaManager
> weak_factory_
;
452 DISALLOW_COPY_AND_ASSIGN(QuotaManager
);
455 struct QuotaManagerDeleter
{
456 static void Destruct(const QuotaManager
* manager
) {
457 manager
->DeleteOnCorrectThread();
461 } // namespace storage
463 #endif // STORAGE_BROWSER_QUOTA_QUOTA_MANAGER_H_