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 "storage/browser/quota/usage_tracker.h"
10 #include "base/stl_util.h"
11 #include "storage/browser/quota/client_usage_tracker.h"
12 #include "storage/browser/quota/storage_monitor.h"
18 void DidGetGlobalUsageForLimitedGlobalUsage(const UsageCallback
& callback
,
19 int64 total_global_usage
,
20 int64 global_unlimited_usage
) {
21 callback
.Run(total_global_usage
- global_unlimited_usage
);
26 UsageTracker::UsageTracker(const QuotaClientList
& clients
,
28 SpecialStoragePolicy
* special_storage_policy
,
29 StorageMonitor
* storage_monitor
)
31 storage_monitor_(storage_monitor
),
33 for (const auto& client
: clients
) {
34 if (client
->DoesSupport(type
)) {
35 client_tracker_map_
[client
->id()] =
36 new ClientUsageTracker(this, client
, type
, special_storage_policy
,
42 UsageTracker::~UsageTracker() {
43 STLDeleteValues(&client_tracker_map_
);
46 ClientUsageTracker
* UsageTracker::GetClientTracker(QuotaClient::ID client_id
) {
47 ClientTrackerMap::iterator found
= client_tracker_map_
.find(client_id
);
48 if (found
!= client_tracker_map_
.end())
53 void UsageTracker::GetGlobalLimitedUsage(const UsageCallback
& callback
) {
54 if (global_usage_callbacks_
.HasCallbacks()) {
55 global_usage_callbacks_
.Add(base::Bind(
56 &DidGetGlobalUsageForLimitedGlobalUsage
, callback
));
60 if (!global_limited_usage_callbacks_
.Add(callback
))
63 AccumulateInfo
* info
= new AccumulateInfo
;
64 // Calling GetGlobalLimitedUsage(accumulator) may synchronously
65 // return if the usage is cached, which may in turn dispatch
66 // the completion callback before we finish looping over
67 // all clients (because info->pending_clients may reach 0
69 // To avoid this, we add one more pending client as a sentinel
70 // and fire the sentinel callback at the end.
71 info
->pending_clients
= client_tracker_map_
.size() + 1;
72 UsageCallback accumulator
= base::Bind(
73 &UsageTracker::AccumulateClientGlobalLimitedUsage
,
74 weak_factory_
.GetWeakPtr(), base::Owned(info
));
76 for (const auto& client_id_and_tracker
: client_tracker_map_
)
77 client_id_and_tracker
.second
->GetGlobalLimitedUsage(accumulator
);
79 // Fire the sentinel as we've now called GetGlobalUsage for all clients.
83 void UsageTracker::GetGlobalUsage(const GlobalUsageCallback
& callback
) {
84 if (!global_usage_callbacks_
.Add(callback
))
87 AccumulateInfo
* info
= new AccumulateInfo
;
88 // Calling GetGlobalUsage(accumulator) may synchronously
89 // return if the usage is cached, which may in turn dispatch
90 // the completion callback before we finish looping over
91 // all clients (because info->pending_clients may reach 0
93 // To avoid this, we add one more pending client as a sentinel
94 // and fire the sentinel callback at the end.
95 info
->pending_clients
= client_tracker_map_
.size() + 1;
96 GlobalUsageCallback accumulator
= base::Bind(
97 &UsageTracker::AccumulateClientGlobalUsage
, weak_factory_
.GetWeakPtr(),
100 for (const auto& client_id_and_tracker
: client_tracker_map_
)
101 client_id_and_tracker
.second
->GetGlobalUsage(accumulator
);
103 // Fire the sentinel as we've now called GetGlobalUsage for all clients.
104 accumulator
.Run(0, 0);
107 void UsageTracker::GetHostUsage(const std::string
& host
,
108 const UsageCallback
& callback
) {
109 if (!host_usage_callbacks_
.Add(host
, callback
))
112 AccumulateInfo
* info
= new AccumulateInfo
;
113 // Calling GetHostUsage(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::AccumulateClientHostUsage
, weak_factory_
.GetWeakPtr(),
123 base::Owned(info
), host
);
125 for (const auto& client_id_and_tracker
: client_tracker_map_
)
126 client_id_and_tracker
.second
->GetHostUsage(host
, accumulator
);
128 // Fire the sentinel as we've now called GetHostUsage for all clients.
132 void UsageTracker::UpdateUsageCache(
133 QuotaClient::ID client_id
, const GURL
& origin
, int64 delta
) {
134 ClientUsageTracker
* client_tracker
= GetClientTracker(client_id
);
135 DCHECK(client_tracker
);
136 client_tracker
->UpdateUsageCache(origin
, delta
);
139 void UsageTracker::GetCachedHostsUsage(
140 std::map
<std::string
, int64
>* host_usage
) const {
143 for (const auto& client_id_and_tracker
: client_tracker_map_
)
144 client_id_and_tracker
.second
->GetCachedHostsUsage(host_usage
);
147 void UsageTracker::GetCachedOrigins(std::set
<GURL
>* origins
) const {
150 for (const auto& client_id_and_tracker
: client_tracker_map_
)
151 client_id_and_tracker
.second
->GetCachedOrigins(origins
);
154 void UsageTracker::SetUsageCacheEnabled(QuotaClient::ID client_id
,
157 ClientUsageTracker
* client_tracker
= GetClientTracker(client_id
);
158 DCHECK(client_tracker
);
160 client_tracker
->SetUsageCacheEnabled(origin
, enabled
);
163 void UsageTracker::AccumulateClientGlobalLimitedUsage(AccumulateInfo
* info
,
164 int64 limited_usage
) {
165 info
->usage
+= limited_usage
;
166 if (--info
->pending_clients
)
169 // All the clients have returned their usage data. Dispatch the
170 // pending callbacks.
171 global_limited_usage_callbacks_
.Run(info
->usage
);
174 void UsageTracker::AccumulateClientGlobalUsage(AccumulateInfo
* info
,
176 int64 unlimited_usage
) {
177 info
->usage
+= usage
;
178 info
->unlimited_usage
+= unlimited_usage
;
179 if (--info
->pending_clients
)
182 // Defend against confusing inputs from clients.
186 // TODO(michaeln): The unlimited number is not trustworthy, it
187 // can get out of whack when apps are installed or uninstalled.
188 if (info
->unlimited_usage
> info
->usage
)
189 info
->unlimited_usage
= info
->usage
;
190 else if (info
->unlimited_usage
< 0)
191 info
->unlimited_usage
= 0;
193 // All the clients have returned their usage data. Dispatch the
194 // pending callbacks.
195 global_usage_callbacks_
.Run(info
->usage
, info
->unlimited_usage
);
198 void UsageTracker::AccumulateClientHostUsage(AccumulateInfo
* info
,
199 const std::string
& host
,
201 info
->usage
+= usage
;
202 if (--info
->pending_clients
)
205 // Defend against confusing inputs from clients.
209 // All the clients have returned their usage data. Dispatch the
210 // pending callbacks.
211 host_usage_callbacks_
.Run(host
, info
->usage
);
214 } // namespace storage