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 |