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.
5 #include "webkit/browser/quota/usage_tracker.h"
13 #include "base/bind.h"
14 #include "base/message_loop/message_loop_proxy.h"
15 #include "base/stl_util.h"
16 #include "net/base/net_util.h"
17 #include "webkit/browser/quota/storage_monitor.h"
18 #include "webkit/browser/quota/storage_observer.h"
24 typedef ClientUsageTracker::OriginUsageAccumulator OriginUsageAccumulator
;
25 typedef ClientUsageTracker::OriginSetByHost OriginSetByHost
;
27 void DidGetOriginUsage(const OriginUsageAccumulator
& accumulator
,
30 accumulator
.Run(origin
, usage
);
33 void DidGetHostUsage(const UsageCallback
& callback
,
35 int64 unlimited_usage
) {
36 DCHECK_GE(limited_usage
, 0);
37 DCHECK_GE(unlimited_usage
, 0);
38 callback
.Run(limited_usage
+ unlimited_usage
);
41 bool EraseOriginFromOriginSet(OriginSetByHost
* origins_by_host
,
42 const std::string
& host
,
44 OriginSetByHost::iterator found
= origins_by_host
->find(host
);
45 if (found
== origins_by_host
->end())
48 if (!found
->second
.erase(origin
))
51 if (found
->second
.empty())
52 origins_by_host
->erase(host
);
56 bool OriginSetContainsOrigin(const OriginSetByHost
& origins
,
57 const std::string
& host
,
59 OriginSetByHost::const_iterator itr
= origins
.find(host
);
60 return itr
!= origins
.end() && ContainsKey(itr
->second
, origin
);
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
);
71 // UsageTracker ----------------------------------------------------------
73 UsageTracker::UsageTracker(const QuotaClientList
& clients
,
75 SpecialStoragePolicy
* special_storage_policy
,
76 StorageMonitor
* storage_monitor
)
78 storage_monitor_(storage_monitor
),
80 for (QuotaClientList::const_iterator iter
= clients
.begin();
81 iter
!= clients
.end();
83 if ((*iter
)->DoesSupport(type
)) {
84 client_tracker_map_
[(*iter
)->id()] =
85 new ClientUsageTracker(this, *iter
, type
, special_storage_policy
,
91 UsageTracker::~UsageTracker() {
92 STLDeleteValues(&client_tracker_map_
);
95 ClientUsageTracker
* UsageTracker::GetClientTracker(QuotaClient::ID client_id
) {
96 ClientTrackerMap::iterator found
= client_tracker_map_
.find(client_id
);
97 if (found
!= client_tracker_map_
.end())
102 void UsageTracker::GetGlobalLimitedUsage(const UsageCallback
& callback
) {
103 if (global_usage_callbacks_
.HasCallbacks()) {
104 global_usage_callbacks_
.Add(base::Bind(
105 &DidGetGlobalUsageForLimitedGlobalUsage
, callback
));
109 if (!global_limited_usage_callbacks_
.Add(callback
))
112 AccumulateInfo
* info
= new AccumulateInfo
;
113 // Calling GetGlobalLimitedUsage(accumulator) may synchronously
114 // return if the usage is cached, which may in turn dispatch
115 // the completion callback before we finish looping over
116 // all clients (because info->pending_clients may reach 0
118 // To avoid this, we add one more pending client as a sentinel
119 // and fire the sentinel callback at the end.
120 info
->pending_clients
= client_tracker_map_
.size() + 1;
121 UsageCallback accumulator
= base::Bind(
122 &UsageTracker::AccumulateClientGlobalLimitedUsage
,
123 weak_factory_
.GetWeakPtr(), base::Owned(info
));
125 for (ClientTrackerMap::iterator iter
= client_tracker_map_
.begin();
126 iter
!= client_tracker_map_
.end();
128 iter
->second
->GetGlobalLimitedUsage(accumulator
);
130 // Fire the sentinel as we've now called GetGlobalUsage for all clients.
134 void UsageTracker::GetGlobalUsage(const GlobalUsageCallback
& callback
) {
135 if (!global_usage_callbacks_
.Add(callback
))
138 AccumulateInfo
* info
= new AccumulateInfo
;
139 // Calling GetGlobalUsage(accumulator) may synchronously
140 // return if the usage is cached, which may in turn dispatch
141 // the completion callback before we finish looping over
142 // all clients (because info->pending_clients may reach 0
144 // To avoid this, we add one more pending client as a sentinel
145 // and fire the sentinel callback at the end.
146 info
->pending_clients
= client_tracker_map_
.size() + 1;
147 GlobalUsageCallback accumulator
= base::Bind(
148 &UsageTracker::AccumulateClientGlobalUsage
, weak_factory_
.GetWeakPtr(),
151 for (ClientTrackerMap::iterator iter
= client_tracker_map_
.begin();
152 iter
!= client_tracker_map_
.end();
154 iter
->second
->GetGlobalUsage(accumulator
);
156 // Fire the sentinel as we've now called GetGlobalUsage for all clients.
157 accumulator
.Run(0, 0);
160 void UsageTracker::GetHostUsage(const std::string
& host
,
161 const UsageCallback
& callback
) {
162 if (!host_usage_callbacks_
.Add(host
, callback
))
165 AccumulateInfo
* info
= new AccumulateInfo
;
166 // Calling GetHostUsage(accumulator) may synchronously
167 // return if the usage is cached, which may in turn dispatch
168 // the completion callback before we finish looping over
169 // all clients (because info->pending_clients may reach 0
171 // To avoid this, we add one more pending client as a sentinel
172 // and fire the sentinel callback at the end.
173 info
->pending_clients
= client_tracker_map_
.size() + 1;
174 UsageCallback accumulator
= base::Bind(
175 &UsageTracker::AccumulateClientHostUsage
, weak_factory_
.GetWeakPtr(),
176 base::Owned(info
), host
);
178 for (ClientTrackerMap::iterator iter
= client_tracker_map_
.begin();
179 iter
!= client_tracker_map_
.end();
181 iter
->second
->GetHostUsage(host
, accumulator
);
183 // Fire the sentinel as we've now called GetHostUsage for all clients.
187 void UsageTracker::UpdateUsageCache(
188 QuotaClient::ID client_id
, const GURL
& origin
, int64 delta
) {
189 ClientUsageTracker
* client_tracker
= GetClientTracker(client_id
);
190 DCHECK(client_tracker
);
191 client_tracker
->UpdateUsageCache(origin
, delta
);
194 void UsageTracker::GetCachedHostsUsage(
195 std::map
<std::string
, int64
>* host_usage
) const {
198 for (ClientTrackerMap::const_iterator iter
= client_tracker_map_
.begin();
199 iter
!= client_tracker_map_
.end(); ++iter
) {
200 iter
->second
->GetCachedHostsUsage(host_usage
);
204 void UsageTracker::GetCachedOrigins(std::set
<GURL
>* origins
) const {
207 for (ClientTrackerMap::const_iterator iter
= client_tracker_map_
.begin();
208 iter
!= client_tracker_map_
.end(); ++iter
) {
209 iter
->second
->GetCachedOrigins(origins
);
213 void UsageTracker::SetUsageCacheEnabled(QuotaClient::ID client_id
,
216 ClientUsageTracker
* client_tracker
= GetClientTracker(client_id
);
217 DCHECK(client_tracker
);
219 client_tracker
->SetUsageCacheEnabled(origin
, enabled
);
222 void UsageTracker::AccumulateClientGlobalLimitedUsage(AccumulateInfo
* info
,
223 int64 limited_usage
) {
224 info
->usage
+= limited_usage
;
225 if (--info
->pending_clients
)
228 // All the clients have returned their usage data. Dispatch the
229 // pending callbacks.
230 global_limited_usage_callbacks_
.Run(MakeTuple(info
->usage
));
233 void UsageTracker::AccumulateClientGlobalUsage(AccumulateInfo
* info
,
235 int64 unlimited_usage
) {
236 info
->usage
+= usage
;
237 info
->unlimited_usage
+= unlimited_usage
;
238 if (--info
->pending_clients
)
241 // Defend against confusing inputs from clients.
245 // TODO(michaeln): The unlimited number is not trustworthy, it
246 // can get out of whack when apps are installed or uninstalled.
247 if (info
->unlimited_usage
> info
->usage
)
248 info
->unlimited_usage
= info
->usage
;
249 else if (info
->unlimited_usage
< 0)
250 info
->unlimited_usage
= 0;
252 // All the clients have returned their usage data. Dispatch the
253 // pending callbacks.
254 global_usage_callbacks_
.Run(MakeTuple(info
->usage
, info
->unlimited_usage
));
257 void UsageTracker::AccumulateClientHostUsage(AccumulateInfo
* info
,
258 const std::string
& host
,
260 info
->usage
+= usage
;
261 if (--info
->pending_clients
)
264 // Defend against confusing inputs from clients.
268 // All the clients have returned their usage data. Dispatch the
269 // pending callbacks.
270 host_usage_callbacks_
.Run(host
, MakeTuple(info
->usage
));
273 // ClientUsageTracker ----------------------------------------------------
275 ClientUsageTracker::ClientUsageTracker(
276 UsageTracker
* tracker
, QuotaClient
* client
, StorageType type
,
277 SpecialStoragePolicy
* special_storage_policy
,
278 StorageMonitor
* storage_monitor
)
282 storage_monitor_(storage_monitor
),
283 global_limited_usage_(0),
284 global_unlimited_usage_(0),
285 global_usage_retrieved_(false),
286 special_storage_policy_(special_storage_policy
) {
289 if (special_storage_policy_
.get())
290 special_storage_policy_
->AddObserver(this);
293 ClientUsageTracker::~ClientUsageTracker() {
294 if (special_storage_policy_
.get())
295 special_storage_policy_
->RemoveObserver(this);
298 void ClientUsageTracker::GetGlobalLimitedUsage(const UsageCallback
& callback
) {
299 if (!global_usage_retrieved_
) {
300 GetGlobalUsage(base::Bind(&DidGetGlobalUsageForLimitedGlobalUsage
,
305 if (non_cached_limited_origins_by_host_
.empty()) {
306 callback
.Run(global_limited_usage_
);
310 AccumulateInfo
* info
= new AccumulateInfo
;
311 info
->pending_jobs
= non_cached_limited_origins_by_host_
.size() + 1;
312 UsageCallback accumulator
= base::Bind(
313 &ClientUsageTracker::AccumulateLimitedOriginUsage
, AsWeakPtr(),
314 base::Owned(info
), callback
);
316 for (OriginSetByHost::iterator host_itr
=
317 non_cached_limited_origins_by_host_
.begin();
318 host_itr
!= non_cached_limited_origins_by_host_
.end(); ++host_itr
) {
319 for (std::set
<GURL
>::iterator origin_itr
= host_itr
->second
.begin();
320 origin_itr
!= host_itr
->second
.end(); ++origin_itr
)
321 client_
->GetOriginUsage(*origin_itr
, type_
, accumulator
);
324 accumulator
.Run(global_limited_usage_
);
327 void ClientUsageTracker::GetGlobalUsage(const GlobalUsageCallback
& callback
) {
328 if (global_usage_retrieved_
&&
329 non_cached_limited_origins_by_host_
.empty() &&
330 non_cached_unlimited_origins_by_host_
.empty()) {
331 callback
.Run(global_limited_usage_
+ global_unlimited_usage_
,
332 global_unlimited_usage_
);
336 client_
->GetOriginsForType(type_
, base::Bind(
337 &ClientUsageTracker::DidGetOriginsForGlobalUsage
, AsWeakPtr(),
341 void ClientUsageTracker::GetHostUsage(
342 const std::string
& host
, const UsageCallback
& callback
) {
343 if (ContainsKey(cached_hosts_
, host
) &&
344 !ContainsKey(non_cached_limited_origins_by_host_
, host
) &&
345 !ContainsKey(non_cached_unlimited_origins_by_host_
, host
)) {
346 // TODO(kinuko): Drop host_usage_map_ cache periodically.
347 callback
.Run(GetCachedHostUsage(host
));
351 if (!host_usage_accumulators_
.Add(
352 host
, base::Bind(&DidGetHostUsage
, callback
)))
354 client_
->GetOriginsForHost(type_
, host
, base::Bind(
355 &ClientUsageTracker::DidGetOriginsForHostUsage
, AsWeakPtr(), host
));
358 void ClientUsageTracker::UpdateUsageCache(
359 const GURL
& origin
, int64 delta
) {
360 std::string host
= net::GetHostOrSpecFromURL(origin
);
361 if (cached_hosts_
.find(host
) != cached_hosts_
.end()) {
362 if (!IsUsageCacheEnabledForOrigin(origin
))
365 cached_usage_by_host_
[host
][origin
] += delta
;
366 if (IsStorageUnlimited(origin
))
367 global_unlimited_usage_
+= delta
;
369 global_limited_usage_
+= delta
;
370 DCHECK_GE(cached_usage_by_host_
[host
][origin
], 0);
371 DCHECK_GE(global_limited_usage_
, 0);
373 // Notify the usage monitor that usage has changed. The storage monitor may
374 // be NULL during tests.
375 if (storage_monitor_
) {
376 StorageObserver::Filter
filter(type_
, origin
);
377 storage_monitor_
->NotifyUsageChange(filter
, delta
);
382 // We don't know about this host yet, so populate our cache for it.
383 GetHostUsage(host
, base::Bind(&ClientUsageTracker::DidGetHostUsageAfterUpdate
,
384 AsWeakPtr(), origin
));
387 void ClientUsageTracker::GetCachedHostsUsage(
388 std::map
<std::string
, int64
>* host_usage
) const {
390 for (HostUsageMap::const_iterator host_iter
= cached_usage_by_host_
.begin();
391 host_iter
!= cached_usage_by_host_
.end(); host_iter
++) {
392 const std::string
& host
= host_iter
->first
;
393 (*host_usage
)[host
] += GetCachedHostUsage(host
);
397 void ClientUsageTracker::GetCachedOrigins(std::set
<GURL
>* origins
) const {
399 for (HostUsageMap::const_iterator host_iter
= cached_usage_by_host_
.begin();
400 host_iter
!= cached_usage_by_host_
.end(); host_iter
++) {
401 const UsageMap
& origin_map
= host_iter
->second
;
402 for (UsageMap::const_iterator origin_iter
= origin_map
.begin();
403 origin_iter
!= origin_map
.end(); origin_iter
++) {
404 origins
->insert(origin_iter
->first
);
409 void ClientUsageTracker::SetUsageCacheEnabled(const GURL
& origin
,
411 std::string host
= net::GetHostOrSpecFromURL(origin
);
413 // Erase |origin| from cache and subtract its usage.
414 HostUsageMap::iterator found_host
= cached_usage_by_host_
.find(host
);
415 if (found_host
!= cached_usage_by_host_
.end()) {
416 UsageMap
& cached_usage_for_host
= found_host
->second
;
418 UsageMap::iterator found
= cached_usage_for_host
.find(origin
);
419 if (found
!= cached_usage_for_host
.end()) {
420 int64 usage
= found
->second
;
421 UpdateUsageCache(origin
, -usage
);
422 cached_usage_for_host
.erase(found
);
423 if (cached_usage_for_host
.empty()) {
424 cached_usage_by_host_
.erase(found_host
);
425 cached_hosts_
.erase(host
);
430 if (IsStorageUnlimited(origin
))
431 non_cached_unlimited_origins_by_host_
[host
].insert(origin
);
433 non_cached_limited_origins_by_host_
[host
].insert(origin
);
435 // Erase |origin| from |non_cached_origins_| and invalidate the usage cache
437 if (EraseOriginFromOriginSet(&non_cached_limited_origins_by_host_
,
439 EraseOriginFromOriginSet(&non_cached_unlimited_origins_by_host_
,
441 cached_hosts_
.erase(host
);
442 global_usage_retrieved_
= false;
447 void ClientUsageTracker::AccumulateLimitedOriginUsage(
448 AccumulateInfo
* info
,
449 const UsageCallback
& callback
,
451 info
->limited_usage
+= usage
;
452 if (--info
->pending_jobs
)
455 callback
.Run(info
->limited_usage
);
458 void ClientUsageTracker::DidGetOriginsForGlobalUsage(
459 const GlobalUsageCallback
& callback
,
460 const std::set
<GURL
>& origins
) {
461 OriginSetByHost origins_by_host
;
462 for (std::set
<GURL
>::const_iterator itr
= origins
.begin();
463 itr
!= origins
.end(); ++itr
)
464 origins_by_host
[net::GetHostOrSpecFromURL(*itr
)].insert(*itr
);
466 AccumulateInfo
* info
= new AccumulateInfo
;
467 // 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
469 // 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
471 // fire the sentinel callback at the end.
472 info
->pending_jobs
= origins_by_host
.size() + 1;
473 HostUsageAccumulator accumulator
=
474 base::Bind(&ClientUsageTracker::AccumulateHostUsage
, AsWeakPtr(),
475 base::Owned(info
), callback
);
477 for (OriginSetByHost::iterator itr
= origins_by_host
.begin();
478 itr
!= origins_by_host
.end(); ++itr
) {
479 if (host_usage_accumulators_
.Add(itr
->first
, accumulator
))
480 GetUsageForOrigins(itr
->first
, itr
->second
);
483 // Fire the sentinel as we've now called GetUsageForOrigins for all clients.
484 accumulator
.Run(0, 0);
487 void ClientUsageTracker::AccumulateHostUsage(
488 AccumulateInfo
* info
,
489 const GlobalUsageCallback
& callback
,
491 int64 unlimited_usage
) {
492 info
->limited_usage
+= limited_usage
;
493 info
->unlimited_usage
+= unlimited_usage
;
494 if (--info
->pending_jobs
)
497 DCHECK_GE(info
->limited_usage
, 0);
498 DCHECK_GE(info
->unlimited_usage
, 0);
500 global_usage_retrieved_
= true;
501 callback
.Run(info
->limited_usage
+ info
->unlimited_usage
,
502 info
->unlimited_usage
);
505 void ClientUsageTracker::DidGetOriginsForHostUsage(
506 const std::string
& host
,
507 const std::set
<GURL
>& origins
) {
508 GetUsageForOrigins(host
, origins
);
511 void ClientUsageTracker::GetUsageForOrigins(
512 const std::string
& host
,
513 const std::set
<GURL
>& origins
) {
514 AccumulateInfo
* info
= new AccumulateInfo
;
515 // 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
517 // 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
519 // fire the sentinel callback at the end.
520 info
->pending_jobs
= origins
.size() + 1;
521 OriginUsageAccumulator accumulator
=
522 base::Bind(&ClientUsageTracker::AccumulateOriginUsage
, AsWeakPtr(),
523 base::Owned(info
), host
);
525 for (std::set
<GURL
>::const_iterator itr
= origins
.begin();
526 itr
!= origins
.end(); ++itr
) {
527 DCHECK_EQ(host
, net::GetHostOrSpecFromURL(*itr
));
529 int64 origin_usage
= 0;
530 if (GetCachedOriginUsage(*itr
, &origin_usage
)) {
531 accumulator
.Run(*itr
, origin_usage
);
533 client_
->GetOriginUsage(*itr
, type_
, base::Bind(
534 &DidGetOriginUsage
, accumulator
, *itr
));
538 // Fire the sentinel as we've now called GetOriginUsage for all clients.
539 accumulator
.Run(GURL(), 0);
542 void ClientUsageTracker::AccumulateOriginUsage(AccumulateInfo
* info
,
543 const std::string
& host
,
546 if (!origin
.is_empty()) {
550 if (IsStorageUnlimited(origin
))
551 info
->unlimited_usage
+= usage
;
553 info
->limited_usage
+= usage
;
554 if (IsUsageCacheEnabledForOrigin(origin
))
555 AddCachedOrigin(origin
, usage
);
557 if (--info
->pending_jobs
)
561 host_usage_accumulators_
.Run(
562 host
, MakeTuple(info
->limited_usage
, info
->unlimited_usage
));
565 void ClientUsageTracker::DidGetHostUsageAfterUpdate(
566 const GURL
& origin
, int64 usage
) {
567 if (!storage_monitor_
)
570 StorageObserver::Filter
filter(type_
, origin
);
571 storage_monitor_
->NotifyUsageChange(filter
, 0);
574 void ClientUsageTracker::AddCachedOrigin(
575 const GURL
& origin
, int64 new_usage
) {
576 DCHECK(IsUsageCacheEnabledForOrigin(origin
));
578 std::string host
= net::GetHostOrSpecFromURL(origin
);
579 int64
* usage
= &cached_usage_by_host_
[host
][origin
];
580 int64 delta
= new_usage
- *usage
;
583 if (IsStorageUnlimited(origin
))
584 global_unlimited_usage_
+= delta
;
586 global_limited_usage_
+= delta
;
588 DCHECK_GE(*usage
, 0);
589 DCHECK_GE(global_limited_usage_
, 0);
592 void ClientUsageTracker::AddCachedHost(const std::string
& host
) {
593 cached_hosts_
.insert(host
);
596 int64
ClientUsageTracker::GetCachedHostUsage(const std::string
& host
) const {
597 HostUsageMap::const_iterator found
= cached_usage_by_host_
.find(host
);
598 if (found
== cached_usage_by_host_
.end())
602 const UsageMap
& map
= found
->second
;
603 for (UsageMap::const_iterator iter
= map
.begin();
604 iter
!= map
.end(); ++iter
) {
605 usage
+= iter
->second
;
610 bool ClientUsageTracker::GetCachedOriginUsage(
612 int64
* usage
) const {
613 std::string host
= net::GetHostOrSpecFromURL(origin
);
614 HostUsageMap::const_iterator found_host
= cached_usage_by_host_
.find(host
);
615 if (found_host
== cached_usage_by_host_
.end())
618 UsageMap::const_iterator found
= found_host
->second
.find(origin
);
619 if (found
== found_host
->second
.end())
622 DCHECK(IsUsageCacheEnabledForOrigin(origin
));
623 *usage
= found
->second
;
627 bool ClientUsageTracker::IsUsageCacheEnabledForOrigin(
628 const GURL
& origin
) const {
629 std::string host
= net::GetHostOrSpecFromURL(origin
);
630 return !OriginSetContainsOrigin(non_cached_limited_origins_by_host_
,
632 !OriginSetContainsOrigin(non_cached_unlimited_origins_by_host_
,
636 void ClientUsageTracker::OnGranted(const GURL
& origin
,
638 DCHECK(CalledOnValidThread());
639 if (change_flags
& SpecialStoragePolicy::STORAGE_UNLIMITED
) {
641 if (GetCachedOriginUsage(origin
, &usage
)) {
642 global_unlimited_usage_
+= usage
;
643 global_limited_usage_
-= usage
;
646 std::string host
= net::GetHostOrSpecFromURL(origin
);
647 if (EraseOriginFromOriginSet(&non_cached_limited_origins_by_host_
,
649 non_cached_unlimited_origins_by_host_
[host
].insert(origin
);
653 void ClientUsageTracker::OnRevoked(const GURL
& origin
,
655 DCHECK(CalledOnValidThread());
656 if (change_flags
& SpecialStoragePolicy::STORAGE_UNLIMITED
) {
658 if (GetCachedOriginUsage(origin
, &usage
)) {
659 global_unlimited_usage_
-= usage
;
660 global_limited_usage_
+= usage
;
663 std::string host
= net::GetHostOrSpecFromURL(origin
);
664 if (EraseOriginFromOriginSet(&non_cached_unlimited_origins_by_host_
,
666 non_cached_limited_origins_by_host_
[host
].insert(origin
);
670 void ClientUsageTracker::OnCleared() {
671 DCHECK(CalledOnValidThread());
672 global_limited_usage_
+= global_unlimited_usage_
;
673 global_unlimited_usage_
= 0;
675 for (OriginSetByHost::const_iterator host_itr
=
676 non_cached_unlimited_origins_by_host_
.begin();
677 host_itr
!= non_cached_unlimited_origins_by_host_
.end();
679 for (std::set
<GURL
>::const_iterator origin_itr
= host_itr
->second
.begin();
680 origin_itr
!= host_itr
->second
.end();
682 non_cached_limited_origins_by_host_
[host_itr
->first
].insert(*origin_itr
);
684 non_cached_unlimited_origins_by_host_
.clear();
687 bool ClientUsageTracker::IsStorageUnlimited(const GURL
& origin
) const {
688 if (type_
== kStorageTypeSyncable
)
690 return special_storage_policy_
.get() &&
691 special_storage_policy_
->IsStorageUnlimited(origin
);