| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "storage/browser/quota/client_usage_tracker.h" | 5 #include "storage/browser/quota/client_usage_tracker.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
| 9 #include "net/base/net_util.h" | 9 #include "net/base/net_util.h" |
| 10 #include "storage/browser/quota/storage_monitor.h" | 10 #include "storage/browser/quota/storage_monitor.h" |
| 11 #include "storage/browser/quota/storage_observer.h" | 11 #include "storage/browser/quota/storage_observer.h" |
| 12 | 12 |
| 13 namespace storage { | 13 namespace storage { |
| 14 | 14 |
| 15 namespace { | 15 namespace { |
| 16 | 16 |
| 17 typedef ClientUsageTracker::OriginUsageAccumulator OriginUsageAccumulator; | 17 typedef ClientUsageTracker::OriginUsageAccumulator OriginUsageAccumulator; |
| 18 typedef ClientUsageTracker::OriginSetByHost OriginSetByHost; | 18 typedef ClientUsageTracker::OriginSetByHost OriginSetByHost; |
| 19 | 19 |
| 20 void DidGetOriginUsage(const OriginUsageAccumulator& accumulator, | |
| 21 const GURL& origin, | |
| 22 int64 usage) { | |
| 23 accumulator.Run(origin, usage); | |
| 24 } | |
| 25 | |
| 26 void DidGetHostUsage(const UsageCallback& callback, | 20 void DidGetHostUsage(const UsageCallback& callback, |
| 27 int64 limited_usage, | 21 int64 limited_usage, |
| 28 int64 unlimited_usage) { | 22 int64 unlimited_usage) { |
| 29 DCHECK_GE(limited_usage, 0); | 23 DCHECK_GE(limited_usage, 0); |
| 30 DCHECK_GE(unlimited_usage, 0); | 24 DCHECK_GE(unlimited_usage, 0); |
| 31 callback.Run(limited_usage + unlimited_usage); | 25 callback.Run(limited_usage + unlimited_usage); |
| 32 } | 26 } |
| 33 | 27 |
| 34 bool EraseOriginFromOriginSet(OriginSetByHost* origins_by_host, | 28 bool EraseOriginFromOriginSet(OriginSetByHost* origins_by_host, |
| 35 const std::string& host, | 29 const std::string& host, |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 callback.Run(global_limited_usage_); | 89 callback.Run(global_limited_usage_); |
| 96 return; | 90 return; |
| 97 } | 91 } |
| 98 | 92 |
| 99 AccumulateInfo* info = new AccumulateInfo; | 93 AccumulateInfo* info = new AccumulateInfo; |
| 100 info->pending_jobs = non_cached_limited_origins_by_host_.size() + 1; | 94 info->pending_jobs = non_cached_limited_origins_by_host_.size() + 1; |
| 101 UsageCallback accumulator = base::Bind( | 95 UsageCallback accumulator = base::Bind( |
| 102 &ClientUsageTracker::AccumulateLimitedOriginUsage, AsWeakPtr(), | 96 &ClientUsageTracker::AccumulateLimitedOriginUsage, AsWeakPtr(), |
| 103 base::Owned(info), callback); | 97 base::Owned(info), callback); |
| 104 | 98 |
| 105 for (OriginSetByHost::iterator host_itr = | 99 for (const auto& host_and_origins : non_cached_limited_origins_by_host_) { |
| 106 non_cached_limited_origins_by_host_.begin(); | 100 for (const auto& origin : host_and_origins.second) |
| 107 host_itr != non_cached_limited_origins_by_host_.end(); ++host_itr) { | 101 client_->GetOriginUsage(origin, type_, accumulator); |
| 108 for (std::set<GURL>::iterator origin_itr = host_itr->second.begin(); | |
| 109 origin_itr != host_itr->second.end(); ++origin_itr) | |
| 110 client_->GetOriginUsage(*origin_itr, type_, accumulator); | |
| 111 } | 102 } |
| 112 | 103 |
| 113 accumulator.Run(global_limited_usage_); | 104 accumulator.Run(global_limited_usage_); |
| 114 } | 105 } |
| 115 | 106 |
| 116 void ClientUsageTracker::GetGlobalUsage(const GlobalUsageCallback& callback) { | 107 void ClientUsageTracker::GetGlobalUsage(const GlobalUsageCallback& callback) { |
| 117 if (global_usage_retrieved_ && | 108 if (global_usage_retrieved_ && |
| 118 non_cached_limited_origins_by_host_.empty() && | 109 non_cached_limited_origins_by_host_.empty() && |
| 119 non_cached_unlimited_origins_by_host_.empty()) { | 110 non_cached_unlimited_origins_by_host_.empty()) { |
| 120 callback.Run(global_limited_usage_ + global_unlimited_usage_, | 111 callback.Run(global_limited_usage_ + global_unlimited_usage_, |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 } | 160 } |
| 170 | 161 |
| 171 // We don't know about this host yet, so populate our cache for it. | 162 // We don't know about this host yet, so populate our cache for it. |
| 172 GetHostUsage(host, base::Bind(&ClientUsageTracker::DidGetHostUsageAfterUpdate, | 163 GetHostUsage(host, base::Bind(&ClientUsageTracker::DidGetHostUsageAfterUpdate, |
| 173 AsWeakPtr(), origin)); | 164 AsWeakPtr(), origin)); |
| 174 } | 165 } |
| 175 | 166 |
| 176 void ClientUsageTracker::GetCachedHostsUsage( | 167 void ClientUsageTracker::GetCachedHostsUsage( |
| 177 std::map<std::string, int64>* host_usage) const { | 168 std::map<std::string, int64>* host_usage) const { |
| 178 DCHECK(host_usage); | 169 DCHECK(host_usage); |
| 179 for (HostUsageMap::const_iterator host_iter = cached_usage_by_host_.begin(); | 170 for (const auto& host_and_usage_map : cached_usage_by_host_) { |
| 180 host_iter != cached_usage_by_host_.end(); host_iter++) { | 171 const std::string& host = host_and_usage_map.first; |
| 181 const std::string& host = host_iter->first; | |
| 182 (*host_usage)[host] += GetCachedHostUsage(host); | 172 (*host_usage)[host] += GetCachedHostUsage(host); |
| 183 } | 173 } |
| 184 } | 174 } |
| 185 | 175 |
| 186 void ClientUsageTracker::GetCachedOrigins(std::set<GURL>* origins) const { | 176 void ClientUsageTracker::GetCachedOrigins(std::set<GURL>* origins) const { |
| 187 DCHECK(origins); | 177 DCHECK(origins); |
| 188 for (HostUsageMap::const_iterator host_iter = cached_usage_by_host_.begin(); | 178 for (const auto& host_and_usage_map : cached_usage_by_host_) { |
| 189 host_iter != cached_usage_by_host_.end(); host_iter++) { | 179 for (const auto& origin_and_usage : host_and_usage_map.second) |
| 190 const UsageMap& origin_map = host_iter->second; | 180 origins->insert(origin_and_usage.first); |
| 191 for (UsageMap::const_iterator origin_iter = origin_map.begin(); | |
| 192 origin_iter != origin_map.end(); origin_iter++) { | |
| 193 origins->insert(origin_iter->first); | |
| 194 } | |
| 195 } | 181 } |
| 196 } | 182 } |
| 197 | 183 |
| 198 void ClientUsageTracker::SetUsageCacheEnabled(const GURL& origin, | 184 void ClientUsageTracker::SetUsageCacheEnabled(const GURL& origin, |
| 199 bool enabled) { | 185 bool enabled) { |
| 200 std::string host = net::GetHostOrSpecFromURL(origin); | 186 std::string host = net::GetHostOrSpecFromURL(origin); |
| 201 if (!enabled) { | 187 if (!enabled) { |
| 202 // Erase |origin| from cache and subtract its usage. | 188 // Erase |origin| from cache and subtract its usage. |
| 203 HostUsageMap::iterator found_host = cached_usage_by_host_.find(host); | 189 HostUsageMap::iterator found_host = cached_usage_by_host_.find(host); |
| 204 if (found_host != cached_usage_by_host_.end()) { | 190 if (found_host != cached_usage_by_host_.end()) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 if (--info->pending_jobs) | 227 if (--info->pending_jobs) |
| 242 return; | 228 return; |
| 243 | 229 |
| 244 callback.Run(info->limited_usage); | 230 callback.Run(info->limited_usage); |
| 245 } | 231 } |
| 246 | 232 |
| 247 void ClientUsageTracker::DidGetOriginsForGlobalUsage( | 233 void ClientUsageTracker::DidGetOriginsForGlobalUsage( |
| 248 const GlobalUsageCallback& callback, | 234 const GlobalUsageCallback& callback, |
| 249 const std::set<GURL>& origins) { | 235 const std::set<GURL>& origins) { |
| 250 OriginSetByHost origins_by_host; | 236 OriginSetByHost origins_by_host; |
| 251 for (std::set<GURL>::const_iterator itr = origins.begin(); | 237 for (const auto& origin : origins) |
| 252 itr != origins.end(); ++itr) | 238 origins_by_host[net::GetHostOrSpecFromURL(origin)].insert(origin); |
| 253 origins_by_host[net::GetHostOrSpecFromURL(*itr)].insert(*itr); | |
| 254 | 239 |
| 255 AccumulateInfo* info = new AccumulateInfo; | 240 AccumulateInfo* info = new AccumulateInfo; |
| 256 // Getting host usage may synchronously return the result if the usage is | 241 // Getting host usage may synchronously return the result if the usage is |
| 257 // cached, which may in turn dispatch the completion callback before we finish | 242 // cached, which may in turn dispatch the completion callback before we finish |
| 258 // looping over all hosts (because info->pending_jobs may reach 0 during the | 243 // looping over all hosts (because info->pending_jobs may reach 0 during the |
| 259 // loop). To avoid this, we add one more pending host as a sentinel and | 244 // loop). To avoid this, we add one more pending host as a sentinel and |
| 260 // fire the sentinel callback at the end. | 245 // fire the sentinel callback at the end. |
| 261 info->pending_jobs = origins_by_host.size() + 1; | 246 info->pending_jobs = origins_by_host.size() + 1; |
| 262 HostUsageAccumulator accumulator = | 247 HostUsageAccumulator accumulator = |
| 263 base::Bind(&ClientUsageTracker::AccumulateHostUsage, AsWeakPtr(), | 248 base::Bind(&ClientUsageTracker::AccumulateHostUsage, AsWeakPtr(), |
| 264 base::Owned(info), callback); | 249 base::Owned(info), callback); |
| 265 | 250 |
| 266 for (OriginSetByHost::iterator itr = origins_by_host.begin(); | 251 for (const auto& host_and_origins : origins_by_host) { |
| 267 itr != origins_by_host.end(); ++itr) { | 252 const std::string& host = host_and_origins.first; |
| 268 if (host_usage_accumulators_.Add(itr->first, accumulator)) | 253 const std::set<GURL>& origins = host_and_origins.second; |
| 269 GetUsageForOrigins(itr->first, itr->second); | 254 if (host_usage_accumulators_.Add(host, accumulator)) |
| 255 GetUsageForOrigins(host, origins); |
| 270 } | 256 } |
| 271 | 257 |
| 272 // Fire the sentinel as we've now called GetUsageForOrigins for all clients. | 258 // Fire the sentinel as we've now called GetUsageForOrigins for all clients. |
| 273 accumulator.Run(0, 0); | 259 accumulator.Run(0, 0); |
| 274 } | 260 } |
| 275 | 261 |
| 276 void ClientUsageTracker::AccumulateHostUsage( | 262 void ClientUsageTracker::AccumulateHostUsage( |
| 277 AccumulateInfo* info, | 263 AccumulateInfo* info, |
| 278 const GlobalUsageCallback& callback, | 264 const GlobalUsageCallback& callback, |
| 279 int64 limited_usage, | 265 int64 limited_usage, |
| (...skipping 24 matching lines...) Expand all Loading... |
| 304 // Getting origin usage may synchronously return the result if the usage is | 290 // Getting origin usage may synchronously return the result if the usage is |
| 305 // cached, which may in turn dispatch the completion callback before we finish | 291 // cached, which may in turn dispatch the completion callback before we finish |
| 306 // looping over all origins (because info->pending_jobs may reach 0 during the | 292 // looping over all origins (because info->pending_jobs may reach 0 during the |
| 307 // loop). To avoid this, we add one more pending origin as a sentinel and | 293 // loop). To avoid this, we add one more pending origin as a sentinel and |
| 308 // fire the sentinel callback at the end. | 294 // fire the sentinel callback at the end. |
| 309 info->pending_jobs = origins.size() + 1; | 295 info->pending_jobs = origins.size() + 1; |
| 310 OriginUsageAccumulator accumulator = | 296 OriginUsageAccumulator accumulator = |
| 311 base::Bind(&ClientUsageTracker::AccumulateOriginUsage, AsWeakPtr(), | 297 base::Bind(&ClientUsageTracker::AccumulateOriginUsage, AsWeakPtr(), |
| 312 base::Owned(info), host); | 298 base::Owned(info), host); |
| 313 | 299 |
| 314 for (std::set<GURL>::const_iterator itr = origins.begin(); | 300 for (const auto& origin : origins) { |
| 315 itr != origins.end(); ++itr) { | 301 DCHECK_EQ(host, net::GetHostOrSpecFromURL(origin)); |
| 316 DCHECK_EQ(host, net::GetHostOrSpecFromURL(*itr)); | |
| 317 | 302 |
| 318 int64 origin_usage = 0; | 303 int64 origin_usage = 0; |
| 319 if (GetCachedOriginUsage(*itr, &origin_usage)) { | 304 if (GetCachedOriginUsage(origin, &origin_usage)) |
| 320 accumulator.Run(*itr, origin_usage); | 305 accumulator.Run(origin, origin_usage); |
| 321 } else { | 306 else |
| 322 client_->GetOriginUsage(*itr, type_, base::Bind( | 307 client_->GetOriginUsage(origin, type_, base::Bind(accumulator, origin)); |
| 323 &DidGetOriginUsage, accumulator, *itr)); | |
| 324 } | |
| 325 } | 308 } |
| 326 | 309 |
| 327 // Fire the sentinel as we've now called GetOriginUsage for all clients. | 310 // Fire the sentinel as we've now called GetOriginUsage for all clients. |
| 328 accumulator.Run(GURL(), 0); | 311 accumulator.Run(GURL(), 0); |
| 329 } | 312 } |
| 330 | 313 |
| 331 void ClientUsageTracker::AccumulateOriginUsage(AccumulateInfo* info, | 314 void ClientUsageTracker::AccumulateOriginUsage(AccumulateInfo* info, |
| 332 const std::string& host, | 315 const std::string& host, |
| 333 const GURL& origin, | 316 const GURL& origin, |
| 334 int64 usage) { | 317 int64 usage) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 void ClientUsageTracker::AddCachedHost(const std::string& host) { | 364 void ClientUsageTracker::AddCachedHost(const std::string& host) { |
| 382 cached_hosts_.insert(host); | 365 cached_hosts_.insert(host); |
| 383 } | 366 } |
| 384 | 367 |
| 385 int64 ClientUsageTracker::GetCachedHostUsage(const std::string& host) const { | 368 int64 ClientUsageTracker::GetCachedHostUsage(const std::string& host) const { |
| 386 HostUsageMap::const_iterator found = cached_usage_by_host_.find(host); | 369 HostUsageMap::const_iterator found = cached_usage_by_host_.find(host); |
| 387 if (found == cached_usage_by_host_.end()) | 370 if (found == cached_usage_by_host_.end()) |
| 388 return 0; | 371 return 0; |
| 389 | 372 |
| 390 int64 usage = 0; | 373 int64 usage = 0; |
| 391 const UsageMap& map = found->second; | 374 const UsageMap& usage_map = found->second; |
| 392 for (UsageMap::const_iterator iter = map.begin(); | 375 for (const auto& origin_and_usage : usage_map) |
| 393 iter != map.end(); ++iter) { | 376 usage += origin_and_usage.second; |
| 394 usage += iter->second; | |
| 395 } | |
| 396 return usage; | 377 return usage; |
| 397 } | 378 } |
| 398 | 379 |
| 399 bool ClientUsageTracker::GetCachedOriginUsage( | 380 bool ClientUsageTracker::GetCachedOriginUsage( |
| 400 const GURL& origin, | 381 const GURL& origin, |
| 401 int64* usage) const { | 382 int64* usage) const { |
| 402 std::string host = net::GetHostOrSpecFromURL(origin); | 383 std::string host = net::GetHostOrSpecFromURL(origin); |
| 403 HostUsageMap::const_iterator found_host = cached_usage_by_host_.find(host); | 384 HostUsageMap::const_iterator found_host = cached_usage_by_host_.find(host); |
| 404 if (found_host == cached_usage_by_host_.end()) | 385 if (found_host == cached_usage_by_host_.end()) |
| 405 return false; | 386 return false; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 host, origin)) | 435 host, origin)) |
| 455 non_cached_limited_origins_by_host_[host].insert(origin); | 436 non_cached_limited_origins_by_host_[host].insert(origin); |
| 456 } | 437 } |
| 457 } | 438 } |
| 458 | 439 |
| 459 void ClientUsageTracker::OnCleared() { | 440 void ClientUsageTracker::OnCleared() { |
| 460 DCHECK(CalledOnValidThread()); | 441 DCHECK(CalledOnValidThread()); |
| 461 global_limited_usage_ += global_unlimited_usage_; | 442 global_limited_usage_ += global_unlimited_usage_; |
| 462 global_unlimited_usage_ = 0; | 443 global_unlimited_usage_ = 0; |
| 463 | 444 |
| 464 for (OriginSetByHost::const_iterator host_itr = | 445 for (const auto& host_and_origins : non_cached_unlimited_origins_by_host_) { |
| 465 non_cached_unlimited_origins_by_host_.begin(); | 446 const auto& host = host_and_origins.first; |
| 466 host_itr != non_cached_unlimited_origins_by_host_.end(); | 447 for (const auto& origin : host_and_origins.second) |
| 467 ++host_itr) { | 448 non_cached_limited_origins_by_host_[host].insert(origin); |
| 468 for (std::set<GURL>::const_iterator origin_itr = host_itr->second.begin(); | |
| 469 origin_itr != host_itr->second.end(); | |
| 470 ++origin_itr) | |
| 471 non_cached_limited_origins_by_host_[host_itr->first].insert(*origin_itr); | |
| 472 } | 449 } |
| 473 non_cached_unlimited_origins_by_host_.clear(); | 450 non_cached_unlimited_origins_by_host_.clear(); |
| 474 } | 451 } |
| 475 | 452 |
| 476 bool ClientUsageTracker::IsStorageUnlimited(const GURL& origin) const { | 453 bool ClientUsageTracker::IsStorageUnlimited(const GURL& origin) const { |
| 477 if (type_ == kStorageTypeSyncable) | 454 if (type_ == kStorageTypeSyncable) |
| 478 return false; | 455 return false; |
| 479 return special_storage_policy_.get() && | 456 return special_storage_policy_.get() && |
| 480 special_storage_policy_->IsStorageUnlimited(origin); | 457 special_storage_policy_->IsStorageUnlimited(origin); |
| 481 } | 458 } |
| 482 | 459 |
| 483 } // namespace storage | 460 } // namespace storage |
| OLD | NEW |