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