OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "webkit/browser/quota/usage_tracker.h" | 5 #include "storage/browser/quota/usage_tracker.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <deque> | 8 #include <deque> |
9 #include <set> | 9 #include <set> |
10 #include <string> | 10 #include <string> |
11 #include <vector> | 11 #include <vector> |
12 | 12 |
13 #include "base/bind.h" | 13 #include "base/bind.h" |
14 #include "base/message_loop/message_loop_proxy.h" | 14 #include "base/message_loop/message_loop_proxy.h" |
15 #include "base/stl_util.h" | 15 #include "base/stl_util.h" |
16 #include "net/base/net_util.h" | 16 #include "net/base/net_util.h" |
17 #include "webkit/browser/quota/storage_monitor.h" | 17 #include "storage/browser/quota/storage_monitor.h" |
18 #include "webkit/browser/quota/storage_observer.h" | 18 #include "storage/browser/quota/storage_observer.h" |
19 | 19 |
20 namespace quota { | 20 namespace quota { |
21 | 21 |
22 namespace { | 22 namespace { |
23 | 23 |
24 typedef ClientUsageTracker::OriginUsageAccumulator OriginUsageAccumulator; | 24 typedef ClientUsageTracker::OriginUsageAccumulator OriginUsageAccumulator; |
25 typedef ClientUsageTracker::OriginSetByHost OriginSetByHost; | 25 typedef ClientUsageTracker::OriginSetByHost OriginSetByHost; |
26 | 26 |
27 void DidGetOriginUsage(const OriginUsageAccumulator& accumulator, | 27 void DidGetOriginUsage(const OriginUsageAccumulator& accumulator, |
28 const GURL& origin, | 28 const GURL& origin, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 } | 67 } |
68 | 68 |
69 } // namespace | 69 } // namespace |
70 | 70 |
71 // UsageTracker ---------------------------------------------------------- | 71 // UsageTracker ---------------------------------------------------------- |
72 | 72 |
73 UsageTracker::UsageTracker(const QuotaClientList& clients, | 73 UsageTracker::UsageTracker(const QuotaClientList& clients, |
74 StorageType type, | 74 StorageType type, |
75 SpecialStoragePolicy* special_storage_policy, | 75 SpecialStoragePolicy* special_storage_policy, |
76 StorageMonitor* storage_monitor) | 76 StorageMonitor* storage_monitor) |
77 : type_(type), | 77 : type_(type), storage_monitor_(storage_monitor), weak_factory_(this) { |
78 storage_monitor_(storage_monitor), | |
79 weak_factory_(this) { | |
80 for (QuotaClientList::const_iterator iter = clients.begin(); | 78 for (QuotaClientList::const_iterator iter = clients.begin(); |
81 iter != clients.end(); | 79 iter != clients.end(); |
82 ++iter) { | 80 ++iter) { |
83 if ((*iter)->DoesSupport(type)) { | 81 if ((*iter)->DoesSupport(type)) { |
84 client_tracker_map_[(*iter)->id()] = | 82 client_tracker_map_[(*iter)->id()] = new ClientUsageTracker( |
85 new ClientUsageTracker(this, *iter, type, special_storage_policy, | 83 this, *iter, type, special_storage_policy, storage_monitor_); |
86 storage_monitor_); | |
87 } | 84 } |
88 } | 85 } |
89 } | 86 } |
90 | 87 |
91 UsageTracker::~UsageTracker() { | 88 UsageTracker::~UsageTracker() { |
92 STLDeleteValues(&client_tracker_map_); | 89 STLDeleteValues(&client_tracker_map_); |
93 } | 90 } |
94 | 91 |
95 ClientUsageTracker* UsageTracker::GetClientTracker(QuotaClient::ID client_id) { | 92 ClientUsageTracker* UsageTracker::GetClientTracker(QuotaClient::ID client_id) { |
96 ClientTrackerMap::iterator found = client_tracker_map_.find(client_id); | 93 ClientTrackerMap::iterator found = client_tracker_map_.find(client_id); |
97 if (found != client_tracker_map_.end()) | 94 if (found != client_tracker_map_.end()) |
98 return found->second; | 95 return found->second; |
99 return NULL; | 96 return NULL; |
100 } | 97 } |
101 | 98 |
102 void UsageTracker::GetGlobalLimitedUsage(const UsageCallback& callback) { | 99 void UsageTracker::GetGlobalLimitedUsage(const UsageCallback& callback) { |
103 if (global_usage_callbacks_.HasCallbacks()) { | 100 if (global_usage_callbacks_.HasCallbacks()) { |
104 global_usage_callbacks_.Add(base::Bind( | 101 global_usage_callbacks_.Add( |
105 &DidGetGlobalUsageForLimitedGlobalUsage, callback)); | 102 base::Bind(&DidGetGlobalUsageForLimitedGlobalUsage, callback)); |
106 return; | 103 return; |
107 } | 104 } |
108 | 105 |
109 if (!global_limited_usage_callbacks_.Add(callback)) | 106 if (!global_limited_usage_callbacks_.Add(callback)) |
110 return; | 107 return; |
111 | 108 |
112 AccumulateInfo* info = new AccumulateInfo; | 109 AccumulateInfo* info = new AccumulateInfo; |
113 // Calling GetGlobalLimitedUsage(accumulator) may synchronously | 110 // Calling GetGlobalLimitedUsage(accumulator) may synchronously |
114 // return if the usage is cached, which may in turn dispatch | 111 // return if the usage is cached, which may in turn dispatch |
115 // the completion callback before we finish looping over | 112 // the completion callback before we finish looping over |
116 // all clients (because info->pending_clients may reach 0 | 113 // all clients (because info->pending_clients may reach 0 |
117 // during the loop). | 114 // during the loop). |
118 // To avoid this, we add one more pending client as a sentinel | 115 // To avoid this, we add one more pending client as a sentinel |
119 // and fire the sentinel callback at the end. | 116 // and fire the sentinel callback at the end. |
120 info->pending_clients = client_tracker_map_.size() + 1; | 117 info->pending_clients = client_tracker_map_.size() + 1; |
121 UsageCallback accumulator = base::Bind( | 118 UsageCallback accumulator = |
122 &UsageTracker::AccumulateClientGlobalLimitedUsage, | 119 base::Bind(&UsageTracker::AccumulateClientGlobalLimitedUsage, |
123 weak_factory_.GetWeakPtr(), base::Owned(info)); | 120 weak_factory_.GetWeakPtr(), |
| 121 base::Owned(info)); |
124 | 122 |
125 for (ClientTrackerMap::iterator iter = client_tracker_map_.begin(); | 123 for (ClientTrackerMap::iterator iter = client_tracker_map_.begin(); |
126 iter != client_tracker_map_.end(); | 124 iter != client_tracker_map_.end(); |
127 ++iter) | 125 ++iter) |
128 iter->second->GetGlobalLimitedUsage(accumulator); | 126 iter->second->GetGlobalLimitedUsage(accumulator); |
129 | 127 |
130 // Fire the sentinel as we've now called GetGlobalUsage for all clients. | 128 // Fire the sentinel as we've now called GetGlobalUsage for all clients. |
131 accumulator.Run(0); | 129 accumulator.Run(0); |
132 } | 130 } |
133 | 131 |
134 void UsageTracker::GetGlobalUsage(const GlobalUsageCallback& callback) { | 132 void UsageTracker::GetGlobalUsage(const GlobalUsageCallback& callback) { |
135 if (!global_usage_callbacks_.Add(callback)) | 133 if (!global_usage_callbacks_.Add(callback)) |
136 return; | 134 return; |
137 | 135 |
138 AccumulateInfo* info = new AccumulateInfo; | 136 AccumulateInfo* info = new AccumulateInfo; |
139 // Calling GetGlobalUsage(accumulator) may synchronously | 137 // Calling GetGlobalUsage(accumulator) may synchronously |
140 // return if the usage is cached, which may in turn dispatch | 138 // return if the usage is cached, which may in turn dispatch |
141 // the completion callback before we finish looping over | 139 // the completion callback before we finish looping over |
142 // all clients (because info->pending_clients may reach 0 | 140 // all clients (because info->pending_clients may reach 0 |
143 // during the loop). | 141 // during the loop). |
144 // To avoid this, we add one more pending client as a sentinel | 142 // To avoid this, we add one more pending client as a sentinel |
145 // and fire the sentinel callback at the end. | 143 // and fire the sentinel callback at the end. |
146 info->pending_clients = client_tracker_map_.size() + 1; | 144 info->pending_clients = client_tracker_map_.size() + 1; |
147 GlobalUsageCallback accumulator = base::Bind( | 145 GlobalUsageCallback accumulator = |
148 &UsageTracker::AccumulateClientGlobalUsage, weak_factory_.GetWeakPtr(), | 146 base::Bind(&UsageTracker::AccumulateClientGlobalUsage, |
149 base::Owned(info)); | 147 weak_factory_.GetWeakPtr(), |
| 148 base::Owned(info)); |
150 | 149 |
151 for (ClientTrackerMap::iterator iter = client_tracker_map_.begin(); | 150 for (ClientTrackerMap::iterator iter = client_tracker_map_.begin(); |
152 iter != client_tracker_map_.end(); | 151 iter != client_tracker_map_.end(); |
153 ++iter) | 152 ++iter) |
154 iter->second->GetGlobalUsage(accumulator); | 153 iter->second->GetGlobalUsage(accumulator); |
155 | 154 |
156 // Fire the sentinel as we've now called GetGlobalUsage for all clients. | 155 // Fire the sentinel as we've now called GetGlobalUsage for all clients. |
157 accumulator.Run(0, 0); | 156 accumulator.Run(0, 0); |
158 } | 157 } |
159 | 158 |
160 void UsageTracker::GetHostUsage(const std::string& host, | 159 void UsageTracker::GetHostUsage(const std::string& host, |
161 const UsageCallback& callback) { | 160 const UsageCallback& callback) { |
162 if (!host_usage_callbacks_.Add(host, callback)) | 161 if (!host_usage_callbacks_.Add(host, callback)) |
163 return; | 162 return; |
164 | 163 |
165 AccumulateInfo* info = new AccumulateInfo; | 164 AccumulateInfo* info = new AccumulateInfo; |
166 // Calling GetHostUsage(accumulator) may synchronously | 165 // Calling GetHostUsage(accumulator) may synchronously |
167 // return if the usage is cached, which may in turn dispatch | 166 // return if the usage is cached, which may in turn dispatch |
168 // the completion callback before we finish looping over | 167 // the completion callback before we finish looping over |
169 // all clients (because info->pending_clients may reach 0 | 168 // all clients (because info->pending_clients may reach 0 |
170 // during the loop). | 169 // during the loop). |
171 // To avoid this, we add one more pending client as a sentinel | 170 // To avoid this, we add one more pending client as a sentinel |
172 // and fire the sentinel callback at the end. | 171 // and fire the sentinel callback at the end. |
173 info->pending_clients = client_tracker_map_.size() + 1; | 172 info->pending_clients = client_tracker_map_.size() + 1; |
174 UsageCallback accumulator = base::Bind( | 173 UsageCallback accumulator = |
175 &UsageTracker::AccumulateClientHostUsage, weak_factory_.GetWeakPtr(), | 174 base::Bind(&UsageTracker::AccumulateClientHostUsage, |
176 base::Owned(info), host); | 175 weak_factory_.GetWeakPtr(), |
| 176 base::Owned(info), |
| 177 host); |
177 | 178 |
178 for (ClientTrackerMap::iterator iter = client_tracker_map_.begin(); | 179 for (ClientTrackerMap::iterator iter = client_tracker_map_.begin(); |
179 iter != client_tracker_map_.end(); | 180 iter != client_tracker_map_.end(); |
180 ++iter) | 181 ++iter) |
181 iter->second->GetHostUsage(host, accumulator); | 182 iter->second->GetHostUsage(host, accumulator); |
182 | 183 |
183 // Fire the sentinel as we've now called GetHostUsage for all clients. | 184 // Fire the sentinel as we've now called GetHostUsage for all clients. |
184 accumulator.Run(0); | 185 accumulator.Run(0); |
185 } | 186 } |
186 | 187 |
187 void UsageTracker::UpdateUsageCache( | 188 void UsageTracker::UpdateUsageCache(QuotaClient::ID client_id, |
188 QuotaClient::ID client_id, const GURL& origin, int64 delta) { | 189 const GURL& origin, |
| 190 int64 delta) { |
189 ClientUsageTracker* client_tracker = GetClientTracker(client_id); | 191 ClientUsageTracker* client_tracker = GetClientTracker(client_id); |
190 DCHECK(client_tracker); | 192 DCHECK(client_tracker); |
191 client_tracker->UpdateUsageCache(origin, delta); | 193 client_tracker->UpdateUsageCache(origin, delta); |
192 } | 194 } |
193 | 195 |
194 void UsageTracker::GetCachedHostsUsage( | 196 void UsageTracker::GetCachedHostsUsage( |
195 std::map<std::string, int64>* host_usage) const { | 197 std::map<std::string, int64>* host_usage) const { |
196 DCHECK(host_usage); | 198 DCHECK(host_usage); |
197 host_usage->clear(); | 199 host_usage->clear(); |
198 for (ClientTrackerMap::const_iterator iter = client_tracker_map_.begin(); | 200 for (ClientTrackerMap::const_iterator iter = client_tracker_map_.begin(); |
199 iter != client_tracker_map_.end(); ++iter) { | 201 iter != client_tracker_map_.end(); |
| 202 ++iter) { |
200 iter->second->GetCachedHostsUsage(host_usage); | 203 iter->second->GetCachedHostsUsage(host_usage); |
201 } | 204 } |
202 } | 205 } |
203 | 206 |
204 void UsageTracker::GetCachedOrigins(std::set<GURL>* origins) const { | 207 void UsageTracker::GetCachedOrigins(std::set<GURL>* origins) const { |
205 DCHECK(origins); | 208 DCHECK(origins); |
206 origins->clear(); | 209 origins->clear(); |
207 for (ClientTrackerMap::const_iterator iter = client_tracker_map_.begin(); | 210 for (ClientTrackerMap::const_iterator iter = client_tracker_map_.begin(); |
208 iter != client_tracker_map_.end(); ++iter) { | 211 iter != client_tracker_map_.end(); |
| 212 ++iter) { |
209 iter->second->GetCachedOrigins(origins); | 213 iter->second->GetCachedOrigins(origins); |
210 } | 214 } |
211 } | 215 } |
212 | 216 |
213 void UsageTracker::SetUsageCacheEnabled(QuotaClient::ID client_id, | 217 void UsageTracker::SetUsageCacheEnabled(QuotaClient::ID client_id, |
214 const GURL& origin, | 218 const GURL& origin, |
215 bool enabled) { | 219 bool enabled) { |
216 ClientUsageTracker* client_tracker = GetClientTracker(client_id); | 220 ClientUsageTracker* client_tracker = GetClientTracker(client_id); |
217 DCHECK(client_tracker); | 221 DCHECK(client_tracker); |
218 | 222 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 info->usage = 0; | 270 info->usage = 0; |
267 | 271 |
268 // All the clients have returned their usage data. Dispatch the | 272 // All the clients have returned their usage data. Dispatch the |
269 // pending callbacks. | 273 // pending callbacks. |
270 host_usage_callbacks_.Run(host, MakeTuple(info->usage)); | 274 host_usage_callbacks_.Run(host, MakeTuple(info->usage)); |
271 } | 275 } |
272 | 276 |
273 // ClientUsageTracker ---------------------------------------------------- | 277 // ClientUsageTracker ---------------------------------------------------- |
274 | 278 |
275 ClientUsageTracker::ClientUsageTracker( | 279 ClientUsageTracker::ClientUsageTracker( |
276 UsageTracker* tracker, QuotaClient* client, StorageType type, | 280 UsageTracker* tracker, |
| 281 QuotaClient* client, |
| 282 StorageType type, |
277 SpecialStoragePolicy* special_storage_policy, | 283 SpecialStoragePolicy* special_storage_policy, |
278 StorageMonitor* storage_monitor) | 284 StorageMonitor* storage_monitor) |
279 : tracker_(tracker), | 285 : tracker_(tracker), |
280 client_(client), | 286 client_(client), |
281 type_(type), | 287 type_(type), |
282 storage_monitor_(storage_monitor), | 288 storage_monitor_(storage_monitor), |
283 global_limited_usage_(0), | 289 global_limited_usage_(0), |
284 global_unlimited_usage_(0), | 290 global_unlimited_usage_(0), |
285 global_usage_retrieved_(false), | 291 global_usage_retrieved_(false), |
286 special_storage_policy_(special_storage_policy) { | 292 special_storage_policy_(special_storage_policy) { |
287 DCHECK(tracker_); | 293 DCHECK(tracker_); |
288 DCHECK(client_); | 294 DCHECK(client_); |
289 if (special_storage_policy_.get()) | 295 if (special_storage_policy_.get()) |
290 special_storage_policy_->AddObserver(this); | 296 special_storage_policy_->AddObserver(this); |
291 } | 297 } |
292 | 298 |
293 ClientUsageTracker::~ClientUsageTracker() { | 299 ClientUsageTracker::~ClientUsageTracker() { |
294 if (special_storage_policy_.get()) | 300 if (special_storage_policy_.get()) |
295 special_storage_policy_->RemoveObserver(this); | 301 special_storage_policy_->RemoveObserver(this); |
296 } | 302 } |
297 | 303 |
298 void ClientUsageTracker::GetGlobalLimitedUsage(const UsageCallback& callback) { | 304 void ClientUsageTracker::GetGlobalLimitedUsage(const UsageCallback& callback) { |
299 if (!global_usage_retrieved_) { | 305 if (!global_usage_retrieved_) { |
300 GetGlobalUsage(base::Bind(&DidGetGlobalUsageForLimitedGlobalUsage, | 306 GetGlobalUsage( |
301 callback)); | 307 base::Bind(&DidGetGlobalUsageForLimitedGlobalUsage, callback)); |
302 return; | 308 return; |
303 } | 309 } |
304 | 310 |
305 if (non_cached_limited_origins_by_host_.empty()) { | 311 if (non_cached_limited_origins_by_host_.empty()) { |
306 callback.Run(global_limited_usage_); | 312 callback.Run(global_limited_usage_); |
307 return; | 313 return; |
308 } | 314 } |
309 | 315 |
310 AccumulateInfo* info = new AccumulateInfo; | 316 AccumulateInfo* info = new AccumulateInfo; |
311 info->pending_jobs = non_cached_limited_origins_by_host_.size() + 1; | 317 info->pending_jobs = non_cached_limited_origins_by_host_.size() + 1; |
312 UsageCallback accumulator = base::Bind( | 318 UsageCallback accumulator = |
313 &ClientUsageTracker::AccumulateLimitedOriginUsage, AsWeakPtr(), | 319 base::Bind(&ClientUsageTracker::AccumulateLimitedOriginUsage, |
314 base::Owned(info), callback); | 320 AsWeakPtr(), |
| 321 base::Owned(info), |
| 322 callback); |
315 | 323 |
316 for (OriginSetByHost::iterator host_itr = | 324 for (OriginSetByHost::iterator host_itr = |
317 non_cached_limited_origins_by_host_.begin(); | 325 non_cached_limited_origins_by_host_.begin(); |
318 host_itr != non_cached_limited_origins_by_host_.end(); ++host_itr) { | 326 host_itr != non_cached_limited_origins_by_host_.end(); |
| 327 ++host_itr) { |
319 for (std::set<GURL>::iterator origin_itr = host_itr->second.begin(); | 328 for (std::set<GURL>::iterator origin_itr = host_itr->second.begin(); |
320 origin_itr != host_itr->second.end(); ++origin_itr) | 329 origin_itr != host_itr->second.end(); |
| 330 ++origin_itr) |
321 client_->GetOriginUsage(*origin_itr, type_, accumulator); | 331 client_->GetOriginUsage(*origin_itr, type_, accumulator); |
322 } | 332 } |
323 | 333 |
324 accumulator.Run(global_limited_usage_); | 334 accumulator.Run(global_limited_usage_); |
325 } | 335 } |
326 | 336 |
327 void ClientUsageTracker::GetGlobalUsage(const GlobalUsageCallback& callback) { | 337 void ClientUsageTracker::GetGlobalUsage(const GlobalUsageCallback& callback) { |
328 if (global_usage_retrieved_ && | 338 if (global_usage_retrieved_ && non_cached_limited_origins_by_host_.empty() && |
329 non_cached_limited_origins_by_host_.empty() && | |
330 non_cached_unlimited_origins_by_host_.empty()) { | 339 non_cached_unlimited_origins_by_host_.empty()) { |
331 callback.Run(global_limited_usage_ + global_unlimited_usage_, | 340 callback.Run(global_limited_usage_ + global_unlimited_usage_, |
332 global_unlimited_usage_); | 341 global_unlimited_usage_); |
333 return; | 342 return; |
334 } | 343 } |
335 | 344 |
336 client_->GetOriginsForType(type_, base::Bind( | 345 client_->GetOriginsForType( |
337 &ClientUsageTracker::DidGetOriginsForGlobalUsage, AsWeakPtr(), | 346 type_, |
338 callback)); | 347 base::Bind(&ClientUsageTracker::DidGetOriginsForGlobalUsage, |
| 348 AsWeakPtr(), |
| 349 callback)); |
339 } | 350 } |
340 | 351 |
341 void ClientUsageTracker::GetHostUsage( | 352 void ClientUsageTracker::GetHostUsage(const std::string& host, |
342 const std::string& host, const UsageCallback& callback) { | 353 const UsageCallback& callback) { |
343 if (ContainsKey(cached_hosts_, host) && | 354 if (ContainsKey(cached_hosts_, host) && |
344 !ContainsKey(non_cached_limited_origins_by_host_, host) && | 355 !ContainsKey(non_cached_limited_origins_by_host_, host) && |
345 !ContainsKey(non_cached_unlimited_origins_by_host_, host)) { | 356 !ContainsKey(non_cached_unlimited_origins_by_host_, host)) { |
346 // TODO(kinuko): Drop host_usage_map_ cache periodically. | 357 // TODO(kinuko): Drop host_usage_map_ cache periodically. |
347 callback.Run(GetCachedHostUsage(host)); | 358 callback.Run(GetCachedHostUsage(host)); |
348 return; | 359 return; |
349 } | 360 } |
350 | 361 |
351 if (!host_usage_accumulators_.Add( | 362 if (!host_usage_accumulators_.Add(host, |
352 host, base::Bind(&DidGetHostUsage, callback))) | 363 base::Bind(&DidGetHostUsage, callback))) |
353 return; | 364 return; |
354 client_->GetOriginsForHost(type_, host, base::Bind( | 365 client_->GetOriginsForHost( |
355 &ClientUsageTracker::DidGetOriginsForHostUsage, AsWeakPtr(), host)); | 366 type_, |
| 367 host, |
| 368 base::Bind( |
| 369 &ClientUsageTracker::DidGetOriginsForHostUsage, AsWeakPtr(), host)); |
356 } | 370 } |
357 | 371 |
358 void ClientUsageTracker::UpdateUsageCache( | 372 void ClientUsageTracker::UpdateUsageCache(const GURL& origin, int64 delta) { |
359 const GURL& origin, int64 delta) { | |
360 std::string host = net::GetHostOrSpecFromURL(origin); | 373 std::string host = net::GetHostOrSpecFromURL(origin); |
361 if (cached_hosts_.find(host) != cached_hosts_.end()) { | 374 if (cached_hosts_.find(host) != cached_hosts_.end()) { |
362 if (!IsUsageCacheEnabledForOrigin(origin)) | 375 if (!IsUsageCacheEnabledForOrigin(origin)) |
363 return; | 376 return; |
364 | 377 |
365 cached_usage_by_host_[host][origin] += delta; | 378 cached_usage_by_host_[host][origin] += delta; |
366 if (IsStorageUnlimited(origin)) | 379 if (IsStorageUnlimited(origin)) |
367 global_unlimited_usage_ += delta; | 380 global_unlimited_usage_ += delta; |
368 else | 381 else |
369 global_limited_usage_ += delta; | 382 global_limited_usage_ += delta; |
370 DCHECK_GE(cached_usage_by_host_[host][origin], 0); | 383 DCHECK_GE(cached_usage_by_host_[host][origin], 0); |
371 DCHECK_GE(global_limited_usage_, 0); | 384 DCHECK_GE(global_limited_usage_, 0); |
372 | 385 |
373 // Notify the usage monitor that usage has changed. The storage monitor may | 386 // Notify the usage monitor that usage has changed. The storage monitor may |
374 // be NULL during tests. | 387 // be NULL during tests. |
375 if (storage_monitor_) { | 388 if (storage_monitor_) { |
376 StorageObserver::Filter filter(type_, origin); | 389 StorageObserver::Filter filter(type_, origin); |
377 storage_monitor_->NotifyUsageChange(filter, delta); | 390 storage_monitor_->NotifyUsageChange(filter, delta); |
378 } | 391 } |
379 return; | 392 return; |
380 } | 393 } |
381 | 394 |
382 // We don't know about this host yet, so populate our cache for it. | 395 // We don't know about this host yet, so populate our cache for it. |
383 GetHostUsage(host, base::Bind(&ClientUsageTracker::DidGetHostUsageAfterUpdate, | 396 GetHostUsage(host, |
384 AsWeakPtr(), origin)); | 397 base::Bind(&ClientUsageTracker::DidGetHostUsageAfterUpdate, |
| 398 AsWeakPtr(), |
| 399 origin)); |
385 } | 400 } |
386 | 401 |
387 void ClientUsageTracker::GetCachedHostsUsage( | 402 void ClientUsageTracker::GetCachedHostsUsage( |
388 std::map<std::string, int64>* host_usage) const { | 403 std::map<std::string, int64>* host_usage) const { |
389 DCHECK(host_usage); | 404 DCHECK(host_usage); |
390 for (HostUsageMap::const_iterator host_iter = cached_usage_by_host_.begin(); | 405 for (HostUsageMap::const_iterator host_iter = cached_usage_by_host_.begin(); |
391 host_iter != cached_usage_by_host_.end(); host_iter++) { | 406 host_iter != cached_usage_by_host_.end(); |
| 407 host_iter++) { |
392 const std::string& host = host_iter->first; | 408 const std::string& host = host_iter->first; |
393 (*host_usage)[host] += GetCachedHostUsage(host); | 409 (*host_usage)[host] += GetCachedHostUsage(host); |
394 } | 410 } |
395 } | 411 } |
396 | 412 |
397 void ClientUsageTracker::GetCachedOrigins(std::set<GURL>* origins) const { | 413 void ClientUsageTracker::GetCachedOrigins(std::set<GURL>* origins) const { |
398 DCHECK(origins); | 414 DCHECK(origins); |
399 for (HostUsageMap::const_iterator host_iter = cached_usage_by_host_.begin(); | 415 for (HostUsageMap::const_iterator host_iter = cached_usage_by_host_.begin(); |
400 host_iter != cached_usage_by_host_.end(); host_iter++) { | 416 host_iter != cached_usage_by_host_.end(); |
| 417 host_iter++) { |
401 const UsageMap& origin_map = host_iter->second; | 418 const UsageMap& origin_map = host_iter->second; |
402 for (UsageMap::const_iterator origin_iter = origin_map.begin(); | 419 for (UsageMap::const_iterator origin_iter = origin_map.begin(); |
403 origin_iter != origin_map.end(); origin_iter++) { | 420 origin_iter != origin_map.end(); |
| 421 origin_iter++) { |
404 origins->insert(origin_iter->first); | 422 origins->insert(origin_iter->first); |
405 } | 423 } |
406 } | 424 } |
407 } | 425 } |
408 | 426 |
409 void ClientUsageTracker::SetUsageCacheEnabled(const GURL& origin, | 427 void ClientUsageTracker::SetUsageCacheEnabled(const GURL& origin, |
410 bool enabled) { | 428 bool enabled) { |
411 std::string host = net::GetHostOrSpecFromURL(origin); | 429 std::string host = net::GetHostOrSpecFromURL(origin); |
412 if (!enabled) { | 430 if (!enabled) { |
413 // Erase |origin| from cache and subtract its usage. | 431 // Erase |origin| from cache and subtract its usage. |
(...skipping 13 matching lines...) Expand all Loading... |
427 } | 445 } |
428 } | 446 } |
429 | 447 |
430 if (IsStorageUnlimited(origin)) | 448 if (IsStorageUnlimited(origin)) |
431 non_cached_unlimited_origins_by_host_[host].insert(origin); | 449 non_cached_unlimited_origins_by_host_[host].insert(origin); |
432 else | 450 else |
433 non_cached_limited_origins_by_host_[host].insert(origin); | 451 non_cached_limited_origins_by_host_[host].insert(origin); |
434 } else { | 452 } else { |
435 // Erase |origin| from |non_cached_origins_| and invalidate the usage cache | 453 // Erase |origin| from |non_cached_origins_| and invalidate the usage cache |
436 // for the host. | 454 // for the host. |
437 if (EraseOriginFromOriginSet(&non_cached_limited_origins_by_host_, | 455 if (EraseOriginFromOriginSet( |
438 host, origin) || | 456 &non_cached_limited_origins_by_host_, host, origin) || |
439 EraseOriginFromOriginSet(&non_cached_unlimited_origins_by_host_, | 457 EraseOriginFromOriginSet( |
440 host, origin)) { | 458 &non_cached_unlimited_origins_by_host_, host, origin)) { |
441 cached_hosts_.erase(host); | 459 cached_hosts_.erase(host); |
442 global_usage_retrieved_ = false; | 460 global_usage_retrieved_ = false; |
443 } | 461 } |
444 } | 462 } |
445 } | 463 } |
446 | 464 |
447 void ClientUsageTracker::AccumulateLimitedOriginUsage( | 465 void ClientUsageTracker::AccumulateLimitedOriginUsage( |
448 AccumulateInfo* info, | 466 AccumulateInfo* info, |
449 const UsageCallback& callback, | 467 const UsageCallback& callback, |
450 int64 usage) { | 468 int64 usage) { |
451 info->limited_usage += usage; | 469 info->limited_usage += usage; |
452 if (--info->pending_jobs) | 470 if (--info->pending_jobs) |
453 return; | 471 return; |
454 | 472 |
455 callback.Run(info->limited_usage); | 473 callback.Run(info->limited_usage); |
456 } | 474 } |
457 | 475 |
458 void ClientUsageTracker::DidGetOriginsForGlobalUsage( | 476 void ClientUsageTracker::DidGetOriginsForGlobalUsage( |
459 const GlobalUsageCallback& callback, | 477 const GlobalUsageCallback& callback, |
460 const std::set<GURL>& origins) { | 478 const std::set<GURL>& origins) { |
461 OriginSetByHost origins_by_host; | 479 OriginSetByHost origins_by_host; |
462 for (std::set<GURL>::const_iterator itr = origins.begin(); | 480 for (std::set<GURL>::const_iterator itr = origins.begin(); |
463 itr != origins.end(); ++itr) | 481 itr != origins.end(); |
| 482 ++itr) |
464 origins_by_host[net::GetHostOrSpecFromURL(*itr)].insert(*itr); | 483 origins_by_host[net::GetHostOrSpecFromURL(*itr)].insert(*itr); |
465 | 484 |
466 AccumulateInfo* info = new AccumulateInfo; | 485 AccumulateInfo* info = new AccumulateInfo; |
467 // Getting host usage may synchronously return the result if the usage is | 486 // Getting host usage may synchronously return the result if the usage is |
468 // cached, which may in turn dispatch the completion callback before we finish | 487 // cached, which may in turn dispatch the completion callback before we finish |
469 // looping over all hosts (because info->pending_jobs may reach 0 during the | 488 // looping over all hosts (because info->pending_jobs may reach 0 during the |
470 // loop). To avoid this, we add one more pending host as a sentinel and | 489 // loop). To avoid this, we add one more pending host as a sentinel and |
471 // fire the sentinel callback at the end. | 490 // fire the sentinel callback at the end. |
472 info->pending_jobs = origins_by_host.size() + 1; | 491 info->pending_jobs = origins_by_host.size() + 1; |
473 HostUsageAccumulator accumulator = | 492 HostUsageAccumulator accumulator = |
474 base::Bind(&ClientUsageTracker::AccumulateHostUsage, AsWeakPtr(), | 493 base::Bind(&ClientUsageTracker::AccumulateHostUsage, |
475 base::Owned(info), callback); | 494 AsWeakPtr(), |
| 495 base::Owned(info), |
| 496 callback); |
476 | 497 |
477 for (OriginSetByHost::iterator itr = origins_by_host.begin(); | 498 for (OriginSetByHost::iterator itr = origins_by_host.begin(); |
478 itr != origins_by_host.end(); ++itr) { | 499 itr != origins_by_host.end(); |
| 500 ++itr) { |
479 if (host_usage_accumulators_.Add(itr->first, accumulator)) | 501 if (host_usage_accumulators_.Add(itr->first, accumulator)) |
480 GetUsageForOrigins(itr->first, itr->second); | 502 GetUsageForOrigins(itr->first, itr->second); |
481 } | 503 } |
482 | 504 |
483 // Fire the sentinel as we've now called GetUsageForOrigins for all clients. | 505 // Fire the sentinel as we've now called GetUsageForOrigins for all clients. |
484 accumulator.Run(0, 0); | 506 accumulator.Run(0, 0); |
485 } | 507 } |
486 | 508 |
487 void ClientUsageTracker::AccumulateHostUsage( | 509 void ClientUsageTracker::AccumulateHostUsage( |
488 AccumulateInfo* info, | 510 AccumulateInfo* info, |
(...skipping 12 matching lines...) Expand all Loading... |
501 callback.Run(info->limited_usage + info->unlimited_usage, | 523 callback.Run(info->limited_usage + info->unlimited_usage, |
502 info->unlimited_usage); | 524 info->unlimited_usage); |
503 } | 525 } |
504 | 526 |
505 void ClientUsageTracker::DidGetOriginsForHostUsage( | 527 void ClientUsageTracker::DidGetOriginsForHostUsage( |
506 const std::string& host, | 528 const std::string& host, |
507 const std::set<GURL>& origins) { | 529 const std::set<GURL>& origins) { |
508 GetUsageForOrigins(host, origins); | 530 GetUsageForOrigins(host, origins); |
509 } | 531 } |
510 | 532 |
511 void ClientUsageTracker::GetUsageForOrigins( | 533 void ClientUsageTracker::GetUsageForOrigins(const std::string& host, |
512 const std::string& host, | 534 const std::set<GURL>& origins) { |
513 const std::set<GURL>& origins) { | |
514 AccumulateInfo* info = new AccumulateInfo; | 535 AccumulateInfo* info = new AccumulateInfo; |
515 // Getting origin usage may synchronously return the result if the usage is | 536 // Getting origin usage may synchronously return the result if the usage is |
516 // cached, which may in turn dispatch the completion callback before we finish | 537 // cached, which may in turn dispatch the completion callback before we finish |
517 // looping over all origins (because info->pending_jobs may reach 0 during the | 538 // looping over all origins (because info->pending_jobs may reach 0 during the |
518 // loop). To avoid this, we add one more pending origin as a sentinel and | 539 // loop). To avoid this, we add one more pending origin as a sentinel and |
519 // fire the sentinel callback at the end. | 540 // fire the sentinel callback at the end. |
520 info->pending_jobs = origins.size() + 1; | 541 info->pending_jobs = origins.size() + 1; |
521 OriginUsageAccumulator accumulator = | 542 OriginUsageAccumulator accumulator = |
522 base::Bind(&ClientUsageTracker::AccumulateOriginUsage, AsWeakPtr(), | 543 base::Bind(&ClientUsageTracker::AccumulateOriginUsage, |
523 base::Owned(info), host); | 544 AsWeakPtr(), |
| 545 base::Owned(info), |
| 546 host); |
524 | 547 |
525 for (std::set<GURL>::const_iterator itr = origins.begin(); | 548 for (std::set<GURL>::const_iterator itr = origins.begin(); |
526 itr != origins.end(); ++itr) { | 549 itr != origins.end(); |
| 550 ++itr) { |
527 DCHECK_EQ(host, net::GetHostOrSpecFromURL(*itr)); | 551 DCHECK_EQ(host, net::GetHostOrSpecFromURL(*itr)); |
528 | 552 |
529 int64 origin_usage = 0; | 553 int64 origin_usage = 0; |
530 if (GetCachedOriginUsage(*itr, &origin_usage)) { | 554 if (GetCachedOriginUsage(*itr, &origin_usage)) { |
531 accumulator.Run(*itr, origin_usage); | 555 accumulator.Run(*itr, origin_usage); |
532 } else { | 556 } else { |
533 client_->GetOriginUsage(*itr, type_, base::Bind( | 557 client_->GetOriginUsage( |
534 &DidGetOriginUsage, accumulator, *itr)); | 558 *itr, type_, base::Bind(&DidGetOriginUsage, accumulator, *itr)); |
535 } | 559 } |
536 } | 560 } |
537 | 561 |
538 // Fire the sentinel as we've now called GetOriginUsage for all clients. | 562 // Fire the sentinel as we've now called GetOriginUsage for all clients. |
539 accumulator.Run(GURL(), 0); | 563 accumulator.Run(GURL(), 0); |
540 } | 564 } |
541 | 565 |
542 void ClientUsageTracker::AccumulateOriginUsage(AccumulateInfo* info, | 566 void ClientUsageTracker::AccumulateOriginUsage(AccumulateInfo* info, |
543 const std::string& host, | 567 const std::string& host, |
544 const GURL& origin, | 568 const GURL& origin, |
(...skipping 10 matching lines...) Expand all Loading... |
555 AddCachedOrigin(origin, usage); | 579 AddCachedOrigin(origin, usage); |
556 } | 580 } |
557 if (--info->pending_jobs) | 581 if (--info->pending_jobs) |
558 return; | 582 return; |
559 | 583 |
560 AddCachedHost(host); | 584 AddCachedHost(host); |
561 host_usage_accumulators_.Run( | 585 host_usage_accumulators_.Run( |
562 host, MakeTuple(info->limited_usage, info->unlimited_usage)); | 586 host, MakeTuple(info->limited_usage, info->unlimited_usage)); |
563 } | 587 } |
564 | 588 |
565 void ClientUsageTracker::DidGetHostUsageAfterUpdate( | 589 void ClientUsageTracker::DidGetHostUsageAfterUpdate(const GURL& origin, |
566 const GURL& origin, int64 usage) { | 590 int64 usage) { |
567 if (!storage_monitor_) | 591 if (!storage_monitor_) |
568 return; | 592 return; |
569 | 593 |
570 StorageObserver::Filter filter(type_, origin); | 594 StorageObserver::Filter filter(type_, origin); |
571 storage_monitor_->NotifyUsageChange(filter, 0); | 595 storage_monitor_->NotifyUsageChange(filter, 0); |
572 } | 596 } |
573 | 597 |
574 void ClientUsageTracker::AddCachedOrigin( | 598 void ClientUsageTracker::AddCachedOrigin(const GURL& origin, int64 new_usage) { |
575 const GURL& origin, int64 new_usage) { | |
576 DCHECK(IsUsageCacheEnabledForOrigin(origin)); | 599 DCHECK(IsUsageCacheEnabledForOrigin(origin)); |
577 | 600 |
578 std::string host = net::GetHostOrSpecFromURL(origin); | 601 std::string host = net::GetHostOrSpecFromURL(origin); |
579 int64* usage = &cached_usage_by_host_[host][origin]; | 602 int64* usage = &cached_usage_by_host_[host][origin]; |
580 int64 delta = new_usage - *usage; | 603 int64 delta = new_usage - *usage; |
581 *usage = new_usage; | 604 *usage = new_usage; |
582 if (delta) { | 605 if (delta) { |
583 if (IsStorageUnlimited(origin)) | 606 if (IsStorageUnlimited(origin)) |
584 global_unlimited_usage_ += delta; | 607 global_unlimited_usage_ += delta; |
585 else | 608 else |
586 global_limited_usage_ += delta; | 609 global_limited_usage_ += delta; |
587 } | 610 } |
588 DCHECK_GE(*usage, 0); | 611 DCHECK_GE(*usage, 0); |
589 DCHECK_GE(global_limited_usage_, 0); | 612 DCHECK_GE(global_limited_usage_, 0); |
590 } | 613 } |
591 | 614 |
592 void ClientUsageTracker::AddCachedHost(const std::string& host) { | 615 void ClientUsageTracker::AddCachedHost(const std::string& host) { |
593 cached_hosts_.insert(host); | 616 cached_hosts_.insert(host); |
594 } | 617 } |
595 | 618 |
596 int64 ClientUsageTracker::GetCachedHostUsage(const std::string& host) const { | 619 int64 ClientUsageTracker::GetCachedHostUsage(const std::string& host) const { |
597 HostUsageMap::const_iterator found = cached_usage_by_host_.find(host); | 620 HostUsageMap::const_iterator found = cached_usage_by_host_.find(host); |
598 if (found == cached_usage_by_host_.end()) | 621 if (found == cached_usage_by_host_.end()) |
599 return 0; | 622 return 0; |
600 | 623 |
601 int64 usage = 0; | 624 int64 usage = 0; |
602 const UsageMap& map = found->second; | 625 const UsageMap& map = found->second; |
603 for (UsageMap::const_iterator iter = map.begin(); | 626 for (UsageMap::const_iterator iter = map.begin(); iter != map.end(); ++iter) { |
604 iter != map.end(); ++iter) { | |
605 usage += iter->second; | 627 usage += iter->second; |
606 } | 628 } |
607 return usage; | 629 return usage; |
608 } | 630 } |
609 | 631 |
610 bool ClientUsageTracker::GetCachedOriginUsage( | 632 bool ClientUsageTracker::GetCachedOriginUsage(const GURL& origin, |
611 const GURL& origin, | 633 int64* usage) const { |
612 int64* usage) const { | |
613 std::string host = net::GetHostOrSpecFromURL(origin); | 634 std::string host = net::GetHostOrSpecFromURL(origin); |
614 HostUsageMap::const_iterator found_host = cached_usage_by_host_.find(host); | 635 HostUsageMap::const_iterator found_host = cached_usage_by_host_.find(host); |
615 if (found_host == cached_usage_by_host_.end()) | 636 if (found_host == cached_usage_by_host_.end()) |
616 return false; | 637 return false; |
617 | 638 |
618 UsageMap::const_iterator found = found_host->second.find(origin); | 639 UsageMap::const_iterator found = found_host->second.find(origin); |
619 if (found == found_host->second.end()) | 640 if (found == found_host->second.end()) |
620 return false; | 641 return false; |
621 | 642 |
622 DCHECK(IsUsageCacheEnabledForOrigin(origin)); | 643 DCHECK(IsUsageCacheEnabledForOrigin(origin)); |
623 *usage = found->second; | 644 *usage = found->second; |
624 return true; | 645 return true; |
625 } | 646 } |
626 | 647 |
627 bool ClientUsageTracker::IsUsageCacheEnabledForOrigin( | 648 bool ClientUsageTracker::IsUsageCacheEnabledForOrigin( |
628 const GURL& origin) const { | 649 const GURL& origin) const { |
629 std::string host = net::GetHostOrSpecFromURL(origin); | 650 std::string host = net::GetHostOrSpecFromURL(origin); |
630 return !OriginSetContainsOrigin(non_cached_limited_origins_by_host_, | 651 return !OriginSetContainsOrigin( |
631 host, origin) && | 652 non_cached_limited_origins_by_host_, host, origin) && |
632 !OriginSetContainsOrigin(non_cached_unlimited_origins_by_host_, | 653 !OriginSetContainsOrigin( |
633 host, origin); | 654 non_cached_unlimited_origins_by_host_, host, origin); |
634 } | 655 } |
635 | 656 |
636 void ClientUsageTracker::OnGranted(const GURL& origin, | 657 void ClientUsageTracker::OnGranted(const GURL& origin, int change_flags) { |
637 int change_flags) { | |
638 DCHECK(CalledOnValidThread()); | 658 DCHECK(CalledOnValidThread()); |
639 if (change_flags & SpecialStoragePolicy::STORAGE_UNLIMITED) { | 659 if (change_flags & SpecialStoragePolicy::STORAGE_UNLIMITED) { |
640 int64 usage = 0; | 660 int64 usage = 0; |
641 if (GetCachedOriginUsage(origin, &usage)) { | 661 if (GetCachedOriginUsage(origin, &usage)) { |
642 global_unlimited_usage_ += usage; | 662 global_unlimited_usage_ += usage; |
643 global_limited_usage_ -= usage; | 663 global_limited_usage_ -= usage; |
644 } | 664 } |
645 | 665 |
646 std::string host = net::GetHostOrSpecFromURL(origin); | 666 std::string host = net::GetHostOrSpecFromURL(origin); |
647 if (EraseOriginFromOriginSet(&non_cached_limited_origins_by_host_, | 667 if (EraseOriginFromOriginSet( |
648 host, origin)) | 668 &non_cached_limited_origins_by_host_, host, origin)) |
649 non_cached_unlimited_origins_by_host_[host].insert(origin); | 669 non_cached_unlimited_origins_by_host_[host].insert(origin); |
650 } | 670 } |
651 } | 671 } |
652 | 672 |
653 void ClientUsageTracker::OnRevoked(const GURL& origin, | 673 void ClientUsageTracker::OnRevoked(const GURL& origin, int change_flags) { |
654 int change_flags) { | |
655 DCHECK(CalledOnValidThread()); | 674 DCHECK(CalledOnValidThread()); |
656 if (change_flags & SpecialStoragePolicy::STORAGE_UNLIMITED) { | 675 if (change_flags & SpecialStoragePolicy::STORAGE_UNLIMITED) { |
657 int64 usage = 0; | 676 int64 usage = 0; |
658 if (GetCachedOriginUsage(origin, &usage)) { | 677 if (GetCachedOriginUsage(origin, &usage)) { |
659 global_unlimited_usage_ -= usage; | 678 global_unlimited_usage_ -= usage; |
660 global_limited_usage_ += usage; | 679 global_limited_usage_ += usage; |
661 } | 680 } |
662 | 681 |
663 std::string host = net::GetHostOrSpecFromURL(origin); | 682 std::string host = net::GetHostOrSpecFromURL(origin); |
664 if (EraseOriginFromOriginSet(&non_cached_unlimited_origins_by_host_, | 683 if (EraseOriginFromOriginSet( |
665 host, origin)) | 684 &non_cached_unlimited_origins_by_host_, host, origin)) |
666 non_cached_limited_origins_by_host_[host].insert(origin); | 685 non_cached_limited_origins_by_host_[host].insert(origin); |
667 } | 686 } |
668 } | 687 } |
669 | 688 |
670 void ClientUsageTracker::OnCleared() { | 689 void ClientUsageTracker::OnCleared() { |
671 DCHECK(CalledOnValidThread()); | 690 DCHECK(CalledOnValidThread()); |
672 global_limited_usage_ += global_unlimited_usage_; | 691 global_limited_usage_ += global_unlimited_usage_; |
673 global_unlimited_usage_ = 0; | 692 global_unlimited_usage_ = 0; |
674 | 693 |
675 for (OriginSetByHost::const_iterator host_itr = | 694 for (OriginSetByHost::const_iterator host_itr = |
676 non_cached_unlimited_origins_by_host_.begin(); | 695 non_cached_unlimited_origins_by_host_.begin(); |
677 host_itr != non_cached_unlimited_origins_by_host_.end(); | 696 host_itr != non_cached_unlimited_origins_by_host_.end(); |
678 ++host_itr) { | 697 ++host_itr) { |
679 for (std::set<GURL>::const_iterator origin_itr = host_itr->second.begin(); | 698 for (std::set<GURL>::const_iterator origin_itr = host_itr->second.begin(); |
680 origin_itr != host_itr->second.end(); | 699 origin_itr != host_itr->second.end(); |
681 ++origin_itr) | 700 ++origin_itr) |
682 non_cached_limited_origins_by_host_[host_itr->first].insert(*origin_itr); | 701 non_cached_limited_origins_by_host_[host_itr->first].insert(*origin_itr); |
683 } | 702 } |
684 non_cached_unlimited_origins_by_host_.clear(); | 703 non_cached_unlimited_origins_by_host_.clear(); |
685 } | 704 } |
686 | 705 |
687 bool ClientUsageTracker::IsStorageUnlimited(const GURL& origin) const { | 706 bool ClientUsageTracker::IsStorageUnlimited(const GURL& origin) const { |
688 if (type_ == kStorageTypeSyncable) | 707 if (type_ == kStorageTypeSyncable) |
689 return false; | 708 return false; |
690 return special_storage_policy_.get() && | 709 return special_storage_policy_.get() && |
691 special_storage_policy_->IsStorageUnlimited(origin); | 710 special_storage_policy_->IsStorageUnlimited(origin); |
692 } | 711 } |
693 | 712 |
694 } // namespace quota | 713 } // namespace quota |
OLD | NEW |