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_USAGE_TRACKER_H_
6#define STORAGE_BROWSER_QUOTA_USAGE_TRACKER_H_
7
8#include <list>
9#include <map>
10#include <set>
11#include <string>
12
13#include "base/basictypes.h"
14#include "base/callback.h"
15#include "base/memory/scoped_ptr.h"
16#include "base/threading/non_thread_safe.h"
17#include "storage/browser/quota/quota_callbacks.h"
18#include "storage/browser/quota/quota_client.h"
19#include "storage/browser/quota/quota_task.h"
20#include "storage/browser/quota/special_storage_policy.h"
21#include "storage/browser/storage_browser_export.h"
22#include "storage/common/quota/quota_types.h"
23#include "url/gurl.h"
24
25namespace storage {
26
27class ClientUsageTracker;
28class StorageMonitor;
29
30// A helper class that gathers and tracks the amount of data stored in
31// all quota clients.
32// An instance of this class is created per storage type.
33class STORAGE_EXPORT UsageTracker : public QuotaTaskObserver {
34 public:
35  UsageTracker(const QuotaClientList& clients, StorageType type,
36               SpecialStoragePolicy* special_storage_policy,
37               StorageMonitor* storage_monitor);
38  virtual ~UsageTracker();
39
40  StorageType type() const { return type_; }
41  ClientUsageTracker* GetClientTracker(QuotaClient::ID client_id);
42
43  void GetGlobalLimitedUsage(const UsageCallback& callback);
44  void GetGlobalUsage(const GlobalUsageCallback& callback);
45  void GetHostUsage(const std::string& host, const UsageCallback& callback);
46  void UpdateUsageCache(QuotaClient::ID client_id,
47                        const GURL& origin,
48                        int64 delta);
49  void GetCachedHostsUsage(std::map<std::string, int64>* host_usage) const;
50  void GetCachedOrigins(std::set<GURL>* origins) const;
51  bool IsWorking() const {
52    return global_usage_callbacks_.HasCallbacks() ||
53           host_usage_callbacks_.HasAnyCallbacks();
54  }
55
56  void SetUsageCacheEnabled(QuotaClient::ID client_id,
57                            const GURL& origin,
58                            bool enabled);
59
60 private:
61  struct AccumulateInfo {
62    AccumulateInfo() : pending_clients(0), usage(0), unlimited_usage(0) {}
63    int pending_clients;
64    int64 usage;
65    int64 unlimited_usage;
66  };
67
68  typedef std::map<QuotaClient::ID, ClientUsageTracker*> ClientTrackerMap;
69
70  friend class ClientUsageTracker;
71  void AccumulateClientGlobalLimitedUsage(AccumulateInfo* info,
72                                          int64 limited_usage);
73  void AccumulateClientGlobalUsage(AccumulateInfo* info,
74                                   int64 usage,
75                                   int64 unlimited_usage);
76  void AccumulateClientHostUsage(AccumulateInfo* info,
77                                 const std::string& host,
78                                 int64 usage);
79
80  const StorageType type_;
81  ClientTrackerMap client_tracker_map_;
82
83  UsageCallbackQueue global_limited_usage_callbacks_;
84  GlobalUsageCallbackQueue global_usage_callbacks_;
85  HostUsageCallbackMap host_usage_callbacks_;
86
87  StorageMonitor* storage_monitor_;
88
89  base::WeakPtrFactory<UsageTracker> weak_factory_;
90  DISALLOW_COPY_AND_ASSIGN(UsageTracker);
91};
92
93// This class holds per-client usage tracking information and caches per-host
94// usage data.  An instance of this class is created per client.
95class ClientUsageTracker : public SpecialStoragePolicy::Observer,
96                           public base::NonThreadSafe,
97                           public base::SupportsWeakPtr<ClientUsageTracker> {
98 public:
99  typedef base::Callback<void(int64 limited_usage,
100                              int64 unlimited_usage)> HostUsageAccumulator;
101  typedef base::Callback<void(const GURL& origin,
102                              int64 usage)> OriginUsageAccumulator;
103  typedef std::map<std::string, std::set<GURL> > OriginSetByHost;
104
105  ClientUsageTracker(UsageTracker* tracker,
106                     QuotaClient* client,
107                     StorageType type,
108                     SpecialStoragePolicy* special_storage_policy,
109                     StorageMonitor* storage_monitor);
110  virtual ~ClientUsageTracker();
111
112  void GetGlobalLimitedUsage(const UsageCallback& callback);
113  void GetGlobalUsage(const GlobalUsageCallback& callback);
114  void GetHostUsage(const std::string& host, const UsageCallback& callback);
115  void UpdateUsageCache(const GURL& origin, int64 delta);
116  void GetCachedHostsUsage(std::map<std::string, int64>* host_usage) const;
117  void GetCachedOrigins(std::set<GURL>* origins) const;
118  int64 GetCachedOriginsUsage(const std::set<GURL>& origins,
119                              std::vector<GURL>* origins_not_in_cache);
120  bool IsUsageCacheEnabledForOrigin(const GURL& origin) const;
121  void SetUsageCacheEnabled(const GURL& origin, bool enabled);
122
123 private:
124  typedef CallbackQueueMap<HostUsageAccumulator, std::string,
125                           Tuple2<int64, int64> > HostUsageAccumulatorMap;
126
127  typedef std::set<std::string> HostSet;
128  typedef std::map<GURL, int64> UsageMap;
129  typedef std::map<std::string, UsageMap> HostUsageMap;
130
131  struct AccumulateInfo {
132    int pending_jobs;
133    int64 limited_usage;
134    int64 unlimited_usage;
135
136    AccumulateInfo()
137        : pending_jobs(0), limited_usage(0), unlimited_usage(0) {}
138  };
139
140  void AccumulateLimitedOriginUsage(AccumulateInfo* info,
141                                    const UsageCallback& callback,
142                                    int64 usage);
143  void DidGetOriginsForGlobalUsage(const GlobalUsageCallback& callback,
144                                   const std::set<GURL>& origins);
145  void AccumulateHostUsage(AccumulateInfo* info,
146                           const GlobalUsageCallback& callback,
147                           int64 limited_usage,
148                           int64 unlimited_usage);
149
150  void DidGetOriginsForHostUsage(const std::string& host,
151                                 const std::set<GURL>& origins);
152
153  void GetUsageForOrigins(const std::string& host,
154                          const std::set<GURL>& origins);
155  void AccumulateOriginUsage(AccumulateInfo* info,
156                             const std::string& host,
157                             const GURL& origin,
158                             int64 usage);
159
160  void DidGetHostUsageAfterUpdate(const GURL& origin, int64 usage);
161
162  // Methods used by our GatherUsage tasks, as a task makes progress
163  // origins and hosts are added incrementally to the cache.
164  void AddCachedOrigin(const GURL& origin, int64 usage);
165  void AddCachedHost(const std::string& host);
166
167  int64 GetCachedHostUsage(const std::string& host) const;
168  int64 GetCachedGlobalUnlimitedUsage();
169  bool GetCachedOriginUsage(const GURL& origin, int64* usage) const;
170
171  // SpecialStoragePolicy::Observer overrides
172  virtual void OnGranted(const GURL& origin, int change_flags) OVERRIDE;
173  virtual void OnRevoked(const GURL& origin, int change_flags) OVERRIDE;
174  virtual void OnCleared() OVERRIDE;
175
176  bool IsStorageUnlimited(const GURL& origin) const;
177
178  UsageTracker* tracker_;
179  QuotaClient* client_;
180  const StorageType type_;
181  StorageMonitor* storage_monitor_;
182
183  int64 global_limited_usage_;
184  int64 global_unlimited_usage_;
185  bool global_usage_retrieved_;
186  HostSet cached_hosts_;
187  HostUsageMap cached_usage_by_host_;
188
189  OriginSetByHost non_cached_limited_origins_by_host_;
190  OriginSetByHost non_cached_unlimited_origins_by_host_;
191
192  GlobalUsageCallbackQueue global_usage_callback_;
193  HostUsageAccumulatorMap host_usage_accumulators_;
194
195  scoped_refptr<SpecialStoragePolicy> special_storage_policy_;
196
197  DISALLOW_COPY_AND_ASSIGN(ClientUsageTracker);
198};
199
200}  // namespace storage
201
202#endif  // STORAGE_BROWSER_QUOTA_USAGE_TRACKER_H_
203