Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / storage / browser / quota / quota_manager.h
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.
4
5 #ifndef STORAGE_BROWSER_QUOTA_QUOTA_MANAGER_H_
6 #define STORAGE_BROWSER_QUOTA_QUOTA_MANAGER_H_
7
8 #include <deque>
9 #include <list>
10 #include <map>
11 #include <set>
12 #include <string>
13 #include <utility>
14 #include <vector>
15
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"
30
31 namespace base {
32 class FilePath;
33 class SequencedTaskRunner;
34 class SingleThreadTaskRunner;
35 }
36
37 namespace quota_internals {
38 class QuotaInternalsProxy;
39 }
40
41 namespace content {
42 class MockQuotaManager;
43 class MockStorageClient;
44 class QuotaManagerTest;
45 class StorageMonitorTest;
46
47 }
48
49 namespace storage {
50
51 class QuotaDatabase;
52 class QuotaManagerProxy;
53 class QuotaTemporaryStorageEvictor;
54 class StorageMonitor;
55 class UsageTracker;
56
57 struct QuotaManagerDeleter;
58
59 struct STORAGE_EXPORT UsageAndQuota {
60   int64 usage;
61   int64 global_limited_usage;
62   int64 quota;
63   int64 available_disk_space;
64
65   UsageAndQuota();
66   UsageAndQuota(int64 usage,
67                 int64 global_limited_usage,
68                 int64 quota,
69                 int64 available_disk_space);
70 };
71
72 // An interface called by QuotaTemporaryStorageEvictor.
73 class STORAGE_EXPORT QuotaEvictionHandler {
74  public:
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;
80
81   // Returns the least recently used origin.  It might return empty
82   // GURL when there are no evictable origins.
83   virtual void GetLRUOrigin(
84       StorageType type,
85       const GetLRUOriginCallback& callback) = 0;
86
87   virtual void EvictOriginData(
88       const GURL& origin,
89       StorageType type,
90       const EvictOriginDataCallback& callback) = 0;
91
92   virtual void GetUsageAndQuotaForEviction(
93       const UsageAndQuotaCallback& callback) = 0;
94
95  protected:
96   virtual ~QuotaEvictionHandler() {}
97 };
98
99 struct UsageInfo {
100   UsageInfo(const std::string& host, StorageType type, int64 usage)
101       : host(host),
102         type(type),
103         usage(usage) {}
104   std::string host;
105   StorageType type;
106   int64 usage;
107 };
108
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> {
116  public:
117   typedef base::Callback<void(QuotaStatusCode,
118                               int64 /* usage */,
119                               int64 /* quota */)>
120       GetUsageAndQuotaCallback;
121
122   static const int64 kIncognitoDefaultQuotaLimit;
123   static const int64 kNoLimit;
124
125   QuotaManager(
126       bool is_incognito,
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);
131
132   // Returns a proxy object that can be used on any thread.
133   QuotaManagerProxy* proxy() { return proxy_.get(); }
134
135   // Called by clients or webapps. Returns usage per host.
136   void GetUsageInfo(const GetUsageInfoCallback& callback);
137
138   // Called by Web Apps.
139   // This method is declared as virtual to allow test code to override it.
140   virtual void GetUsageAndQuotaForWebApps(
141       const GURL& origin,
142       StorageType type,
143       const GetUsageAndQuotaCallback& callback);
144
145   // Called by StorageClients.
146   // This method is declared as virtual to allow test code to override it.
147   //
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(
152       const GURL& origin,
153       StorageType type,
154       const GetUsageAndQuotaCallback& callback);
155
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,
160                              const GURL& origin,
161                              StorageType type);
162
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,
167                              const GURL& origin,
168                              StorageType type,
169                              int64 delta);
170
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();
178   }
179
180   void SetUsageCacheEnabled(QuotaClient::ID client_id,
181                             const GURL& origin,
182                             StorageType type,
183                             bool enabled);
184
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,
193                                 StorageType type,
194                                 int quota_client_mask,
195                                 const StatusCallback& callback);
196   void DeleteHostData(const std::string& host,
197                       StorageType type,
198                       int quota_client_mask,
199                       const StatusCallback& callback);
200
201   // Called by UI and internal modules.
202   void GetAvailableSpace(const AvailableSpaceCallback& callback);
203   void GetTemporaryGlobalQuota(const QuotaCallback& callback);
204
205   // Ok to call with NULL callback.
206   void SetTemporaryGlobalOverrideQuota(int64 new_quota,
207                                        const QuotaCallback& callback);
208
209   void GetPersistentHostQuota(const std::string& host,
210                               const QuotaCallback& callback);
211   void SetPersistentHostQuota(const std::string& host,
212                               int64 new_quota,
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);
220
221   bool IsTrackingHostUsage(StorageType type, QuotaClient::ID client_id) const;
222
223   void GetStatistics(std::map<std::string, std::string>* statistics);
224
225   bool IsStorageUnlimited(const GURL& origin, StorageType type) const;
226
227   bool CanQueryDiskSize(const GURL& origin) const {
228     return special_storage_policy_.get() &&
229            special_storage_policy_->CanQueryDiskSize(origin);
230   }
231
232   virtual void GetOriginsModifiedSince(StorageType type,
233                                        base::Time modified_since,
234                                        const GetOriginsCallback& callback);
235
236   bool ResetUsageTracker(StorageType type);
237
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);
244
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;
248
249   static const int64 kPerHostPersistentQuotaLimit;
250
251   static const char kDatabaseName[];
252
253   static const int kThresholdOfErrorsToBeBlacklisted;
254
255   static const int kEvictionIntervalInMilliSeconds;
256
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;
262
263  protected:
264   virtual ~QuotaManager();
265
266  private:
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;
277
278   class GetUsageInfoTask;
279
280   class OriginDataDeleter;
281   class HostDataDeleter;
282
283   class GetModifiedSinceHelper;
284   class DumpQuotaTableHelper;
285   class DumpOriginInfoTableHelper;
286
287   typedef QuotaDatabase::QuotaTableEntry QuotaTableEntry;
288   typedef QuotaDatabase::OriginInfoTableEntry OriginInfoTableEntry;
289   typedef std::vector<QuotaTableEntry> QuotaTableEntries;
290   typedef std::vector<OriginInfoTableEntry> OriginInfoTableEntries;
291
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&);
295
296   typedef base::Callback<void(const QuotaTableEntries&)>
297       DumpQuotaTableCallback;
298   typedef base::Callback<void(const OriginInfoTableEntries&)>
299       DumpOriginInfoTableCallback;
300
301   struct EvictionContext {
302     EvictionContext();
303     virtual ~EvictionContext();
304     GURL evicted_origin;
305     StorageType evicted_type;
306
307     EvictOriginDataCallback evict_origin_data_callback;
308   };
309
310   typedef QuotaEvictionHandler::UsageAndQuotaCallback
311       UsageAndQuotaDispatcherCallback;
312
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();
318
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);
323
324   UsageTracker* GetUsageTracker(StorageType type) const;
325
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);
329
330   // These internal methods are separately defined mainly for testing.
331   void NotifyStorageAccessedInternal(
332       QuotaClient::ID client_id,
333       const GURL& origin,
334       StorageType type,
335       base::Time accessed_time);
336   void NotifyStorageModifiedInternal(
337       QuotaClient::ID client_id,
338       const GURL& origin,
339       StorageType type,
340       int64 delta,
341       base::Time modified_time);
342
343   void DumpQuotaTable(const DumpQuotaTableCallback& callback);
344   void DumpOriginInfoTable(const DumpOriginInfoTableCallback& callback);
345
346   // Methods for eviction logic.
347   void StartEviction();
348   void DeleteOriginFromDatabase(const GURL& origin, StorageType type);
349
350   void DidOriginDataEvicted(QuotaStatusCode status);
351
352   void ReportHistogram();
353   void DidGetTemporaryGlobalUsageForHistogram(int64 usage,
354                                               int64 unlimited_usage);
355   void DidGetPersistentGlobalUsageForHistogram(int64 usage,
356                                                int64 unlimited_usage);
357
358   // QuotaEvictionHandler.
359   virtual void GetLRUOrigin(
360       StorageType type,
361       const GetLRUOriginCallback& callback) OVERRIDE;
362   virtual void EvictOriginData(
363       const GURL& origin,
364       StorageType type,
365       const EvictOriginDataCallback& callback) OVERRIDE;
366   virtual void GetUsageAndQuotaForEviction(
367       const UsageAndQuotaCallback& callback) OVERRIDE;
368
369   void DidSetTemporaryGlobalOverrideQuota(const QuotaCallback& callback,
370                                           const int64* new_quota,
371                                           bool success);
372   void DidGetPersistentHostQuota(const std::string& host,
373                                  const int64* quota,
374                                  bool success);
375   void DidSetPersistentHostQuota(const std::string& host,
376                                  const QuotaCallback& callback,
377                                  const int64* new_quota,
378                                  bool success);
379   void DidInitialize(int64* temporary_quota_override,
380                      int64* desired_available_space,
381                      bool success);
382   void DidGetLRUOrigin(const GURL* origin,
383                        bool success);
384   void DidGetInitialTemporaryGlobalQuota(QuotaStatusCode status,
385                                          int64 quota_unused);
386   void DidInitializeTemporaryOriginsInfo(bool success);
387   void DidGetAvailableSpace(int64 space);
388   void DidDatabaseWork(bool success);
389
390   void DeleteOnCorrectThread() const;
391
392   void PostTaskAndReplyWithResultForDBThread(
393       const tracked_objects::Location& from_here,
394       const base::Callback<bool(QuotaDatabase*)>& task,
395       const base::Callback<void(bool)>& reply);
396
397   const bool is_incognito_;
398   const base::FilePath profile_path_;
399
400   scoped_refptr<QuotaManagerProxy> proxy_;
401   bool db_disabled_;
402   bool eviction_disabled_;
403   scoped_refptr<base::SingleThreadTaskRunner> io_thread_;
404   scoped_refptr<base::SequencedTaskRunner> db_thread_;
405   mutable scoped_ptr<QuotaDatabase> database_;
406
407   GetLRUOriginCallback lru_origin_callback_;
408   std::set<GURL> access_notified_origins_;
409
410   QuotaClientList clients_;
411
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.
417
418   scoped_ptr<QuotaTemporaryStorageEvictor> temporary_storage_evictor_;
419   EvictionContext eviction_context_;
420
421   ClosureQueue db_initialization_callbacks_;
422   AvailableSpaceCallbackQueue available_space_callbacks_;
423   GlobalQuotaCallbackQueue temporary_global_quota_callbacks_;
424   HostQuotaCallbackMap persistent_host_quota_callbacks_;
425
426   bool temporary_quota_initialized_;
427   int64 temporary_quota_override_;
428
429   int64 desired_available_space_;
430
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_;
435
436   scoped_refptr<SpecialStoragePolicy> special_storage_policy_;
437
438   base::RepeatingTimer<QuotaManager> histogram_timer_;
439
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_;
444
445   scoped_ptr<StorageMonitor> storage_monitor_;
446
447   base::WeakPtrFactory<QuotaManager> weak_factory_;
448
449   DISALLOW_COPY_AND_ASSIGN(QuotaManager);
450 };
451
452 struct QuotaManagerDeleter {
453   static void Destruct(const QuotaManager* manager) {
454     manager->DeleteOnCorrectThread();
455   }
456 };
457
458 }  // namespace storage
459
460 #endif  // STORAGE_BROWSER_QUOTA_QUOTA_MANAGER_H_