Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / webkit / 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 WEBKIT_BROWSER_QUOTA_QUOTA_MANAGER_H_
6 #define WEBKIT_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 "webkit/browser/quota/quota_callbacks.h"
24 #include "webkit/browser/quota/quota_client.h"
25 #include "webkit/browser/quota/quota_database.h"
26 #include "webkit/browser/quota/quota_task.h"
27 #include "webkit/browser/quota/special_storage_policy.h"
28 #include "webkit/browser/quota/storage_observer.h"
29 #include "webkit/browser/webkit_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 quota {
50
51 class QuotaDatabase;
52 class QuotaManagerProxy;
53 class QuotaTemporaryStorageEvictor;
54 class StorageMonitor;
55 class UsageTracker;
56
57 struct QuotaManagerDeleter;
58
59 struct WEBKIT_STORAGE_BROWSER_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 WEBKIT_STORAGE_BROWSER_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 WEBKIT_STORAGE_BROWSER_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(bool is_incognito,
126                const base::FilePath& profile_path,
127                base::SingleThreadTaskRunner* io_thread,
128                base::SequencedTaskRunner* db_thread,
129                SpecialStoragePolicy* special_storage_policy);
130
131   // Returns a proxy object that can be used on any thread.
132   QuotaManagerProxy* proxy() { return proxy_.get(); }
133
134   // Called by clients or webapps. Returns usage per host.
135   void GetUsageInfo(const GetUsageInfoCallback& callback);
136
137   // Called by Web Apps.
138   // This method is declared as virtual to allow test code to override it.
139   virtual void GetUsageAndQuotaForWebApps(
140       const GURL& origin,
141       StorageType type,
142       const GetUsageAndQuotaCallback& callback);
143
144   // Called by StorageClients.
145   // This method is declared as virtual to allow test code to override it.
146   //
147   // For UnlimitedStorage origins, this version skips usage and quota handling
148   // to avoid extra query cost.
149   // Do not call this method for apps/user-facing code.
150   virtual void GetUsageAndQuota(
151       const GURL& origin,
152       StorageType type,
153       const GetUsageAndQuotaCallback& callback);
154
155   // Called by clients via proxy.
156   // Client storage should call this method when storage is accessed.
157   // Used to maintain LRU ordering.
158   void NotifyStorageAccessed(QuotaClient::ID client_id,
159                              const GURL& origin,
160                              StorageType type);
161
162   // Called by clients via proxy.
163   // Client storage must call this method whenever they have made any
164   // modifications that change the amount of data stored in their storage.
165   void NotifyStorageModified(QuotaClient::ID client_id,
166                              const GURL& origin,
167                              StorageType type,
168                              int64 delta);
169
170   // Used to avoid evicting origins with open pages.
171   // A call to NotifyOriginInUse must be balanced by a later call
172   // to NotifyOriginNoLongerInUse.
173   void NotifyOriginInUse(const GURL& origin);
174   void NotifyOriginNoLongerInUse(const GURL& origin);
175   bool IsOriginInUse(const GURL& origin) const {
176     return origins_in_use_.find(origin) != origins_in_use_.end();
177   }
178
179   void SetUsageCacheEnabled(QuotaClient::ID client_id,
180                             const GURL& origin,
181                             StorageType type,
182                             bool enabled);
183
184   // DeleteOriginData and DeleteHostData (surprisingly enough) delete data of a
185   // particular StorageType associated with either a specific origin or set of
186   // origins. Each method additionally requires a |quota_client_mask| which
187   // specifies the types of QuotaClients to delete from the origin. This is
188   // specified by the caller as a bitmask built from QuotaClient::IDs. Setting
189   // the mask to QuotaClient::kAllClientsMask will remove all clients from the
190   // origin, regardless of type.
191   virtual void DeleteOriginData(const GURL& origin,
192                                 StorageType type,
193                                 int quota_client_mask,
194                                 const StatusCallback& callback);
195   void DeleteHostData(const std::string& host,
196                       StorageType type,
197                       int quota_client_mask,
198                       const StatusCallback& callback);
199
200   // Called by UI and internal modules.
201   void GetAvailableSpace(const AvailableSpaceCallback& callback);
202   void GetTemporaryGlobalQuota(const QuotaCallback& callback);
203
204   // Ok to call with NULL callback.
205   void SetTemporaryGlobalOverrideQuota(int64 new_quota,
206                                        const QuotaCallback& callback);
207
208   void GetPersistentHostQuota(const std::string& host,
209                               const QuotaCallback& callback);
210   void SetPersistentHostQuota(const std::string& host,
211                               int64 new_quota,
212                               const QuotaCallback& callback);
213   void GetGlobalUsage(StorageType type, const GlobalUsageCallback& callback);
214   void GetHostUsage(const std::string& host, StorageType type,
215                     const UsageCallback& callback);
216   void GetHostUsage(const std::string& host, StorageType type,
217                     QuotaClient::ID client_id,
218                     const UsageCallback& callback);
219
220   bool IsTrackingHostUsage(StorageType type, QuotaClient::ID client_id) const;
221
222   void GetStatistics(std::map<std::string, std::string>* statistics);
223
224   bool IsStorageUnlimited(const GURL& origin, StorageType type) const;
225
226   bool CanQueryDiskSize(const GURL& origin) const {
227     return special_storage_policy_.get() &&
228            special_storage_policy_->CanQueryDiskSize(origin);
229   }
230
231   virtual void GetOriginsModifiedSince(StorageType type,
232                                        base::Time modified_since,
233                                        const GetOriginsCallback& callback);
234
235   bool ResetUsageTracker(StorageType type);
236
237   // Used to register/deregister observers that wish to monitor storage events.
238   void AddStorageObserver(StorageObserver* observer,
239                           const StorageObserver::MonitorParams& params);
240   void RemoveStorageObserver(StorageObserver* observer);
241   void RemoveStorageObserverForFilter(StorageObserver* observer,
242                                       const StorageObserver::Filter& filter);
243
244   // Determines the portion of the temp pool that can be
245   // utilized by a single host (ie. 5 for 20%).
246   static const int kPerHostTemporaryPortion;
247
248   static const int64 kPerHostPersistentQuotaLimit;
249
250   static const char kDatabaseName[];
251
252   static const int kThresholdOfErrorsToBeBlacklisted;
253
254   static const int kEvictionIntervalInMilliSeconds;
255
256   // These are kept non-const so that test code can change the value.
257   // TODO(kinuko): Make this a real const value and add a proper way to set
258   // the quota for syncable storage. (http://crbug.com/155488)
259   static int64 kMinimumPreserveForSystem;
260   static int64 kSyncableStorageDefaultHostQuota;
261
262  protected:
263   virtual ~QuotaManager();
264
265  private:
266   friend class base::DeleteHelper<QuotaManager>;
267   friend class base::RefCountedThreadSafe<QuotaManager, QuotaManagerDeleter>;
268   friend class content::QuotaManagerTest;
269   friend class content::StorageMonitorTest;
270   friend class content::MockQuotaManager;
271   friend class content::MockStorageClient;
272   friend class quota_internals::QuotaInternalsProxy;
273   friend class QuotaManagerProxy;
274   friend class QuotaTemporaryStorageEvictor;
275   friend struct QuotaManagerDeleter;
276
277   class GetUsageInfoTask;
278
279   class OriginDataDeleter;
280   class HostDataDeleter;
281
282   class GetModifiedSinceHelper;
283   class DumpQuotaTableHelper;
284   class DumpOriginInfoTableHelper;
285
286   typedef QuotaDatabase::QuotaTableEntry QuotaTableEntry;
287   typedef QuotaDatabase::OriginInfoTableEntry OriginInfoTableEntry;
288   typedef std::vector<QuotaTableEntry> QuotaTableEntries;
289   typedef std::vector<OriginInfoTableEntry> OriginInfoTableEntries;
290
291   // Function pointer type used to store the function which returns the
292   // available disk space for the disk containing the given FilePath.
293   typedef int64 (*GetAvailableDiskSpaceFn)(const base::FilePath&);
294
295   typedef base::Callback<void(const QuotaTableEntries&)>
296       DumpQuotaTableCallback;
297   typedef base::Callback<void(const OriginInfoTableEntries&)>
298       DumpOriginInfoTableCallback;
299
300   struct EvictionContext {
301     EvictionContext();
302     virtual ~EvictionContext();
303     GURL evicted_origin;
304     StorageType evicted_type;
305
306     EvictOriginDataCallback evict_origin_data_callback;
307   };
308
309   typedef QuotaEvictionHandler::UsageAndQuotaCallback
310       UsageAndQuotaDispatcherCallback;
311
312   // This initialization method is lazily called on the IO thread
313   // when the first quota manager API is called.
314   // Initialize must be called after all quota clients are added to the
315   // manager by RegisterStorage.
316   void LazyInitialize();
317
318   // Called by clients via proxy.
319   // Registers a quota client to the manager.
320   // The client must remain valid until OnQuotaManagerDestored is called.
321   void RegisterClient(QuotaClient* client);
322
323   UsageTracker* GetUsageTracker(StorageType type) const;
324
325   // Extract cached origins list from the usage tracker.
326   // (Might return empty list if no origin is tracked by the tracker.)
327   void GetCachedOrigins(StorageType type, std::set<GURL>* origins);
328
329   // These internal methods are separately defined mainly for testing.
330   void NotifyStorageAccessedInternal(
331       QuotaClient::ID client_id,
332       const GURL& origin,
333       StorageType type,
334       base::Time accessed_time);
335   void NotifyStorageModifiedInternal(
336       QuotaClient::ID client_id,
337       const GURL& origin,
338       StorageType type,
339       int64 delta,
340       base::Time modified_time);
341
342   void DumpQuotaTable(const DumpQuotaTableCallback& callback);
343   void DumpOriginInfoTable(const DumpOriginInfoTableCallback& callback);
344
345   // Methods for eviction logic.
346   void StartEviction();
347   void DeleteOriginFromDatabase(const GURL& origin, StorageType type);
348
349   void DidOriginDataEvicted(QuotaStatusCode status);
350
351   void ReportHistogram();
352   void DidGetTemporaryGlobalUsageForHistogram(int64 usage,
353                                               int64 unlimited_usage);
354   void DidGetPersistentGlobalUsageForHistogram(int64 usage,
355                                                int64 unlimited_usage);
356
357   // QuotaEvictionHandler.
358   virtual void GetLRUOrigin(
359       StorageType type,
360       const GetLRUOriginCallback& callback) OVERRIDE;
361   virtual void EvictOriginData(
362       const GURL& origin,
363       StorageType type,
364       const EvictOriginDataCallback& callback) OVERRIDE;
365   virtual void GetUsageAndQuotaForEviction(
366       const UsageAndQuotaCallback& callback) OVERRIDE;
367
368   void DidSetTemporaryGlobalOverrideQuota(const QuotaCallback& callback,
369                                           const int64* new_quota,
370                                           bool success);
371   void DidGetPersistentHostQuota(const std::string& host,
372                                  const int64* quota,
373                                  bool success);
374   void DidSetPersistentHostQuota(const std::string& host,
375                                  const QuotaCallback& callback,
376                                  const int64* new_quota,
377                                  bool success);
378   void DidInitialize(int64* temporary_quota_override,
379                      int64* desired_available_space,
380                      bool success);
381   void DidGetLRUOrigin(const GURL* origin,
382                        bool success);
383   void DidGetInitialTemporaryGlobalQuota(QuotaStatusCode status,
384                                          int64 quota_unused);
385   void DidInitializeTemporaryOriginsInfo(bool success);
386   void DidGetAvailableSpace(int64 space);
387   void DidDatabaseWork(bool success);
388
389   void DeleteOnCorrectThread() const;
390
391   void PostTaskAndReplyWithResultForDBThread(
392       const tracked_objects::Location& from_here,
393       const base::Callback<bool(QuotaDatabase*)>& task,
394       const base::Callback<void(bool)>& reply);
395
396   const bool is_incognito_;
397   const base::FilePath profile_path_;
398
399   scoped_refptr<QuotaManagerProxy> proxy_;
400   bool db_disabled_;
401   bool eviction_disabled_;
402   scoped_refptr<base::SingleThreadTaskRunner> io_thread_;
403   scoped_refptr<base::SequencedTaskRunner> db_thread_;
404   mutable scoped_ptr<QuotaDatabase> database_;
405
406   GetLRUOriginCallback lru_origin_callback_;
407   std::set<GURL> access_notified_origins_;
408
409   QuotaClientList clients_;
410
411   scoped_ptr<UsageTracker> temporary_usage_tracker_;
412   scoped_ptr<UsageTracker> persistent_usage_tracker_;
413   scoped_ptr<UsageTracker> syncable_usage_tracker_;
414   // TODO(michaeln): Need a way to clear the cache, drop and
415   // reinstantiate the trackers when they're not handling requests.
416
417   scoped_ptr<QuotaTemporaryStorageEvictor> temporary_storage_evictor_;
418   EvictionContext eviction_context_;
419
420   ClosureQueue db_initialization_callbacks_;
421   AvailableSpaceCallbackQueue available_space_callbacks_;
422   GlobalQuotaCallbackQueue temporary_global_quota_callbacks_;
423   HostQuotaCallbackMap persistent_host_quota_callbacks_;
424
425   bool temporary_quota_initialized_;
426   int64 temporary_quota_override_;
427
428   int64 desired_available_space_;
429
430   // Map from origin to count.
431   std::map<GURL, int> origins_in_use_;
432   // Map from origin to error count.
433   std::map<GURL, int> origins_in_error_;
434
435   scoped_refptr<SpecialStoragePolicy> special_storage_policy_;
436
437   base::RepeatingTimer<QuotaManager> histogram_timer_;
438
439   // Pointer to the function used to get the available disk space. This is
440   // overwritten by QuotaManagerTest in order to attain a deterministic reported
441   // value. The default value points to base::SysInfo::AmountOfFreeDiskSpace.
442   GetAvailableDiskSpaceFn get_disk_space_fn_;
443
444   scoped_ptr<StorageMonitor> storage_monitor_;
445
446   base::WeakPtrFactory<QuotaManager> weak_factory_;
447
448   DISALLOW_COPY_AND_ASSIGN(QuotaManager);
449 };
450
451 struct QuotaManagerDeleter {
452   static void Destruct(const QuotaManager* manager) {
453     manager->DeleteOnCorrectThread();
454   }
455 };
456
457 }  // namespace quota
458
459 #endif  // WEBKIT_BROWSER_QUOTA_QUOTA_MANAGER_H_