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 25 namespace storage { 26 27 class ClientUsageTracker; 28 class 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. 33 class 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. 95 class 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