OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 #include "webkit/quota/usage_tracker.h" | |
6 | |
7 #include <algorithm> | |
8 #include <deque> | |
9 #include <set> | |
10 #include <string> | |
11 #include <vector> | |
12 | |
13 #include "base/bind.h" | |
14 #include "base/message_loop_proxy.h" | |
15 #include "base/stl_util.h" | |
16 #include "net/base/net_util.h" | |
17 | |
18 namespace quota { | |
19 | |
20 namespace { | |
21 | |
22 typedef ClientUsageTracker::OriginUsageAccumulator OriginUsageAccumulator; | |
23 typedef ClientUsageTracker::OriginSetByHost OriginSetByHost; | |
24 | |
25 void DidGetOriginUsage(const OriginUsageAccumulator& accumulator, | |
26 const GURL& origin, | |
27 int64 usage) { | |
28 accumulator.Run(origin, usage); | |
29 } | |
30 | |
31 void DidGetHostUsage(const UsageCallback& callback, | |
32 int64 cached_usage, | |
33 int64 non_cached_usage) { | |
34 DCHECK_GE(cached_usage, 0); | |
35 DCHECK_GE(non_cached_usage, 0); | |
36 callback.Run(cached_usage + non_cached_usage); | |
37 } | |
38 | |
39 void NoopHostUsageCallback(int64 usage) {} | |
40 | |
41 bool EraseOriginFromOriginSet(OriginSetByHost* origins_by_host, | |
42 const std::string& host, | |
43 const GURL& origin) { | |
44 OriginSetByHost::iterator found = origins_by_host->find(host); | |
45 if (found == origins_by_host->end()) | |
46 return false; | |
47 | |
48 if (!found->second.erase(origin)) | |
49 return false; | |
50 | |
51 if (found->second.empty()) | |
52 origins_by_host->erase(host); | |
53 return true; | |
54 } | |
55 | |
56 bool OriginSetContainsOrigin(const OriginSetByHost& origins, | |
57 const std::string& host, | |
58 const GURL& origin) { | |
59 OriginSetByHost::const_iterator itr = origins.find(host); | |
60 return itr != origins.end() && ContainsKey(itr->second, origin); | |
61 } | |
62 | |
63 void DidGetGlobalUsageForLimitedGlobalUsage(const UsageCallback& callback, | |
64 int64 total_global_usage, | |
65 int64 global_unlimited_usage) { | |
66 callback.Run(total_global_usage - global_unlimited_usage); | |
67 } | |
68 | |
69 } // namespace | |
70 | |
71 // UsageTracker ---------------------------------------------------------- | |
72 | |
73 UsageTracker::UsageTracker(const QuotaClientList& clients, | |
74 StorageType type, | |
75 SpecialStoragePolicy* special_storage_policy) | |
76 : type_(type), | |
77 weak_factory_(this) { | |
78 for (QuotaClientList::const_iterator iter = clients.begin(); | |
79 iter != clients.end(); | |
80 ++iter) { | |
81 client_tracker_map_[(*iter)->id()] = | |
82 new ClientUsageTracker(this, *iter, type, special_storage_policy); | |
83 } | |
84 } | |
85 | |
86 UsageTracker::~UsageTracker() { | |
87 STLDeleteValues(&client_tracker_map_); | |
88 } | |
89 | |
90 ClientUsageTracker* UsageTracker::GetClientTracker(QuotaClient::ID client_id) { | |
91 ClientTrackerMap::iterator found = client_tracker_map_.find(client_id); | |
92 if (found != client_tracker_map_.end()) | |
93 return found->second; | |
94 return NULL; | |
95 } | |
96 | |
97 void UsageTracker::GetGlobalLimitedUsage(const UsageCallback& callback) { | |
98 GetGlobalUsage(base::Bind(&DidGetGlobalUsageForLimitedGlobalUsage, callback)); | |
99 } | |
100 | |
101 void UsageTracker::GetGlobalUsage(const GlobalUsageCallback& callback) { | |
102 if (!global_usage_callbacks_.Add(callback)) | |
103 return; | |
104 | |
105 AccumulateInfo* info = new AccumulateInfo; | |
106 // Calling GetGlobalUsage(accumulator) may synchronously | |
107 // return if the usage is cached, which may in turn dispatch | |
108 // the completion callback before we finish looping over | |
109 // all clients (because info->pending_clients may reach 0 | |
110 // during the loop). | |
111 // To avoid this, we add one more pending client as a sentinel | |
112 // and fire the sentinel callback at the end. | |
113 info->pending_clients = client_tracker_map_.size() + 1; | |
114 GlobalUsageCallback accumulator = base::Bind( | |
115 &UsageTracker::AccumulateClientGlobalUsage, weak_factory_.GetWeakPtr(), | |
116 base::Owned(info)); | |
117 | |
118 for (ClientTrackerMap::iterator iter = client_tracker_map_.begin(); | |
119 iter != client_tracker_map_.end(); | |
120 ++iter) | |
121 iter->second->GetGlobalUsage(accumulator); | |
122 | |
123 // Fire the sentinel as we've now called GetGlobalUsage for all clients. | |
124 accumulator.Run(0, 0); | |
125 } | |
126 | |
127 void UsageTracker::GetHostUsage(const std::string& host, | |
128 const UsageCallback& callback) { | |
129 if (!host_usage_callbacks_.Add(host, callback)) | |
130 return; | |
131 | |
132 AccumulateInfo* info = new AccumulateInfo; | |
133 // Calling GetHostUsage(accumulator) may synchronously | |
134 // return if the usage is cached, which may in turn dispatch | |
135 // the completion callback before we finish looping over | |
136 // all clients (because info->pending_clients may reach 0 | |
137 // during the loop). | |
138 // To avoid this, we add one more pending client as a sentinel | |
139 // and fire the sentinel callback at the end. | |
140 info->pending_clients = client_tracker_map_.size() + 1; | |
141 UsageCallback accumulator = base::Bind( | |
142 &UsageTracker::AccumulateClientHostUsage, weak_factory_.GetWeakPtr(), | |
143 base::Owned(info), host); | |
144 | |
145 for (ClientTrackerMap::iterator iter = client_tracker_map_.begin(); | |
146 iter != client_tracker_map_.end(); | |
147 ++iter) | |
148 iter->second->GetHostUsage(host, accumulator); | |
149 | |
150 // Fire the sentinel as we've now called GetHostUsage for all clients. | |
151 accumulator.Run(0); | |
152 } | |
153 | |
154 void UsageTracker::UpdateUsageCache( | |
155 QuotaClient::ID client_id, const GURL& origin, int64 delta) { | |
156 ClientUsageTracker* client_tracker = GetClientTracker(client_id); | |
157 DCHECK(client_tracker); | |
158 client_tracker->UpdateUsageCache(origin, delta); | |
159 } | |
160 | |
161 void UsageTracker::GetCachedHostsUsage( | |
162 std::map<std::string, int64>* host_usage) const { | |
163 DCHECK(host_usage); | |
164 host_usage->clear(); | |
165 for (ClientTrackerMap::const_iterator iter = client_tracker_map_.begin(); | |
166 iter != client_tracker_map_.end(); ++iter) { | |
167 iter->second->GetCachedHostsUsage(host_usage); | |
168 } | |
169 } | |
170 | |
171 void UsageTracker::GetCachedOrigins(std::set<GURL>* origins) const { | |
172 DCHECK(origins); | |
173 origins->clear(); | |
174 for (ClientTrackerMap::const_iterator iter = client_tracker_map_.begin(); | |
175 iter != client_tracker_map_.end(); ++iter) { | |
176 iter->second->GetCachedOrigins(origins); | |
177 } | |
178 } | |
179 | |
180 void UsageTracker::SetUsageCacheEnabled(QuotaClient::ID client_id, | |
181 const GURL& origin, | |
182 bool enabled) { | |
183 ClientUsageTracker* client_tracker = GetClientTracker(client_id); | |
184 DCHECK(client_tracker); | |
185 | |
186 client_tracker->SetUsageCacheEnabled(origin, enabled); | |
187 } | |
188 | |
189 void UsageTracker::AccumulateClientGlobalUsage(AccumulateInfo* info, | |
190 int64 usage, | |
191 int64 unlimited_usage) { | |
192 info->usage += usage; | |
193 info->unlimited_usage += unlimited_usage; | |
194 | |
195 if (--info->pending_clients) | |
196 return; | |
197 | |
198 // Defend against confusing inputs from clients. | |
199 if (info->usage < 0) | |
200 info->usage = 0; | |
201 | |
202 // TODO(michaeln): The unlimited number is not trustworthy, it | |
203 // can get out of whack when apps are installed or uninstalled. | |
204 if (info->unlimited_usage > info->usage) | |
205 info->unlimited_usage = info->usage; | |
206 else if (info->unlimited_usage < 0) | |
207 info->unlimited_usage = 0; | |
208 | |
209 // All the clients have returned their usage data. Dispatch the | |
210 // pending callbacks. | |
211 global_usage_callbacks_.Run(MakeTuple(info->usage, info->unlimited_usage)); | |
212 } | |
213 | |
214 void UsageTracker::AccumulateClientHostUsage(AccumulateInfo* info, | |
215 const std::string& host, | |
216 int64 usage) { | |
217 info->usage += usage; | |
218 if (--info->pending_clients) | |
219 return; | |
220 | |
221 // Defend against confusing inputs from clients. | |
222 if (info->usage < 0) | |
223 info->usage = 0; | |
224 | |
225 // All the clients have returned their usage data. Dispatch the | |
226 // pending callbacks. | |
227 host_usage_callbacks_.Run(host, MakeTuple(info->usage)); | |
228 } | |
229 | |
230 // ClientUsageTracker ---------------------------------------------------- | |
231 | |
232 ClientUsageTracker::ClientUsageTracker( | |
233 UsageTracker* tracker, QuotaClient* client, StorageType type, | |
234 SpecialStoragePolicy* special_storage_policy) | |
235 : tracker_(tracker), | |
236 client_(client), | |
237 type_(type), | |
238 global_limited_usage_(0), | |
239 global_unlimited_usage_(0), | |
240 global_usage_retrieved_(false), | |
241 special_storage_policy_(special_storage_policy) { | |
242 DCHECK(tracker_); | |
243 DCHECK(client_); | |
244 if (special_storage_policy_) | |
245 special_storage_policy_->AddObserver(this); | |
246 } | |
247 | |
248 ClientUsageTracker::~ClientUsageTracker() { | |
249 if (special_storage_policy_) | |
250 special_storage_policy_->RemoveObserver(this); | |
251 } | |
252 | |
253 void ClientUsageTracker::GetGlobalUsage(const GlobalUsageCallback& callback) { | |
254 if (global_usage_retrieved_ && | |
255 non_cached_limited_origins_by_host_.empty() && | |
256 non_cached_unlimited_origins_by_host_.empty()) { | |
257 callback.Run(global_limited_usage_ + global_unlimited_usage_, | |
258 global_unlimited_usage_); | |
259 return; | |
260 } | |
261 | |
262 client_->GetOriginsForType(type_, base::Bind( | |
263 &ClientUsageTracker::DidGetOriginsForGlobalUsage, AsWeakPtr(), | |
264 callback)); | |
265 } | |
266 | |
267 void ClientUsageTracker::GetHostUsage( | |
268 const std::string& host, const UsageCallback& callback) { | |
269 if (ContainsKey(cached_hosts_, host) && | |
270 !ContainsKey(non_cached_limited_origins_by_host_, host) && | |
271 !ContainsKey(non_cached_unlimited_origins_by_host_, host)) { | |
272 // TODO(kinuko): Drop host_usage_map_ cache periodically. | |
273 callback.Run(GetCachedHostUsage(host)); | |
274 return; | |
275 } | |
276 | |
277 if (!host_usage_accumulators_.Add(host, base::Bind( | |
278 &DidGetHostUsage, callback))) | |
279 return; | |
280 client_->GetOriginsForHost(type_, host, base::Bind( | |
281 &ClientUsageTracker::DidGetOriginsForHostUsage, AsWeakPtr(), host)); | |
282 } | |
283 | |
284 void ClientUsageTracker::UpdateUsageCache( | |
285 const GURL& origin, int64 delta) { | |
286 std::string host = net::GetHostOrSpecFromURL(origin); | |
287 if (cached_hosts_.find(host) != cached_hosts_.end()) { | |
288 if (!IsUsageCacheEnabledForOrigin(origin)) | |
289 return; | |
290 | |
291 cached_usage_by_host_[host][origin] += delta; | |
292 if (IsStorageUnlimited(origin)) | |
293 global_unlimited_usage_ += delta; | |
294 else | |
295 global_limited_usage_ += delta; | |
296 DCHECK_GE(cached_usage_by_host_[host][origin], 0); | |
297 DCHECK_GE(global_limited_usage_, 0); | |
298 return; | |
299 } | |
300 | |
301 // We don't know about this host yet, so populate our cache for it. | |
302 GetHostUsage(host, base::Bind(&NoopHostUsageCallback)); | |
303 } | |
304 | |
305 void ClientUsageTracker::GetCachedHostsUsage( | |
306 std::map<std::string, int64>* host_usage) const { | |
307 DCHECK(host_usage); | |
308 for (HostUsageMap::const_iterator host_iter = cached_usage_by_host_.begin(); | |
309 host_iter != cached_usage_by_host_.end(); host_iter++) { | |
310 const std::string& host = host_iter->first; | |
311 (*host_usage)[host] += GetCachedHostUsage(host); | |
312 } | |
313 } | |
314 | |
315 void ClientUsageTracker::GetCachedOrigins(std::set<GURL>* origins) const { | |
316 DCHECK(origins); | |
317 for (HostUsageMap::const_iterator host_iter = cached_usage_by_host_.begin(); | |
318 host_iter != cached_usage_by_host_.end(); host_iter++) { | |
319 const UsageMap& origin_map = host_iter->second; | |
320 for (UsageMap::const_iterator origin_iter = origin_map.begin(); | |
321 origin_iter != origin_map.end(); origin_iter++) { | |
322 origins->insert(origin_iter->first); | |
323 } | |
324 } | |
325 } | |
326 | |
327 void ClientUsageTracker::SetUsageCacheEnabled(const GURL& origin, | |
328 bool enabled) { | |
329 std::string host = net::GetHostOrSpecFromURL(origin); | |
330 if (!enabled) { | |
331 // Erase |origin| from cache and subtract its usage. | |
332 HostUsageMap::iterator found_host = cached_usage_by_host_.find(host); | |
333 if (found_host != cached_usage_by_host_.end()) { | |
334 UsageMap& cached_usage_for_host = found_host->second; | |
335 | |
336 UsageMap::iterator found = cached_usage_for_host.find(origin); | |
337 if (found != cached_usage_for_host.end()) { | |
338 int64 usage = found->second; | |
339 UpdateUsageCache(origin, -usage); | |
340 cached_usage_for_host.erase(found); | |
341 if (cached_usage_for_host.empty()) { | |
342 cached_usage_by_host_.erase(found_host); | |
343 cached_hosts_.erase(host); | |
344 } | |
345 } | |
346 } | |
347 | |
348 if (IsStorageUnlimited(origin)) | |
349 non_cached_unlimited_origins_by_host_[host].insert(origin); | |
350 else | |
351 non_cached_limited_origins_by_host_[host].insert(origin); | |
352 } else { | |
353 // Erase |origin| from |non_cached_origins_| and invalidate the usage cache | |
354 // for the host. | |
355 if (EraseOriginFromOriginSet(&non_cached_limited_origins_by_host_, | |
356 host, origin) || | |
357 EraseOriginFromOriginSet(&non_cached_unlimited_origins_by_host_, | |
358 host, origin)) { | |
359 cached_hosts_.erase(host); | |
360 global_usage_retrieved_ = false; | |
361 } | |
362 } | |
363 } | |
364 | |
365 void ClientUsageTracker::DidGetOriginsForGlobalUsage( | |
366 const GlobalUsageCallback& callback, | |
367 const std::set<GURL>& origins) { | |
368 OriginSetByHost origins_by_host; | |
369 for (std::set<GURL>::const_iterator itr = origins.begin(); | |
370 itr != origins.end(); ++itr) | |
371 origins_by_host[net::GetHostOrSpecFromURL(*itr)].insert(*itr); | |
372 | |
373 AccumulateInfo* info = new AccumulateInfo; | |
374 // Getting host usage may synchronously return the result if the usage is | |
375 // cached, which may in turn dispatch the completion callback before we finish | |
376 // looping over all hosts (because info->pending_jobs may reach 0 during the | |
377 // loop). To avoid this, we add one more pending host as a sentinel and | |
378 // fire the sentinel callback at the end. | |
379 info->pending_jobs = origins_by_host.size() + 1; | |
380 HostUsageAccumulator accumulator = | |
381 base::Bind(&ClientUsageTracker::AccumulateHostUsage, AsWeakPtr(), | |
382 base::Owned(info), callback); | |
383 | |
384 for (OriginSetByHost::iterator itr = origins_by_host.begin(); | |
385 itr != origins_by_host.end(); ++itr) { | |
386 if (host_usage_accumulators_.Add(itr->first, accumulator)) | |
387 GetUsageForOrigins(itr->first, itr->second); | |
388 } | |
389 | |
390 // Fire the sentinel as we've now called GetUsageForOrigins for all clients. | |
391 accumulator.Run(0, 0); | |
392 } | |
393 | |
394 void ClientUsageTracker::AccumulateHostUsage( | |
395 AccumulateInfo* info, | |
396 const GlobalUsageCallback& callback, | |
397 int64 cached_usage, | |
398 int64 non_cached_usage) { | |
399 info->cached_usage += cached_usage; | |
400 info->non_cached_usage += non_cached_usage; | |
401 if (--info->pending_jobs) | |
402 return; | |
403 | |
404 int64 total_usage = info->cached_usage + info->non_cached_usage; | |
405 int64 unlimited_usage = global_unlimited_usage_ + info->non_cached_usage; | |
406 | |
407 DCHECK_GE(total_usage, 0); | |
408 DCHECK_GE(unlimited_usage, 0); | |
409 if (unlimited_usage > total_usage) | |
410 unlimited_usage = total_usage; | |
411 | |
412 global_usage_retrieved_ = true; | |
413 callback.Run(total_usage, unlimited_usage); | |
414 } | |
415 | |
416 void ClientUsageTracker::DidGetOriginsForHostUsage( | |
417 const std::string& host, | |
418 const std::set<GURL>& origins) { | |
419 GetUsageForOrigins(host, origins); | |
420 } | |
421 | |
422 void ClientUsageTracker::GetUsageForOrigins( | |
423 const std::string& host, | |
424 const std::set<GURL>& origins) { | |
425 AccumulateInfo* info = new AccumulateInfo; | |
426 // Getting origin usage may synchronously return the result if the usage is | |
427 // cached, which may in turn dispatch the completion callback before we finish | |
428 // looping over all origins (because info->pending_jobs may reach 0 during the | |
429 // loop). To avoid this, we add one more pending origin as a sentinel and | |
430 // fire the sentinel callback at the end. | |
431 info->pending_jobs = origins.size() + 1; | |
432 OriginUsageAccumulator accumulator = | |
433 base::Bind(&ClientUsageTracker::AccumulateOriginUsage, AsWeakPtr(), | |
434 base::Owned(info), host); | |
435 | |
436 for (std::set<GURL>::const_iterator itr = origins.begin(); | |
437 itr != origins.end(); ++itr) { | |
438 DCHECK_EQ(host, net::GetHostOrSpecFromURL(*itr)); | |
439 | |
440 int64 origin_usage = 0; | |
441 if (GetCachedOriginUsage(*itr, &origin_usage)) { | |
442 accumulator.Run(*itr, origin_usage); | |
443 } else { | |
444 client_->GetOriginUsage(*itr, type_, base::Bind( | |
445 &DidGetOriginUsage, accumulator, *itr)); | |
446 } | |
447 } | |
448 | |
449 // Fire the sentinel as we've now called GetOriginUsage for all clients. | |
450 accumulator.Run(GURL(), 0); | |
451 } | |
452 | |
453 void ClientUsageTracker::AccumulateOriginUsage(AccumulateInfo* info, | |
454 const std::string& host, | |
455 const GURL& origin, | |
456 int64 usage) { | |
457 if (!origin.is_empty()) { | |
458 if (usage < 0) | |
459 usage = 0; | |
460 | |
461 if (IsUsageCacheEnabledForOrigin(origin)) { | |
462 info->cached_usage += usage; | |
463 AddCachedOrigin(origin, usage); | |
464 } else { | |
465 info->non_cached_usage += usage; | |
466 } | |
467 } | |
468 if (--info->pending_jobs) | |
469 return; | |
470 | |
471 AddCachedHost(host); | |
472 host_usage_accumulators_.Run( | |
473 host, MakeTuple(info->cached_usage, info->non_cached_usage)); | |
474 } | |
475 | |
476 void ClientUsageTracker::AddCachedOrigin( | |
477 const GURL& origin, int64 new_usage) { | |
478 if (!IsUsageCacheEnabledForOrigin(origin)) | |
479 return; | |
480 | |
481 std::string host = net::GetHostOrSpecFromURL(origin); | |
482 int64* usage = &cached_usage_by_host_[host][origin]; | |
483 int64 delta = new_usage - *usage; | |
484 *usage = new_usage; | |
485 if (delta) { | |
486 if (IsStorageUnlimited(origin)) | |
487 global_unlimited_usage_ += delta; | |
488 else | |
489 global_limited_usage_ += delta; | |
490 } | |
491 DCHECK_GE(*usage, 0); | |
492 DCHECK_GE(global_limited_usage_, 0); | |
493 } | |
494 | |
495 void ClientUsageTracker::AddCachedHost(const std::string& host) { | |
496 cached_hosts_.insert(host); | |
497 } | |
498 | |
499 int64 ClientUsageTracker::GetCachedHostUsage(const std::string& host) const { | |
500 HostUsageMap::const_iterator found = cached_usage_by_host_.find(host); | |
501 if (found == cached_usage_by_host_.end()) | |
502 return 0; | |
503 | |
504 int64 usage = 0; | |
505 const UsageMap& map = found->second; | |
506 for (UsageMap::const_iterator iter = map.begin(); | |
507 iter != map.end(); ++iter) { | |
508 usage += iter->second; | |
509 } | |
510 return usage; | |
511 } | |
512 | |
513 bool ClientUsageTracker::GetCachedOriginUsage( | |
514 const GURL& origin, | |
515 int64* usage) const { | |
516 std::string host = net::GetHostOrSpecFromURL(origin); | |
517 HostUsageMap::const_iterator found_host = cached_usage_by_host_.find(host); | |
518 if (found_host == cached_usage_by_host_.end()) | |
519 return false; | |
520 | |
521 UsageMap::const_iterator found = found_host->second.find(origin); | |
522 if (found == found_host->second.end()) | |
523 return false; | |
524 | |
525 DCHECK(IsUsageCacheEnabledForOrigin(origin)); | |
526 *usage = found->second; | |
527 return true; | |
528 } | |
529 | |
530 bool ClientUsageTracker::IsUsageCacheEnabledForOrigin( | |
531 const GURL& origin) const { | |
532 std::string host = net::GetHostOrSpecFromURL(origin); | |
533 return !OriginSetContainsOrigin(non_cached_limited_origins_by_host_, | |
534 host, origin) && | |
535 !OriginSetContainsOrigin(non_cached_unlimited_origins_by_host_, | |
536 host, origin); | |
537 } | |
538 | |
539 void ClientUsageTracker::OnGranted(const GURL& origin, | |
540 int change_flags) { | |
541 DCHECK(CalledOnValidThread()); | |
542 if (change_flags & SpecialStoragePolicy::STORAGE_UNLIMITED) { | |
543 int64 usage = 0; | |
544 if (GetCachedOriginUsage(origin, &usage)) { | |
545 global_unlimited_usage_ += usage; | |
546 global_limited_usage_ -= usage; | |
547 } | |
548 | |
549 std::string host = net::GetHostOrSpecFromURL(origin); | |
550 if (EraseOriginFromOriginSet(&non_cached_limited_origins_by_host_, | |
551 host, origin)) | |
552 non_cached_unlimited_origins_by_host_[host].insert(origin); | |
553 } | |
554 } | |
555 | |
556 void ClientUsageTracker::OnRevoked(const GURL& origin, | |
557 int change_flags) { | |
558 DCHECK(CalledOnValidThread()); | |
559 if (change_flags & SpecialStoragePolicy::STORAGE_UNLIMITED) { | |
560 int64 usage = 0; | |
561 if (GetCachedOriginUsage(origin, &usage)) { | |
562 global_unlimited_usage_ -= usage; | |
563 global_limited_usage_ += usage; | |
564 } | |
565 | |
566 std::string host = net::GetHostOrSpecFromURL(origin); | |
567 if (EraseOriginFromOriginSet(&non_cached_unlimited_origins_by_host_, | |
568 host, origin)) | |
569 non_cached_limited_origins_by_host_[host].insert(origin); | |
570 } | |
571 } | |
572 | |
573 void ClientUsageTracker::OnCleared() { | |
574 DCHECK(CalledOnValidThread()); | |
575 global_limited_usage_ += global_unlimited_usage_; | |
576 global_unlimited_usage_ = 0; | |
577 | |
578 for (OriginSetByHost::const_iterator host_itr = | |
579 non_cached_unlimited_origins_by_host_.begin(); | |
580 host_itr != non_cached_unlimited_origins_by_host_.end(); | |
581 ++host_itr) { | |
582 for (std::set<GURL>::const_iterator origin_itr = host_itr->second.begin(); | |
583 origin_itr != host_itr->second.end(); | |
584 ++origin_itr) | |
585 non_cached_limited_origins_by_host_[host_itr->first].insert(*origin_itr); | |
586 } | |
587 non_cached_unlimited_origins_by_host_.clear(); | |
588 } | |
589 | |
590 bool ClientUsageTracker::IsStorageUnlimited(const GURL& origin) const { | |
591 if (type_ == kStorageTypeSyncable) | |
592 return false; | |
593 return special_storage_policy_.get() && | |
594 special_storage_policy_->IsStorageUnlimited(origin); | |
595 } | |
596 | |
597 } // namespace quota | |
OLD | NEW |