| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/quota/usage_tracker.h" | 5 #include "webkit/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 | 11 |
| 12 #include "base/message_loop_proxy.h" | 12 #include "base/message_loop_proxy.h" |
| 13 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
| 14 #include "net/base/net_util.h" | 14 #include "net/base/net_util.h" |
| 15 #include "webkit/quota/special_storage_policy.h" | |
| 16 | 15 |
| 17 namespace quota { | 16 namespace quota { |
| 18 | 17 |
| 19 namespace { | 18 namespace { |
| 20 bool SortByHost(const GURL& lhs, const GURL& rhs) { | 19 bool SortByHost(const GURL& lhs, const GURL& rhs) { |
| 21 return net::GetHostOrSpecFromURL(lhs) > net::GetHostOrSpecFromURL(rhs); | 20 return net::GetHostOrSpecFromURL(lhs) > net::GetHostOrSpecFromURL(rhs); |
| 22 } | 21 } |
| 23 } | 22 } |
| 24 | 23 |
| 25 // A task class for getting the total amount of data used for a collection of | 24 // A task class for getting the total amount of data used for a collection of |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 | 326 |
| 328 ClientUsageTracker::ClientUsageTracker( | 327 ClientUsageTracker::ClientUsageTracker( |
| 329 UsageTracker* tracker, QuotaClient* client, StorageType type, | 328 UsageTracker* tracker, QuotaClient* client, StorageType type, |
| 330 SpecialStoragePolicy* special_storage_policy) | 329 SpecialStoragePolicy* special_storage_policy) |
| 331 : tracker_(tracker), | 330 : tracker_(tracker), |
| 332 client_(client), | 331 client_(client), |
| 333 type_(type), | 332 type_(type), |
| 334 global_usage_(0), | 333 global_usage_(0), |
| 335 global_unlimited_usage_(0), | 334 global_unlimited_usage_(0), |
| 336 global_usage_retrieved_(false), | 335 global_usage_retrieved_(false), |
| 336 global_unlimited_usage_is_valid_(true), |
| 337 global_usage_task_(NULL), | 337 global_usage_task_(NULL), |
| 338 special_storage_policy_(special_storage_policy) { | 338 special_storage_policy_(special_storage_policy) { |
| 339 DCHECK(tracker_); | 339 DCHECK(tracker_); |
| 340 DCHECK(client_); | 340 DCHECK(client_); |
| 341 if (special_storage_policy_) |
| 342 special_storage_policy_->AddObserver(this); |
| 341 } | 343 } |
| 342 | 344 |
| 343 ClientUsageTracker::~ClientUsageTracker() { | 345 ClientUsageTracker::~ClientUsageTracker() { |
| 346 if (special_storage_policy_) |
| 347 special_storage_policy_->RemoveObserver(this); |
| 344 } | 348 } |
| 345 | 349 |
| 346 void ClientUsageTracker::GetGlobalUsage(GlobalUsageCallback* callback) { | 350 void ClientUsageTracker::GetGlobalUsage(GlobalUsageCallback* callback) { |
| 347 if (global_usage_retrieved_) { | 351 if (global_usage_retrieved_) { |
| 348 callback->Run(type_, global_usage_, global_unlimited_usage_); | 352 callback->Run(type_, global_usage_, GetCachedGlobalUnlimitedUsage()); |
| 349 delete callback; | 353 delete callback; |
| 350 return; | 354 return; |
| 351 } | 355 } |
| 352 DCHECK(!global_usage_callback_.HasCallbacks()); | 356 DCHECK(!global_usage_callback_.HasCallbacks()); |
| 353 global_usage_callback_.Add(callback); | 357 global_usage_callback_.Add(callback); |
| 354 global_usage_task_ = new GatherGlobalUsageTask(tracker_, client_); | 358 global_usage_task_ = new GatherGlobalUsageTask(tracker_, client_); |
| 355 global_usage_task_->Start(); | 359 global_usage_task_->Start(); |
| 356 } | 360 } |
| 357 | 361 |
| 358 void ClientUsageTracker::GetHostUsage( | 362 void ClientUsageTracker::GetHostUsage( |
| (...skipping 11 matching lines...) Expand all Loading... |
| 370 host_usage_tasks_[host] = task; | 374 host_usage_tasks_[host] = task; |
| 371 task->Start(); | 375 task->Start(); |
| 372 } | 376 } |
| 373 | 377 |
| 374 void ClientUsageTracker::UpdateUsageCache( | 378 void ClientUsageTracker::UpdateUsageCache( |
| 375 const GURL& origin, int64 delta) { | 379 const GURL& origin, int64 delta) { |
| 376 std::string host = net::GetHostOrSpecFromURL(origin); | 380 std::string host = net::GetHostOrSpecFromURL(origin); |
| 377 if (cached_hosts_.find(host) != cached_hosts_.end()) { | 381 if (cached_hosts_.find(host) != cached_hosts_.end()) { |
| 378 cached_usage_[host][origin] += delta; | 382 cached_usage_[host][origin] += delta; |
| 379 global_usage_ += delta; | 383 global_usage_ += delta; |
| 380 if (IsStorageUnlimited(origin)) | 384 if (global_unlimited_usage_is_valid_ && IsStorageUnlimited(origin)) |
| 381 global_unlimited_usage_ += delta; | 385 global_unlimited_usage_ += delta; |
| 382 DCHECK_GE(cached_usage_[host][origin], 0); | 386 DCHECK_GE(cached_usage_[host][origin], 0); |
| 383 DCHECK_GE(global_usage_, 0); | 387 DCHECK_GE(global_usage_, 0); |
| 384 return; | 388 return; |
| 385 } | 389 } |
| 386 | 390 |
| 387 // We don't know about this host yet, so populate our cache for it. | 391 // We don't know about this host yet, so populate our cache for it. |
| 388 GetHostUsage(host, | 392 GetHostUsage(host, |
| 389 NewCallback(this, &ClientUsageTracker::NoopHostUsageCallback)); | 393 NewCallback(this, &ClientUsageTracker::NoopHostUsageCallback)); |
| 390 } | 394 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 404 void ClientUsageTracker::AddCachedOrigin( | 408 void ClientUsageTracker::AddCachedOrigin( |
| 405 const GURL& origin, int64 usage) { | 409 const GURL& origin, int64 usage) { |
| 406 std::string host = net::GetHostOrSpecFromURL(origin); | 410 std::string host = net::GetHostOrSpecFromURL(origin); |
| 407 UsageMap::iterator iter = cached_usage_[host]. | 411 UsageMap::iterator iter = cached_usage_[host]. |
| 408 insert(UsageMap::value_type(origin, 0)).first; | 412 insert(UsageMap::value_type(origin, 0)).first; |
| 409 int64 old_usage = iter->second; | 413 int64 old_usage = iter->second; |
| 410 iter->second = usage; | 414 iter->second = usage; |
| 411 int64 delta = usage - old_usage; | 415 int64 delta = usage - old_usage; |
| 412 if (delta) { | 416 if (delta) { |
| 413 global_usage_ += delta; | 417 global_usage_ += delta; |
| 414 if (IsStorageUnlimited(origin)) | 418 if (global_unlimited_usage_is_valid_ && IsStorageUnlimited(origin)) |
| 415 global_unlimited_usage_ += delta; | 419 global_unlimited_usage_ += delta; |
| 416 } | 420 } |
| 417 DCHECK_GE(iter->second, 0); | 421 DCHECK_GE(iter->second, 0); |
| 418 DCHECK_GE(global_usage_, 0); | 422 DCHECK_GE(global_usage_, 0); |
| 419 } | 423 } |
| 420 | 424 |
| 421 void ClientUsageTracker::AddCachedHost(const std::string& host) { | 425 void ClientUsageTracker::AddCachedHost(const std::string& host) { |
| 422 cached_hosts_.insert(host); | 426 cached_hosts_.insert(host); |
| 423 } | 427 } |
| 424 | 428 |
| 425 void ClientUsageTracker::GatherGlobalUsageComplete() { | 429 void ClientUsageTracker::GatherGlobalUsageComplete() { |
| 426 DCHECK(global_usage_task_ != NULL); | 430 DCHECK(global_usage_task_ != NULL); |
| 427 global_usage_task_ = NULL; | 431 global_usage_task_ = NULL; |
| 428 // TODO(kinuko): Record when it has retrieved the global usage. | 432 // TODO(kinuko): Record when it has retrieved the global usage. |
| 429 global_usage_retrieved_ = true; | 433 global_usage_retrieved_ = true; |
| 430 | 434 |
| 431 DCHECK(global_usage_callback_.HasCallbacks()); | 435 DCHECK(global_usage_callback_.HasCallbacks()); |
| 432 global_usage_callback_.Run(type_, global_usage_, global_unlimited_usage_); | 436 global_usage_callback_.Run(type_, global_usage_, |
| 437 GetCachedGlobalUnlimitedUsage()); |
| 433 | 438 |
| 434 for (HostUsageCallbackMap::iterator iter = host_usage_callbacks_.Begin(); | 439 for (HostUsageCallbackMap::iterator iter = host_usage_callbacks_.Begin(); |
| 435 iter != host_usage_callbacks_.End(); ++iter) { | 440 iter != host_usage_callbacks_.End(); ++iter) { |
| 436 iter->second.Run(iter->first, type_, GetCachedHostUsage(iter->first)); | 441 iter->second.Run(iter->first, type_, GetCachedHostUsage(iter->first)); |
| 437 } | 442 } |
| 438 host_usage_callbacks_.Clear(); | 443 host_usage_callbacks_.Clear(); |
| 439 } | 444 } |
| 440 | 445 |
| 441 void ClientUsageTracker::GatherHostUsageComplete(const std::string& host) { | 446 void ClientUsageTracker::GatherHostUsageComplete(const std::string& host) { |
| 442 DCHECK(host_usage_tasks_.find(host) != host_usage_tasks_.end()); | 447 DCHECK(host_usage_tasks_.find(host) != host_usage_tasks_.end()); |
| 443 host_usage_tasks_.erase(host); | 448 host_usage_tasks_.erase(host); |
| 444 host_usage_callbacks_.Run(host, host, type_, GetCachedHostUsage(host)); | 449 host_usage_callbacks_.Run(host, host, type_, GetCachedHostUsage(host)); |
| 445 } | 450 } |
| 446 | 451 |
| 447 int64 ClientUsageTracker::GetCachedHostUsage(const std::string& host) { | 452 int64 ClientUsageTracker::GetCachedHostUsage(const std::string& host) { |
| 448 HostUsageMap::const_iterator found = cached_usage_.find(host); | 453 HostUsageMap::const_iterator found = cached_usage_.find(host); |
| 449 if (found == cached_usage_.end()) | 454 if (found == cached_usage_.end()) |
| 450 return 0; | 455 return 0; |
| 451 | 456 |
| 452 int64 usage = 0; | 457 int64 usage = 0; |
| 453 const UsageMap& map = found->second; | 458 const UsageMap& map = found->second; |
| 454 for (UsageMap::const_iterator iter = map.begin(); | 459 for (UsageMap::const_iterator iter = map.begin(); |
| 455 iter != map.end(); ++iter) { | 460 iter != map.end(); ++iter) { |
| 456 usage += iter->second; | 461 usage += iter->second; |
| 457 } | 462 } |
| 458 return usage; | 463 return usage; |
| 459 } | 464 } |
| 460 | 465 |
| 466 int64 ClientUsageTracker::GetCachedGlobalUnlimitedUsage() { |
| 467 if (!global_unlimited_usage_is_valid_) { |
| 468 global_unlimited_usage_ = 0; |
| 469 for (HostUsageMap::const_iterator host_iter = cached_usage_.begin(); |
| 470 host_iter != cached_usage_.end(); host_iter++) { |
| 471 const UsageMap& origin_map = host_iter->second; |
| 472 for (UsageMap::const_iterator origin_iter = origin_map.begin(); |
| 473 origin_iter != origin_map.end(); origin_iter++) { |
| 474 if (IsStorageUnlimited(origin_iter->first)) |
| 475 global_unlimited_usage_ += origin_iter->second; |
| 476 } |
| 477 } |
| 478 global_unlimited_usage_is_valid_ = true; |
| 479 } |
| 480 return global_unlimited_usage_; |
| 481 } |
| 482 |
| 483 void ClientUsageTracker::OnSpecialStoragePolicyChanged() { |
| 484 DCHECK(CalledOnValidThread()); |
| 485 global_unlimited_usage_is_valid_ = false; |
| 486 } |
| 487 |
| 461 void ClientUsageTracker::NoopHostUsageCallback( | 488 void ClientUsageTracker::NoopHostUsageCallback( |
| 462 const std::string& host, StorageType type, int64 usage) { | 489 const std::string& host, StorageType type, int64 usage) { |
| 463 } | 490 } |
| 464 | 491 |
| 465 bool ClientUsageTracker::IsStorageUnlimited(const GURL& origin) const { | 492 bool ClientUsageTracker::IsStorageUnlimited(const GURL& origin) const { |
| 466 return special_storage_policy_.get() && | 493 return special_storage_policy_.get() && |
| 467 special_storage_policy_->IsStorageUnlimited(origin); | 494 special_storage_policy_->IsStorageUnlimited(origin); |
| 468 } | 495 } |
| 469 | 496 |
| 470 } // namespace quota | 497 } // namespace quota |
| OLD | NEW |