| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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/quota_manager.h" | 5 #include "storage/browser/quota/quota_manager.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| 11 #include <functional> | 11 #include <functional> |
| 12 #include <limits> | 12 #include <limits> |
| 13 #include <memory> | 13 #include <memory> |
| 14 #include <utility> | 14 #include <utility> |
| 15 | 15 |
| 16 #include "base/bind.h" | 16 #include "base/bind.h" |
| 17 #include "base/bind_helpers.h" | 17 #include "base/bind_helpers.h" |
| 18 #include "base/command_line.h" | 18 #include "base/command_line.h" |
| 19 #include "base/files/file_util.h" | 19 #include "base/files/file_util.h" |
| 20 #include "base/macros.h" | 20 #include "base/macros.h" |
| 21 #include "base/metrics/histogram.h" | 21 #include "base/metrics/histogram.h" |
| 22 #include "base/numerics/safe_conversions.h" |
| 22 #include "base/profiler/scoped_tracker.h" | 23 #include "base/profiler/scoped_tracker.h" |
| 23 #include "base/sequenced_task_runner.h" | 24 #include "base/sequenced_task_runner.h" |
| 24 #include "base/single_thread_task_runner.h" | 25 #include "base/single_thread_task_runner.h" |
| 25 #include "base/strings/string_number_conversions.h" | 26 #include "base/strings/string_number_conversions.h" |
| 26 #include "base/sys_info.h" | 27 #include "base/sys_info.h" |
| 27 #include "base/task_runner_util.h" | 28 #include "base/task_runner_util.h" |
| 28 #include "base/time/time.h" | 29 #include "base/time/time.h" |
| 29 #include "base/trace_event/trace_event.h" | 30 #include "base/trace_event/trace_event.h" |
| 30 #include "net/base/url_util.h" | 31 #include "net/base/url_util.h" |
| 31 #include "storage/browser/quota/client_usage_tracker.h" | 32 #include "storage/browser/quota/client_usage_tracker.h" |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 quota = std::min(quota, QuotaManager::kIncognitoDefaultQuotaLimit); | 333 quota = std::min(quota, QuotaManager::kIncognitoDefaultQuotaLimit); |
| 333 callback.Run(status, usage, quota); | 334 callback.Run(status, usage, quota); |
| 334 return; | 335 return; |
| 335 } | 336 } |
| 336 | 337 |
| 337 // For apps with unlimited permission or can_query_disk_size is true (and not | 338 // For apps with unlimited permission or can_query_disk_size is true (and not |
| 338 // in incognito mode). | 339 // in incognito mode). |
| 339 // We assume we can expose the actual disk size for them and cap the quota by | 340 // We assume we can expose the actual disk size for them and cap the quota by |
| 340 // the available disk space. | 341 // the available disk space. |
| 341 if (is_unlimited || can_query_disk_size) { | 342 if (is_unlimited || can_query_disk_size) { |
| 342 callback.Run( | 343 quota = CalculateQuotaWithDiskSpace( |
| 343 status, usage, | 344 usage_and_quota.available_disk_space, |
| 344 CalculateQuotaWithDiskSpace( | 345 usage, quota); |
| 345 usage_and_quota.available_disk_space, | |
| 346 usage, quota)); | |
| 347 return; | |
| 348 } | 346 } |
| 349 | 347 |
| 350 callback.Run(status, usage, quota); | 348 callback.Run(status, usage, quota); |
| 349 |
| 350 if (type == kStorageTypeTemporary && !is_unlimited) |
| 351 UMA_HISTOGRAM_MBYTES("Quota.QuotaForOrigin", quota); |
| 351 } | 352 } |
| 352 | 353 |
| 353 } // namespace | 354 } // namespace |
| 354 | 355 |
| 355 UsageAndQuota::UsageAndQuota() | 356 UsageAndQuota::UsageAndQuota() |
| 356 : usage(0), | 357 : usage(0), |
| 357 global_limited_usage(0), | 358 global_limited_usage(0), |
| 358 quota(0), | 359 quota(0), |
| 359 available_disk_space(0) { | 360 available_disk_space(0) { |
| 360 } | 361 } |
| (...skipping 1109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1470 return; | 1471 return; |
| 1471 } | 1472 } |
| 1472 | 1473 |
| 1473 DCHECK(origin == origin.GetOrigin()); | 1474 DCHECK(origin == origin.GetOrigin()); |
| 1474 OriginDataDeleter* deleter = new OriginDataDeleter( | 1475 OriginDataDeleter* deleter = new OriginDataDeleter( |
| 1475 this, origin, type, quota_client_mask, is_eviction, callback); | 1476 this, origin, type, quota_client_mask, is_eviction, callback); |
| 1476 deleter->Start(); | 1477 deleter->Start(); |
| 1477 } | 1478 } |
| 1478 | 1479 |
| 1479 void QuotaManager::ReportHistogram() { | 1480 void QuotaManager::ReportHistogram() { |
| 1481 DCHECK(!is_incognito_); |
| 1480 GetGlobalUsage(kStorageTypeTemporary, | 1482 GetGlobalUsage(kStorageTypeTemporary, |
| 1481 base::Bind( | 1483 base::Bind( |
| 1482 &QuotaManager::DidGetTemporaryGlobalUsageForHistogram, | 1484 &QuotaManager::DidGetTemporaryGlobalUsageForHistogram, |
| 1483 weak_factory_.GetWeakPtr())); | 1485 weak_factory_.GetWeakPtr())); |
| 1484 GetGlobalUsage(kStorageTypePersistent, | |
| 1485 base::Bind( | |
| 1486 &QuotaManager::DidGetPersistentGlobalUsageForHistogram, | |
| 1487 weak_factory_.GetWeakPtr())); | |
| 1488 } | 1486 } |
| 1489 | 1487 |
| 1490 void QuotaManager::DidGetTemporaryGlobalUsageForHistogram( | 1488 void QuotaManager::DidGetTemporaryGlobalUsageForHistogram( |
| 1491 int64_t usage, | 1489 int64_t usage, |
| 1492 int64_t unlimited_usage) { | 1490 int64_t unlimited_usage) { |
| 1493 UMA_HISTOGRAM_MBYTES("Quota.GlobalUsageOfTemporaryStorage", usage); | 1491 UMA_HISTOGRAM_MBYTES("Quota.GlobalUsageOfTemporaryStorage", usage); |
| 1494 | 1492 |
| 1495 std::set<GURL> origins; | 1493 std::set<GURL> origins; |
| 1496 GetCachedOrigins(kStorageTypeTemporary, &origins); | 1494 GetCachedOrigins(kStorageTypeTemporary, &origins); |
| 1497 | 1495 |
| 1498 size_t num_origins = origins.size(); | 1496 size_t num_origins = origins.size(); |
| 1499 size_t protected_origins = 0; | 1497 size_t protected_origins = 0; |
| 1500 size_t unlimited_origins = 0; | 1498 size_t unlimited_origins = 0; |
| 1501 CountOriginType(origins, | 1499 CountOriginType(origins, |
| 1502 special_storage_policy_.get(), | 1500 special_storage_policy_.get(), |
| 1503 &protected_origins, | 1501 &protected_origins, |
| 1504 &unlimited_origins); | 1502 &unlimited_origins); |
| 1505 | |
| 1506 UMA_HISTOGRAM_COUNTS("Quota.NumberOfTemporaryStorageOrigins", | 1503 UMA_HISTOGRAM_COUNTS("Quota.NumberOfTemporaryStorageOrigins", |
| 1507 num_origins); | 1504 num_origins); |
| 1508 UMA_HISTOGRAM_COUNTS("Quota.NumberOfProtectedTemporaryStorageOrigins", | 1505 UMA_HISTOGRAM_COUNTS("Quota.NumberOfProtectedTemporaryStorageOrigins", |
| 1509 protected_origins); | 1506 protected_origins); |
| 1510 UMA_HISTOGRAM_COUNTS("Quota.NumberOfUnlimitedTemporaryStorageOrigins", | 1507 UMA_HISTOGRAM_COUNTS("Quota.NumberOfUnlimitedTemporaryStorageOrigins", |
| 1511 unlimited_origins); | 1508 unlimited_origins); |
| 1509 |
| 1510 GetGlobalUsage(kStorageTypePersistent, |
| 1511 base::Bind( |
| 1512 &QuotaManager::DidGetPersistentGlobalUsageForHistogram, |
| 1513 weak_factory_.GetWeakPtr())); |
| 1512 } | 1514 } |
| 1513 | 1515 |
| 1514 void QuotaManager::DidGetPersistentGlobalUsageForHistogram( | 1516 void QuotaManager::DidGetPersistentGlobalUsageForHistogram( |
| 1515 int64_t usage, | 1517 int64_t usage, |
| 1516 int64_t unlimited_usage) { | 1518 int64_t unlimited_usage) { |
| 1517 UMA_HISTOGRAM_MBYTES("Quota.GlobalUsageOfPersistentStorage", usage); | 1519 UMA_HISTOGRAM_MBYTES("Quota.GlobalUsageOfPersistentStorage", usage); |
| 1518 | 1520 |
| 1519 std::set<GURL> origins; | 1521 std::set<GURL> origins; |
| 1520 GetCachedOrigins(kStorageTypePersistent, &origins); | 1522 GetCachedOrigins(kStorageTypePersistent, &origins); |
| 1521 | 1523 |
| 1522 size_t num_origins = origins.size(); | 1524 size_t num_origins = origins.size(); |
| 1523 size_t protected_origins = 0; | 1525 size_t protected_origins = 0; |
| 1524 size_t unlimited_origins = 0; | 1526 size_t unlimited_origins = 0; |
| 1525 CountOriginType(origins, | 1527 CountOriginType(origins, |
| 1526 special_storage_policy_.get(), | 1528 special_storage_policy_.get(), |
| 1527 &protected_origins, | 1529 &protected_origins, |
| 1528 &unlimited_origins); | 1530 &unlimited_origins); |
| 1529 | |
| 1530 UMA_HISTOGRAM_COUNTS("Quota.NumberOfPersistentStorageOrigins", | 1531 UMA_HISTOGRAM_COUNTS("Quota.NumberOfPersistentStorageOrigins", |
| 1531 num_origins); | 1532 num_origins); |
| 1532 UMA_HISTOGRAM_COUNTS("Quota.NumberOfProtectedPersistentStorageOrigins", | 1533 UMA_HISTOGRAM_COUNTS("Quota.NumberOfProtectedPersistentStorageOrigins", |
| 1533 protected_origins); | 1534 protected_origins); |
| 1534 UMA_HISTOGRAM_COUNTS("Quota.NumberOfUnlimitedPersistentStorageOrigins", | 1535 UMA_HISTOGRAM_COUNTS("Quota.NumberOfUnlimitedPersistentStorageOrigins", |
| 1535 unlimited_origins); | 1536 unlimited_origins); |
| 1537 |
| 1538 // We DumpOriginInfoTable last to ensure the trackers caches are loaded. |
| 1539 DumpOriginInfoTable( |
| 1540 base::Bind(&QuotaManager::DidDumpOriginInfoTableForHistogram, |
| 1541 weak_factory_.GetWeakPtr())); |
| 1542 } |
| 1543 |
| 1544 void QuotaManager::DidDumpOriginInfoTableForHistogram( |
| 1545 const OriginInfoTableEntries& entries) { |
| 1546 using UsageMap = std::map<GURL, int64_t>; |
| 1547 UsageMap usage_map; |
| 1548 GetUsageTracker(kStorageTypeTemporary)->GetCachedOriginsUsage(&usage_map); |
| 1549 base::Time now = base::Time::Now(); |
| 1550 for (const auto& info : entries) { |
| 1551 if (info.type != kStorageTypeTemporary) |
| 1552 continue; |
| 1553 |
| 1554 // Ignore stale database entries. If there is no map entry, the origin's |
| 1555 // data has been deleted. |
| 1556 UsageMap::const_iterator found = usage_map.find(info.origin); |
| 1557 if (found == usage_map.end() || found->second == 0) |
| 1558 continue; |
| 1559 |
| 1560 base::TimeDelta age = now - std::max(info.last_access_time, |
| 1561 info.last_modified_time); |
| 1562 UMA_HISTOGRAM_COUNTS_1000("Quota.AgeOfOriginInDays", age.InDays()); |
| 1563 |
| 1564 int64_t kilobytes = std::max(found->second / INT64_C(1024), INT64_C(1)); |
| 1565 base::Histogram::FactoryGet( |
| 1566 "Quota.AgeOfDataInDays", 1, 1000, 50, |
| 1567 base::HistogramBase::kUmaTargetedHistogramFlag)-> |
| 1568 AddCount(age.InDays(), |
| 1569 base::saturated_cast<int>(kilobytes)); |
| 1570 } |
| 1536 } | 1571 } |
| 1537 | 1572 |
| 1538 std::set<GURL> QuotaManager::GetEvictionOriginExceptions( | 1573 std::set<GURL> QuotaManager::GetEvictionOriginExceptions( |
| 1539 const std::set<GURL>& extra_exceptions) { | 1574 const std::set<GURL>& extra_exceptions) { |
| 1540 std::set<GURL> exceptions = extra_exceptions; | 1575 std::set<GURL> exceptions = extra_exceptions; |
| 1541 for (const auto& p : origins_in_use_) { | 1576 for (const auto& p : origins_in_use_) { |
| 1542 if (p.second > 0) | 1577 if (p.second > 0) |
| 1543 exceptions.insert(p.first); | 1578 exceptions.insert(p.first); |
| 1544 } | 1579 } |
| 1545 | 1580 |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1709 } | 1744 } |
| 1710 | 1745 |
| 1711 void QuotaManager::DidInitialize(int64_t* temporary_quota_override, | 1746 void QuotaManager::DidInitialize(int64_t* temporary_quota_override, |
| 1712 int64_t* desired_available_space, | 1747 int64_t* desired_available_space, |
| 1713 bool success) { | 1748 bool success) { |
| 1714 temporary_quota_override_ = *temporary_quota_override; | 1749 temporary_quota_override_ = *temporary_quota_override; |
| 1715 desired_available_space_ = *desired_available_space; | 1750 desired_available_space_ = *desired_available_space; |
| 1716 temporary_quota_initialized_ = true; | 1751 temporary_quota_initialized_ = true; |
| 1717 DidDatabaseWork(success); | 1752 DidDatabaseWork(success); |
| 1718 | 1753 |
| 1719 histogram_timer_.Start(FROM_HERE, | 1754 if (!is_incognito_) { |
| 1720 base::TimeDelta::FromMilliseconds( | 1755 histogram_timer_.Start(FROM_HERE, |
| 1721 kReportHistogramInterval), | 1756 base::TimeDelta::FromMilliseconds( |
| 1722 this, &QuotaManager::ReportHistogram); | 1757 kReportHistogramInterval), |
| 1758 this, &QuotaManager::ReportHistogram); |
| 1759 } |
| 1723 | 1760 |
| 1724 db_initialization_callbacks_.Run(); | 1761 db_initialization_callbacks_.Run(); |
| 1725 GetTemporaryGlobalQuota( | 1762 GetTemporaryGlobalQuota( |
| 1726 base::Bind(&QuotaManager::DidGetInitialTemporaryGlobalQuota, | 1763 base::Bind(&QuotaManager::DidGetInitialTemporaryGlobalQuota, |
| 1727 weak_factory_.GetWeakPtr(), base::TimeTicks::Now())); | 1764 weak_factory_.GetWeakPtr(), base::TimeTicks::Now())); |
| 1728 } | 1765 } |
| 1729 | 1766 |
| 1730 void QuotaManager::DidGetLRUOrigin(const GURL* origin, | 1767 void QuotaManager::DidGetLRUOrigin(const GURL* origin, |
| 1731 bool success) { | 1768 bool success) { |
| 1732 DidDatabaseWork(success); | 1769 DidDatabaseWork(success); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1835 return false; | 1872 return false; |
| 1836 *available_space = static_cast<uint64_t>(stats.f_bavail) * stats.f_frsize; | 1873 *available_space = static_cast<uint64_t>(stats.f_bavail) * stats.f_frsize; |
| 1837 *total_size = static_cast<uint64_t>(stats.f_blocks) * stats.f_frsize; | 1874 *total_size = static_cast<uint64_t>(stats.f_blocks) * stats.f_frsize; |
| 1838 #else | 1875 #else |
| 1839 #error Not implemented | 1876 #error Not implemented |
| 1840 #endif | 1877 #endif |
| 1841 return true; | 1878 return true; |
| 1842 } | 1879 } |
| 1843 | 1880 |
| 1844 } // namespace storage | 1881 } // namespace storage |
| OLD | NEW |