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