Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1243)

Unified Diff: storage/browser/quota/quota_manager.cc

Issue 1782053004: Change how the quota system computes the total poolsize for temporary storage (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « storage/browser/quota/quota_manager.h ('k') | storage/browser/quota/quota_manager_proxy.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: storage/browser/quota/quota_manager.cc
diff --git a/storage/browser/quota/quota_manager.cc b/storage/browser/quota/quota_manager.cc
index 489d7177017e892828cf3deb89f739c1b30d9d37..0c536bcf8b8f48424a6b4a480ba84364d8356b4c 100644
--- a/storage/browser/quota/quota_manager.cc
+++ b/storage/browser/quota/quota_manager.cc
@@ -13,6 +13,7 @@
#include <memory>
#include <utility>
+#include "base/barrier_closure.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
@@ -27,6 +28,7 @@
#include "base/sys_info.h"
#include "base/task_runner_util.h"
#include "base/threading/thread_restrictions.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "net/base/url_util.h"
@@ -37,66 +39,57 @@
#include "storage/browser/quota/usage_tracker.h"
#include "storage/common/quota/quota_types.h"
-#define UMA_HISTOGRAM_MBYTES(name, sample) \
- UMA_HISTOGRAM_CUSTOM_COUNTS( \
- (name), static_cast<int>((sample) / kMBytes), \
- 1, 10 * 1024 * 1024 /* 10TB */, 100)
-
namespace storage {
namespace {
const int64_t kMBytes = 1024 * 1024;
const int kMinutesInMilliSeconds = 60 * 1000;
-
const int64_t kReportHistogramInterval = 60 * 60 * 1000; // 1 hour
-const double kTemporaryQuotaRatioToAvail = 1.0 / 3.0; // 33%
-} // namespace
+#define UMA_HISTOGRAM_MBYTES(name, sample) \
+ UMA_HISTOGRAM_CUSTOM_COUNTS((name), static_cast<int>((sample) / kMBytes), 1, \
+ 10 * 1024 * 1024 /* 10TB */, 100)
-// Arbitrary for now, but must be reasonably small so that
-// in-memory databases can fit.
-// TODO(kinuko): Refer SysInfo::AmountOfPhysicalMemory() to determine this.
-const int64_t QuotaManager::kIncognitoDefaultQuotaLimit = 100 * kMBytes;
+} // namespace
const int64_t QuotaManager::kNoLimit = INT64_MAX;
-const int QuotaManager::kPerHostTemporaryPortion = 5; // 20%
-
// Cap size for per-host persistent quota determined by the histogram.
// This is a bit lax value because the histogram says nothing about per-host
// persistent storage usage and we determined by global persistent storage
// usage that is less than 10GB for almost all users.
const int64_t QuotaManager::kPerHostPersistentQuotaLimit = 10 * 1024 * kMBytes;
+// Heuristics: assuming average cloud server allows a few Gigs storage
+// on the server side and the storage needs to be shared for user data
+// and by multiple apps.
+int64_t QuotaManager::kSyncableStorageDefaultHostQuota = 500 * kMBytes;
+
const char QuotaManager::kDatabaseName[] = "QuotaManager";
const int QuotaManager::kThresholdOfErrorsToBeBlacklisted = 3;
-
-// Preserve kMinimumPreserveForSystem disk space for system book-keeping
-// when returning the quota to unlimited apps/extensions.
-// TODO(kinuko): This should be like 10% of the actual disk space.
-// For now we simply use a constant as getting the disk size needs
-// platform-dependent code. (http://crbug.com/178976)
-int64_t QuotaManager::kMinimumPreserveForSystem = 1024 * kMBytes;
-
const int QuotaManager::kEvictionIntervalInMilliSeconds =
30 * kMinutesInMilliSeconds;
-const char QuotaManager::kTimeBetweenRepeatedOriginEvictionsHistogram[] =
- "Quota.TimeBetweenRepeatedOriginEvictions";
+const char QuotaManager::kDaysBetweenRepeatedOriginEvictionsHistogram[] =
+ "Quota.DaysBetweenRepeatedOriginEvictions";
const char QuotaManager::kEvictedOriginAccessedCountHistogram[] =
"Quota.EvictedOriginAccessCount";
-const char QuotaManager::kEvictedOriginTimeSinceAccessHistogram[] =
- "Quota.EvictedOriginTimeSinceAccess";
-
-// Heuristics: assuming average cloud server allows a few Gigs storage
-// on the server side and the storage needs to be shared for user data
-// and by multiple apps.
-int64_t QuotaManager::kSyncableStorageDefaultHostQuota = 500 * kMBytes;
+const char QuotaManager::kEvictedOriginDaysSinceAccessHistogram[] =
+ "Quota.EvictedOriginDaysSinceAccess";
namespace {
+bool IsSupportedType(StorageType type) {
+ return type == kStorageTypeTemporary || type == kStorageTypePersistent ||
+ type == kStorageTypeSyncable;
+}
+
+bool IsSupportedIncognitoType(StorageType type) {
+ return type == kStorageTypeTemporary || type == kStorageTypePersistent;
+}
+
void CountOriginType(const std::set<GURL>& origins,
SpecialStoragePolicy* policy,
size_t* protected_origins,
@@ -117,17 +110,6 @@ void CountOriginType(const std::set<GURL>& origins,
}
}
-bool SetTemporaryGlobalOverrideQuotaOnDBThread(int64_t* new_quota,
- QuotaDatabase* database) {
- DCHECK(database);
- if (!database->SetQuotaConfigValue(
- QuotaDatabase::kTemporaryQuotaOverrideKey, *new_quota)) {
- *new_quota = -1;
- return false;
- }
- return true;
-}
-
bool GetPersistentHostQuotaOnDBThread(const std::string& host,
int64_t* quota,
QuotaDatabase* database) {
@@ -146,17 +128,6 @@ bool SetPersistentHostQuotaOnDBThread(const std::string& host,
return false;
}
-bool InitializeOnDBThread(int64_t* temporary_quota_override,
- int64_t* desired_available_space,
- QuotaDatabase* database) {
- DCHECK(database);
- database->GetQuotaConfigValue(QuotaDatabase::kTemporaryQuotaOverrideKey,
- temporary_quota_override);
- database->GetQuotaConfigValue(QuotaDatabase::kDesiredAvailableSpaceKey,
- desired_available_space);
- return true;
-}
-
bool GetLRUOriginOnDBThread(StorageType type,
const std::set<GURL>& exceptions,
SpecialStoragePolicy* policy,
@@ -180,9 +151,10 @@ bool DeleteOriginInfoOnDBThread(const GURL& origin,
database->GetOriginInfo(origin, type, &entry);
UMA_HISTOGRAM_COUNTS(QuotaManager::kEvictedOriginAccessedCountHistogram,
entry.used_count);
- UMA_HISTOGRAM_LONG_TIMES(
- QuotaManager::kEvictedOriginTimeSinceAccessHistogram,
- now - entry.last_access_time);
+ UMA_HISTOGRAM_COUNTS_1000(
+ QuotaManager::kEvictedOriginDaysSinceAccessHistogram,
+ (now - entry.last_access_time).InDays());
+
}
if (!database->DeleteOriginInfo(origin, type))
@@ -197,16 +169,16 @@ bool DeleteOriginInfoOnDBThread(const GURL& origin,
database->GetOriginLastEvictionTime(origin, type, &last_eviction_time);
if (last_eviction_time != base::Time()) {
- UMA_HISTOGRAM_LONG_TIMES(
- QuotaManager::kTimeBetweenRepeatedOriginEvictionsHistogram,
- now - last_eviction_time);
+ UMA_HISTOGRAM_COUNTS_1000(
+ QuotaManager::kDaysBetweenRepeatedOriginEvictionsHistogram,
+ (now - last_eviction_time).InDays());
}
return database->SetOriginLastEvictionTime(origin, type, now);
}
-bool InitializeTemporaryOriginsInfoOnDBThread(const std::set<GURL>* origins,
- QuotaDatabase* database) {
+bool BootstrapDatabaseOnDBThread(const std::set<GURL>* origins,
+ QuotaDatabase* database) {
DCHECK(database);
if (database->IsOriginDatabaseBootstrapped())
return true;
@@ -235,277 +207,233 @@ bool UpdateModifiedTimeOnDBThread(const GURL& origin,
return database->SetOriginLastModifiedTime(origin, type, modified_time);
}
-int64_t CalculateTemporaryGlobalQuota(int64_t global_limited_usage,
- int64_t available_space) {
- DCHECK_GE(global_limited_usage, 0);
- int64_t avail_space = available_space;
- if (avail_space <
- std::numeric_limits<int64_t>::max() - global_limited_usage) {
- // We basically calculate the temporary quota by
- // [available_space + space_used_for_temp] * kTempQuotaRatio,
- // but make sure we'll have no overflow.
- avail_space += global_limited_usage;
- }
- int64_t pool_size = avail_space * kTemporaryQuotaRatioToAvail;
- UMA_HISTOGRAM_MBYTES("Quota.GlobalTemporaryPoolSize", pool_size);
- return pool_size;
-}
-
-void DispatchTemporaryGlobalQuotaCallback(
- const QuotaCallback& callback,
- QuotaStatusCode status,
- const UsageAndQuota& usage_and_quota) {
- if (status != kQuotaStatusOk) {
- callback.Run(status, 0);
- return;
- }
-
- callback.Run(status, CalculateTemporaryGlobalQuota(
- usage_and_quota.global_limited_usage,
- usage_and_quota.available_disk_space));
-}
-
-int64_t CalculateQuotaWithDiskSpace(int64_t available_disk_space,
- int64_t usage,
- int64_t quota) {
- if (available_disk_space < QuotaManager::kMinimumPreserveForSystem) {
- LOG(WARNING)
- << "Running out of disk space for profile."
- << " QuotaManager starts forbidding further quota consumption.";
- return usage;
- }
-
- if (quota < usage) {
- // No more space; cap the quota to the current usage.
- return usage;
- }
-
- available_disk_space -= QuotaManager::kMinimumPreserveForSystem;
- if (available_disk_space < quota - usage)
- return available_disk_space + usage;
-
- return quota;
-}
-
-int64_t CalculateTemporaryHostQuota(int64_t host_usage,
- int64_t global_quota,
- int64_t global_limited_usage) {
- DCHECK_GE(global_limited_usage, 0);
- int64_t host_quota = global_quota / QuotaManager::kPerHostTemporaryPortion;
- if (global_limited_usage > global_quota)
- host_quota = std::min(host_quota, host_usage);
- return host_quota;
-}
-
-void DispatchUsageAndQuotaForWebApps(
- StorageType type,
- bool is_incognito,
- bool is_unlimited,
- bool can_query_disk_size,
- const QuotaManager::GetUsageAndQuotaCallback& callback,
- QuotaStatusCode status,
- const UsageAndQuota& usage_and_quota) {
- if (status != kQuotaStatusOk) {
- callback.Run(status, 0, 0);
- return;
- }
-
- int64_t usage = usage_and_quota.usage;
- int64_t quota = usage_and_quota.quota;
-
- if (type == kStorageTypeTemporary && !is_unlimited) {
- quota = CalculateTemporaryHostQuota(
- usage, quota, usage_and_quota.global_limited_usage);
- }
-
- if (is_incognito) {
- quota = std::min(quota, QuotaManager::kIncognitoDefaultQuotaLimit);
- callback.Run(status, usage, quota);
- return;
- }
-
- // For apps with unlimited permission or can_query_disk_size is true (and not
- // in incognito mode).
- // We assume we can expose the actual disk size for them and cap the quota by
- // the available disk space.
- if (is_unlimited || can_query_disk_size) {
- quota = CalculateQuotaWithDiskSpace(
- usage_and_quota.available_disk_space,
- usage, quota);
- }
-
- callback.Run(status, usage, quota);
-
- if (type == kStorageTypeTemporary && !is_unlimited)
- UMA_HISTOGRAM_MBYTES("Quota.QuotaForOrigin", quota);
-}
-
} // namespace
-UsageAndQuota::UsageAndQuota()
- : usage(0),
- global_limited_usage(0),
- quota(0),
- available_disk_space(0) {
-}
-
-UsageAndQuota::UsageAndQuota(int64_t usage,
- int64_t global_limited_usage,
- int64_t quota,
- int64_t available_disk_space)
- : usage(usage),
- global_limited_usage(global_limited_usage),
- quota(quota),
- available_disk_space(available_disk_space) {}
-
-class UsageAndQuotaCallbackDispatcher
- : public QuotaTask,
- public base::SupportsWeakPtr<UsageAndQuotaCallbackDispatcher> {
+class QuotaManager::UsageAndQuotaHelper : public QuotaTask {
public:
- explicit UsageAndQuotaCallbackDispatcher(QuotaManager* manager)
+ UsageAndQuotaHelper(QuotaManager* manager,
+ const GURL& origin,
+ StorageType type,
+ bool is_unlimited,
+ bool is_incognito,
+ const UsageAndQuotaCallback& callback)
: QuotaTask(manager),
- has_usage_(false),
- has_global_limited_usage_(false),
- has_quota_(false),
- has_available_disk_space_(false),
- status_(kQuotaStatusUnknown),
- usage_and_quota_(-1, -1, -1, -1),
- waiting_callbacks_(1) {}
-
- ~UsageAndQuotaCallbackDispatcher() override {}
-
- void WaitForResults(const QuotaManager::UsageAndQuotaCallback& callback) {
- callback_ = callback;
- Start();
- }
-
- void set_usage(int64_t usage) {
- usage_and_quota_.usage = usage;
- has_usage_ = true;
- }
-
- void set_global_limited_usage(int64_t global_limited_usage) {
- usage_and_quota_.global_limited_usage = global_limited_usage;
- has_global_limited_usage_ = true;
- }
+ origin_(origin),
+ callback_(callback),
+ type_(type),
+ is_unlimited_(is_unlimited),
+ is_incognito_(is_incognito),
+ weak_factory_(this) {}
- void set_quota(int64_t quota) {
- usage_and_quota_.quota = quota;
- has_quota_ = true;
+ protected:
+ void Run() override {
+ // Start the async process of gathering the info we need.
+ // Gather 4 pieces of info before computing an answer:
+ // settings, device_storage_capacity, host_usage, and host_quota.
+ base::Closure barrier = base::BarrierClosure(
+ 4, base::Bind(&UsageAndQuotaHelper::OnBarrierComplete,
+ weak_factory_.GetWeakPtr()));
+
+ std::string host = net::GetHostOrSpecFromURL(origin_);
+
+ manager()->GetQuotaSettings(base::Bind(&UsageAndQuotaHelper::OnGotSettings,
+ weak_factory_.GetWeakPtr(),
+ barrier));
+ manager()->GetStorageCapacity(
+ base::Bind(&UsageAndQuotaHelper::OnGotCapacity,
+ weak_factory_.GetWeakPtr(), barrier));
+ manager()->GetHostUsage(host, type_,
+ base::Bind(&UsageAndQuotaHelper::OnGotHostUsage,
+ weak_factory_.GetWeakPtr(), barrier));
+
+ // Determine host_quota differently depending on type.
+ if (is_unlimited_) {
+ SetDesiredHostQuota(barrier, kQuotaStatusOk, kNoLimit);
+ } else if (type_ == kStorageTypeSyncable) {
+ SetDesiredHostQuota(barrier, kQuotaStatusOk,
+ kSyncableStorageDefaultHostQuota);
+ } else if (type_ == kStorageTypePersistent) {
+ manager()->GetPersistentHostQuota(
+ host, base::Bind(&UsageAndQuotaHelper::SetDesiredHostQuota,
+ weak_factory_.GetWeakPtr(), barrier));
+ } else {
+ DCHECK_EQ(kStorageTypeTemporary, type_);
+ // For temporary storge, OnGotSettings will set the host quota.
+ }
}
- void set_available_disk_space(int64_t available_disk_space) {
- usage_and_quota_.available_disk_space = available_disk_space;
- has_available_disk_space_ = true;
+ void Aborted() override {
+ weak_factory_.InvalidateWeakPtrs();
+ callback_.Run(kQuotaErrorAbort, 0, 0);
+ DeleteSoon();
}
- UsageCallback GetHostUsageCallback() {
- ++waiting_callbacks_;
- has_usage_ = true;
- return base::Bind(&UsageAndQuotaCallbackDispatcher::DidGetHostUsage,
- AsWeakPtr());
+ void Completed() override {
+ weak_factory_.InvalidateWeakPtrs();
+
+ // Constrain the desired |host_quota| to something that fits.
+ // If available space is too low, cap usage at current levels.
+ // If it's close to being too low, cap growth to avoid it getting too low.
+ int64_t host_quota =
+ std::min(desired_host_quota_,
+ host_usage_ +
+ std::max(INT64_C(0), available_space_ -
+ settings_.must_remain_available));
+ callback_.Run(kQuotaStatusOk, host_usage_, host_quota);
+ if (type_ == kStorageTypeTemporary && !is_incognito_ && !is_unlimited_) {
+ UMA_HISTOGRAM_MBYTES("Quota.QuotaForOrigin", host_quota);
+ if (host_quota > 0) {
+ UMA_HISTOGRAM_PERCENTAGE("Quota.PercentUsedByOrigin",
+ std::min(100, static_cast<int>((host_usage_ * 100) / host_quota)));
+ }
+ }
+ DeleteSoon();
}
- UsageCallback GetGlobalLimitedUsageCallback() {
- ++waiting_callbacks_;
- has_global_limited_usage_ = true;
- return base::Bind(
- &UsageAndQuotaCallbackDispatcher::DidGetGlobalLimitedUsage,
- AsWeakPtr());
+ private:
+ QuotaManager* manager() const {
+ return static_cast<QuotaManager*>(observer());
}
- QuotaCallback GetQuotaCallback() {
- ++waiting_callbacks_;
- has_quota_ = true;
- return base::Bind(&UsageAndQuotaCallbackDispatcher::DidGetQuota,
- AsWeakPtr());
+ void OnGotSettings(const base::Closure& barrier_closure,
+ const QuotaSettings& settings) {
+ settings_ = settings;
+ barrier_closure.Run();
+ if (type_ == kStorageTypeTemporary && !is_unlimited_) {
+ SetDesiredHostQuota(barrier_closure, kQuotaStatusOk,
+ settings.per_host_quota);
+ }
}
- QuotaCallback GetAvailableSpaceCallback() {
- ++waiting_callbacks_;
- has_available_disk_space_ = true;
- return base::Bind(&UsageAndQuotaCallbackDispatcher::DidGetAvailableSpace,
- AsWeakPtr());
+ void OnGotCapacity(const base::Closure& barrier_closure,
+ int64_t total_space,
+ int64_t available_space) {
+ total_space_ = total_space;
+ available_space_ = available_space;
+ barrier_closure.Run();
}
- private:
- void DidGetHostUsage(int64_t usage) {
- if (status_ == kQuotaStatusUnknown)
- status_ = kQuotaStatusOk;
- usage_and_quota_.usage = usage;
- CheckCompleted();
+ void OnGotHostUsage(const base::Closure& barrier_closure, int64_t usage) {
+ host_usage_ = usage;
+ barrier_closure.Run();
}
- void DidGetGlobalLimitedUsage(int64_t limited_usage) {
- if (status_ == kQuotaStatusUnknown)
- status_ = kQuotaStatusOk;
- usage_and_quota_.global_limited_usage = limited_usage;
- CheckCompleted();
+ void SetDesiredHostQuota(const base::Closure& barrier_closure,
+ QuotaStatusCode status,
+ int64_t quota) {
+ desired_host_quota_ = quota;
+ barrier_closure.Run();
}
- void DidGetQuota(QuotaStatusCode status, int64_t quota) {
- if (status_ == kQuotaStatusUnknown || status_ == kQuotaStatusOk)
- status_ = status;
- usage_and_quota_.quota = quota;
- CheckCompleted();
- }
+ void OnBarrierComplete() { CallCompleted(); }
- void DidGetAvailableSpace(QuotaStatusCode status, int64_t space) {
- // crbug.com/349708
- TRACE_EVENT0(
- "io", "UsageAndQuotaCallbackDispatcher::DidGetAvailableSpace");
+ GURL origin_;
+ QuotaManager::UsageAndQuotaCallback callback_;
+ StorageType type_;
+ bool is_unlimited_;
+ bool is_incognito_;
+ int64_t available_space_ = 0;
+ int64_t total_space_ = 0;
+ int64_t desired_host_quota_ = 0;
+ int64_t host_usage_ = 0;
+ QuotaSettings settings_;
+ base::WeakPtrFactory<UsageAndQuotaHelper> weak_factory_;
+ DISALLOW_COPY_AND_ASSIGN(UsageAndQuotaHelper);
+};
- DCHECK_GE(space, 0);
- if (status_ == kQuotaStatusUnknown || status_ == kQuotaStatusOk)
- status_ = status;
- usage_and_quota_.available_disk_space = space;
- CheckCompleted();
- }
+// Helper to asychronously gather information needed at the start of an
+// eviction round.
+class QuotaManager::EvictionRoundInfoHelper : public QuotaTask {
+ public:
+ EvictionRoundInfoHelper(QuotaManager* manager,
+ const EvictionRoundInfoCallback& callback)
+ : QuotaTask(manager), callback_(callback), weak_factory_(this) {}
+ protected:
void Run() override {
- // We initialize waiting_callbacks to 1 so that we won't run
- // the completion callback until here even some of the callbacks
- // are dispatched synchronously.
- CheckCompleted();
+ // Gather 2 pieces of info before deciding if we need to get GlobalUsage:
+ // settings and device_storage_capacity.
+ base::Closure barrier = base::BarrierClosure(
+ 2, base::Bind(&EvictionRoundInfoHelper::OnBarrierComplete,
+ weak_factory_.GetWeakPtr()));
+
+ manager()->GetQuotaSettings(
+ base::Bind(&EvictionRoundInfoHelper::OnGotSettings,
+ weak_factory_.GetWeakPtr(), barrier));
+ manager()->GetStorageCapacity(
+ base::Bind(&EvictionRoundInfoHelper::OnGotCapacity,
+ weak_factory_.GetWeakPtr(), barrier));
}
void Aborted() override {
- callback_.Run(kQuotaErrorAbort, UsageAndQuota());
+ weak_factory_.InvalidateWeakPtrs();
+ callback_.Run(kQuotaErrorAbort, QuotaSettings(), 0, 0, 0, false);
DeleteSoon();
}
void Completed() override {
- // crbug.com/349708
- TRACE_EVENT0("io", "UsageAndQuotaCallbackDispatcher::Completed");
-
- DCHECK(!has_usage_ || usage_and_quota_.usage >= 0);
- DCHECK(!has_global_limited_usage_ ||
- usage_and_quota_.global_limited_usage >= 0);
- DCHECK(!has_quota_ || usage_and_quota_.quota >= 0);
- DCHECK(!has_available_disk_space_ ||
- usage_and_quota_.available_disk_space >= 0);
-
- callback_.Run(status_, usage_and_quota_);
+ weak_factory_.InvalidateWeakPtrs();
+ callback_.Run(kQuotaStatusOk, settings_,
+ available_space_, total_space_,
+ global_usage_, global_usage_is_complete_);
DeleteSoon();
}
- void CheckCompleted() {
- if (--waiting_callbacks_ <= 0)
- CallCompleted();
+ private:
+ QuotaManager* manager() const {
+ return static_cast<QuotaManager*>(observer());
}
- // For sanity checks, they're checked only when DCHECK is on.
- bool has_usage_;
- bool has_global_limited_usage_;
- bool has_quota_;
- bool has_available_disk_space_;
+ void OnGotSettings(const base::Closure& barrier_closure,
+ const QuotaSettings& settings) {
+ settings_ = settings;
+ barrier_closure.Run();
+ }
- QuotaStatusCode status_;
- UsageAndQuota usage_and_quota_;
- QuotaManager::UsageAndQuotaCallback callback_;
- int waiting_callbacks_;
+ void OnGotCapacity(const base::Closure& barrier_closure,
+ int64_t total_space,
+ int64_t available_space) {
+ total_space_ = total_space;
+ available_space_ = available_space;
+ barrier_closure.Run();
+ }
- DISALLOW_COPY_AND_ASSIGN(UsageAndQuotaCallbackDispatcher);
+ void OnBarrierComplete() {
+ // Avoid computing the full current_usage when there's no pressure.
+ int64_t consumed_space = total_space_ - available_space_;
+ if (consumed_space < settings_.pool_size &&
+ available_space_ > settings_.should_remain_available) {
+ DCHECK(!global_usage_is_complete_);
+ global_usage_ =
+ manager()->GetUsageTracker(kStorageTypeTemporary)->GetCachedUsage();
+ CallCompleted();
+ return;
+ }
+ manager()->GetGlobalUsage(
+ kStorageTypeTemporary,
+ base::Bind(&EvictionRoundInfoHelper::OnGotGlobalUsage,
+ weak_factory_.GetWeakPtr()));
+ }
+
+ void OnGotGlobalUsage(int64_t usage, int64_t unlimited_usage) {
+ global_usage_ = std::max(INT64_C(0), usage - unlimited_usage);
+ global_usage_is_complete_ = true;
+ if (total_space_ > 0) {
+ UMA_HISTOGRAM_PERCENTAGE("Quota.PercentUsedForTemporaryStorage",
+ std::min(100,
+ static_cast<int>((global_usage_ * 100) / total_space_)));
+ }
+ CallCompleted();
+ }
+
+ EvictionRoundInfoCallback callback_;
+ QuotaSettings settings_;
+ int64_t available_space_ = 0;
+ int64_t total_space_ = 0;
+ int64_t global_usage_ = 0;
+ bool global_usage_is_complete_ = false;
+ base::WeakPtrFactory<EvictionRoundInfoHelper> weak_factory_;
+ DISALLOW_COPY_AND_ASSIGN(EvictionRoundInfoHelper);
};
class QuotaManager::GetUsageInfoTask : public QuotaTask {
@@ -867,7 +795,8 @@ QuotaManager::QuotaManager(
const base::FilePath& profile_path,
const scoped_refptr<base::SingleThreadTaskRunner>& io_thread,
const scoped_refptr<base::SequencedTaskRunner>& db_thread,
- const scoped_refptr<SpecialStoragePolicy>& special_storage_policy)
+ const scoped_refptr<SpecialStoragePolicy>& special_storage_policy,
+ const GetQuotaSettingsFunc& get_settings_function)
: is_incognito_(is_incognito),
profile_path_(profile_path),
proxy_(new QuotaManagerProxy(this, io_thread)),
@@ -875,13 +804,25 @@ QuotaManager::QuotaManager(
eviction_disabled_(false),
io_thread_(io_thread),
db_thread_(db_thread),
+ get_settings_function_(get_settings_function),
is_getting_eviction_origin_(false),
- temporary_quota_initialized_(false),
- temporary_quota_override_(-1),
special_storage_policy_(special_storage_policy),
get_volume_info_fn_(&QuotaManager::GetVolumeInfo),
storage_monitor_(new StorageMonitor(this)),
- weak_factory_(this) {}
+ weak_factory_(this) {
+ DCHECK_EQ(settings_.refresh_interval, base::TimeDelta::Max());
+ if (!get_settings_function.is_null()) {
+ // Reset the interval to ensure we use the get_settings_function
+ // the first times settings_ is needed.
+ settings_.refresh_interval = base::TimeDelta();
+ get_settings_task_runner_ = base::ThreadTaskRunnerHandle::Get();
+ }
+}
+
+void QuotaManager::SetQuotaSettings(const QuotaSettings& settings) {
+ settings_ = settings;
+ settings_timestamp_ = base::TimeTicks::Now();
+}
void QuotaManager::GetUsageInfo(const GetUsageInfoCallback& callback) {
LazyInitialize();
@@ -892,61 +833,28 @@ void QuotaManager::GetUsageInfo(const GetUsageInfoCallback& callback) {
void QuotaManager::GetUsageAndQuotaForWebApps(
const GURL& origin,
StorageType type,
- const GetUsageAndQuotaCallback& callback) {
- // TODO(pkasting): Remove ScopedTracker below once crbug.com/477117 is fixed.
- tracked_objects::ScopedTracker tracking_profile(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "477117 QuotaManager::GetUsageAndQuotaForWebApps"));
- if (type != kStorageTypeTemporary &&
- type != kStorageTypePersistent &&
- type != kStorageTypeSyncable) {
+ const UsageAndQuotaCallback& callback) {
+ DCHECK(origin == origin.GetOrigin());
+ if (!IsSupportedType(type) ||
+ (is_incognito_ && !IsSupportedIncognitoType(type))) {
callback.Run(kQuotaErrorNotSupported, 0, 0);
return;
}
-
- DCHECK(origin == origin.GetOrigin());
LazyInitialize();
-
- bool unlimited = IsStorageUnlimited(origin, type);
- bool can_query_disk_size = CanQueryDiskSize(origin);
-
- UsageAndQuotaCallbackDispatcher* dispatcher =
- new UsageAndQuotaCallbackDispatcher(this);
-
- if (unlimited) {
- dispatcher->set_quota(kNoLimit);
- } else {
- if (type == kStorageTypeTemporary) {
- GetUsageTracker(type)->GetGlobalLimitedUsage(
- dispatcher->GetGlobalLimitedUsageCallback());
- GetTemporaryGlobalQuota(dispatcher->GetQuotaCallback());
- } else if (type == kStorageTypePersistent) {
- GetPersistentHostQuota(net::GetHostOrSpecFromURL(origin),
- dispatcher->GetQuotaCallback());
- } else {
- dispatcher->set_quota(kSyncableStorageDefaultHostQuota);
- }
- }
-
- DCHECK(GetUsageTracker(type));
- GetUsageTracker(type)->GetHostUsage(net::GetHostOrSpecFromURL(origin),
- dispatcher->GetHostUsageCallback());
-
- if (!is_incognito_ && (unlimited || can_query_disk_size))
- GetAvailableSpace(dispatcher->GetAvailableSpaceCallback());
-
- dispatcher->WaitForResults(base::Bind(
- &DispatchUsageAndQuotaForWebApps,
- type, is_incognito_, unlimited, can_query_disk_size,
- callback));
+ UsageAndQuotaHelper* helper = new UsageAndQuotaHelper(
+ this, origin, type, IsStorageUnlimited(origin, type), is_incognito_,
+ callback);
+ helper->Start();
}
-void QuotaManager::GetUsageAndQuota(
- const GURL& origin, StorageType type,
- const GetUsageAndQuotaCallback& callback) {
+void QuotaManager::GetUsageAndQuota(const GURL& origin,
+ StorageType type,
+ const UsageAndQuotaCallback& callback) {
DCHECK(origin == origin.GetOrigin());
if (IsStorageUnlimited(origin, type)) {
+ // TODO(michaeln): This seems like a non-obvious odd behavior, probably for
+ // apps/extensions, but it would be good to elimiate this special case.
callback.Run(kQuotaStatusOk, 0, kNoLimit);
return;
}
@@ -992,11 +900,6 @@ void QuotaManager::SetUsageCacheEnabled(QuotaClient::ID client_id,
GetUsageTracker(type)->SetUsageCacheEnabled(client_id, origin, enabled);
}
-void QuotaManager::SetTemporaryStorageEvictionPolicy(
- std::unique_ptr<QuotaEvictionPolicy> policy) {
- temporary_storage_eviction_policy_ = std::move(policy);
-}
-
void QuotaManager::DeleteOriginData(const GURL& origin,
StorageType type,
int quota_client_mask,
@@ -1009,7 +912,6 @@ void QuotaManager::DeleteHostData(const std::string& host,
int quota_client_mask,
const StatusCallback& callback) {
LazyInitialize();
-
if (host.empty() || clients_.empty()) {
callback.Run(kQuotaStatusOk);
return;
@@ -1020,72 +922,6 @@ void QuotaManager::DeleteHostData(const std::string& host,
deleter->Start();
}
-void QuotaManager::GetAvailableSpace(const AvailableSpaceCallback& callback) {
- if (!available_space_callbacks_.Add(callback))
- return;
- // crbug.com/349708
- TRACE_EVENT0("io", "QuotaManager::GetAvailableSpace");
-
- PostTaskAndReplyWithResult(
- db_thread_.get(),
- FROM_HERE,
- base::Bind(&QuotaManager::CallGetAmountOfFreeDiskSpace,
- get_volume_info_fn_, profile_path_),
- base::Bind(&QuotaManager::DidGetAvailableSpace,
- weak_factory_.GetWeakPtr()));
-}
-
-void QuotaManager::GetTemporaryGlobalQuota(const QuotaCallback& callback) {
- LazyInitialize();
- if (!temporary_quota_initialized_) {
- db_initialization_callbacks_.Add(base::Bind(
- &QuotaManager::GetTemporaryGlobalQuota,
- weak_factory_.GetWeakPtr(), callback));
- return;
- }
-
- if (temporary_quota_override_ > 0) {
- callback.Run(kQuotaStatusOk, temporary_quota_override_);
- return;
- }
-
- UsageAndQuotaCallbackDispatcher* dispatcher =
- new UsageAndQuotaCallbackDispatcher(this);
- GetUsageTracker(kStorageTypeTemporary)->
- GetGlobalLimitedUsage(dispatcher->GetGlobalLimitedUsageCallback());
- GetAvailableSpace(dispatcher->GetAvailableSpaceCallback());
- dispatcher->WaitForResults(
- base::Bind(&DispatchTemporaryGlobalQuotaCallback, callback));
-}
-
-void QuotaManager::SetTemporaryGlobalOverrideQuota(
- int64_t new_quota,
- const QuotaCallback& callback) {
- LazyInitialize();
-
- if (new_quota < 0) {
- if (!callback.is_null())
- callback.Run(kQuotaErrorInvalidModification, -1);
- return;
- }
-
- if (db_disabled_) {
- if (!callback.is_null())
- callback.Run(kQuotaErrorInvalidAccess, -1);
- return;
- }
-
- int64_t* new_quota_ptr = new int64_t(new_quota);
- PostTaskAndReplyWithResultForDBThread(
- FROM_HERE,
- base::Bind(&SetTemporaryGlobalOverrideQuotaOnDBThread,
- base::Unretained(new_quota_ptr)),
- base::Bind(&QuotaManager::DidSetTemporaryGlobalOverrideQuota,
- weak_factory_.GetWeakPtr(),
- callback,
- base::Owned(new_quota_ptr)));
-}
-
void QuotaManager::GetPersistentHostQuota(const std::string& host,
const QuotaCallback& callback) {
LazyInitialize();
@@ -1127,10 +963,8 @@ void QuotaManager::SetPersistentHostQuota(const std::string& host,
return;
}
- if (kPerHostPersistentQuotaLimit < new_quota) {
- // Cap the requested size at the per-host quota limit.
- new_quota = kPerHostPersistentQuotaLimit;
- }
+ // Cap the requested size at the per-host quota limit.
+ new_quota = std::min(new_quota, kPerHostPersistentQuotaLimit);
if (db_disabled_) {
callback.Run(kQuotaErrorInvalidAccess, -1);
@@ -1290,7 +1124,7 @@ QuotaManager::EvictionContext::~EvictionContext() {
void QuotaManager::LazyInitialize() {
DCHECK(io_thread_->BelongsToCurrentThread());
if (database_) {
- // Initialization seems to be done already.
+ // Already initialized.
return;
}
@@ -1308,17 +1142,45 @@ void QuotaManager::LazyInitialize() {
clients_, kStorageTypeSyncable, special_storage_policy_.get(),
storage_monitor_.get()));
- int64_t* temporary_quota_override = new int64_t(-1);
- int64_t* desired_available_space = new int64_t(-1);
+ if (!is_incognito_) {
+ histogram_timer_.Start(
+ FROM_HERE, base::TimeDelta::FromMilliseconds(kReportHistogramInterval),
+ this, &QuotaManager::ReportHistogram);
+ }
+
+ base::PostTaskAndReplyWithResult(
+ db_thread_.get(), FROM_HERE,
+ base::Bind(&QuotaDatabase::IsOriginDatabaseBootstrapped,
+ base::Unretained(database_.get())),
+ base::Bind(&QuotaManager::FinishLazyInitialize,
+ weak_factory_.GetWeakPtr()));
+}
+
+void QuotaManager::FinishLazyInitialize(bool is_database_bootstrapped) {
+ is_database_bootstrapped_ = is_database_bootstrapped;
+ StartEviction();
+}
+
+void QuotaManager::BootstrapDatabaseForEviction(
+ const GetOriginCallback& did_get_origin_callback,
+ int64_t usage,
+ int64_t unlimited_usage) {
+ // The usage cache should be fully populated now so we can
+ // seed the database with origins we know about.
+ std::set<GURL>* origins = new std::set<GURL>;
+ temporary_usage_tracker_->GetCachedOrigins(origins);
PostTaskAndReplyWithResultForDBThread(
- FROM_HERE,
- base::Bind(&InitializeOnDBThread,
- base::Unretained(temporary_quota_override),
- base::Unretained(desired_available_space)),
- base::Bind(&QuotaManager::DidInitialize,
- weak_factory_.GetWeakPtr(),
- base::Owned(temporary_quota_override),
- base::Owned(desired_available_space)));
+ FROM_HERE, base::Bind(&BootstrapDatabaseOnDBThread, base::Owned(origins)),
+ base::Bind(&QuotaManager::DidBootstrapDatabase,
+ weak_factory_.GetWeakPtr(), did_get_origin_callback));
+}
+
+void QuotaManager::DidBootstrapDatabase(
+ const GetOriginCallback& did_get_origin_callback,
+ bool success) {
+ is_database_bootstrapped_ = success;
+ DidDatabaseWork(success);
+ GetLRUOrigin(kStorageTypeTemporary, did_get_origin_callback);
}
void QuotaManager::RegisterClient(QuotaClient* client) {
@@ -1413,11 +1275,10 @@ void QuotaManager::DumpOriginInfoTable(
void QuotaManager::StartEviction() {
DCHECK(!temporary_storage_evictor_.get());
+ if (eviction_disabled_)
+ return;
temporary_storage_evictor_.reset(new QuotaTemporaryStorageEvictor(
this, kEvictionIntervalInMilliSeconds));
- if (desired_available_space_ >= 0)
- temporary_storage_evictor_->set_min_available_disk_space_to_start_eviction(
- desired_available_space_);
temporary_storage_evictor_->Start();
}
@@ -1603,26 +1464,21 @@ void QuotaManager::GetEvictionOrigin(StorageType type,
base::Bind(&QuotaManager::DidGetEvictionOrigin,
weak_factory_.GetWeakPtr(), callback);
- if (type == kStorageTypeTemporary && temporary_storage_eviction_policy_) {
- std::map<GURL, int64_t> usage_map;
- // The cached origins are populated by the prior call to
- // GetUsageAndQuotaForEviction().
- GetUsageTracker(kStorageTypeTemporary)->GetCachedOriginsUsage(&usage_map);
-
- temporary_storage_eviction_policy_->GetEvictionOrigin(
- special_storage_policy_, GetEvictionOriginExceptions(extra_exceptions),
- usage_map, global_quota, did_get_origin_callback);
-
+ if (!is_database_bootstrapped_ && !eviction_disabled_) {
+ // Once bootstrapped, GetLRUOrigin will be called.
+ GetGlobalUsage(
+ kStorageTypeTemporary,
+ base::Bind(&QuotaManager::BootstrapDatabaseForEviction,
+ weak_factory_.GetWeakPtr(), did_get_origin_callback));
return;
}
- // TODO(calamity): convert LRU origin retrieval into a QuotaEvictionPolicy.
GetLRUOrigin(type, did_get_origin_callback);
}
void QuotaManager::EvictOriginData(const GURL& origin,
StorageType type,
- const EvictOriginDataCallback& callback) {
+ const StatusCallback& callback) {
DCHECK(io_thread_->BelongsToCurrentThread());
DCHECK_EQ(type, kStorageTypeTemporary);
@@ -1635,47 +1491,12 @@ void QuotaManager::EvictOriginData(const GURL& origin,
weak_factory_.GetWeakPtr()));
}
-void QuotaManager::GetUsageAndQuotaForEviction(
- const UsageAndQuotaCallback& callback) {
- // crbug.com/349708
- TRACE_EVENT0("io", "QuotaManager::GetUsageAndQuotaForEviction");
-
+void QuotaManager::GetEvictionRoundInfo(
+ const EvictionRoundInfoCallback& callback) {
DCHECK(io_thread_->BelongsToCurrentThread());
LazyInitialize();
-
- UsageAndQuotaCallbackDispatcher* dispatcher =
- new UsageAndQuotaCallbackDispatcher(this);
- GetUsageTracker(kStorageTypeTemporary)
- ->GetGlobalLimitedUsage(dispatcher->GetGlobalLimitedUsageCallback());
- GetTemporaryGlobalQuota(dispatcher->GetQuotaCallback());
- GetAvailableSpace(dispatcher->GetAvailableSpaceCallback());
- dispatcher->WaitForResults(callback);
-}
-
-void QuotaManager::AsyncGetVolumeInfo(
- const VolumeInfoCallback& callback) {
- DCHECK(io_thread_->BelongsToCurrentThread());
- uint64_t* available_space = new uint64_t(0);
- uint64_t* total_space = new uint64_t(0);
- PostTaskAndReplyWithResult(
- db_thread_.get(),
- FROM_HERE,
- base::Bind(get_volume_info_fn_,
- profile_path_,
- base::Unretained(available_space),
- base::Unretained(total_space)),
- base::Bind(&QuotaManager::DidGetVolumeInfo,
- weak_factory_.GetWeakPtr(),
- callback,
- base::Owned(available_space),
- base::Owned(total_space)));
-}
-
-void QuotaManager::DidGetVolumeInfo(
- const VolumeInfoCallback& callback,
- uint64_t* available_space, uint64_t* total_space, bool success) {
- DCHECK(io_thread_->BelongsToCurrentThread());
- callback.Run(success, *available_space, *total_space);
+ EvictionRoundInfoHelper* helper = new EvictionRoundInfoHelper(this, callback);
+ helper->Start();
}
void QuotaManager::GetLRUOrigin(StorageType type,
@@ -1700,28 +1521,12 @@ void QuotaManager::GetLRUOrigin(StorageType type,
base::Owned(url)));
}
-void QuotaManager::DidSetTemporaryGlobalOverrideQuota(
- const QuotaCallback& callback,
- const int64_t* new_quota,
- bool success) {
- QuotaStatusCode status = kQuotaErrorInvalidAccess;
- DidDatabaseWork(success);
- if (success) {
- temporary_quota_override_ = *new_quota;
- status = kQuotaStatusOk;
- }
-
- if (callback.is_null())
- return;
-
- callback.Run(status, *new_quota);
-}
-
void QuotaManager::DidGetPersistentHostQuota(const std::string& host,
const int64_t* quota,
bool success) {
DidDatabaseWork(success);
- persistent_host_quota_callbacks_.Run(host, kQuotaStatusOk, *quota);
+ persistent_host_quota_callbacks_.Run(
+ host, kQuotaStatusOk, std::min(*quota, kPerHostPersistentQuotaLimit));
}
void QuotaManager::DidSetPersistentHostQuota(const std::string& host,
@@ -1732,27 +1537,6 @@ void QuotaManager::DidSetPersistentHostQuota(const std::string& host,
callback.Run(success ? kQuotaStatusOk : kQuotaErrorInvalidAccess, *new_quota);
}
-void QuotaManager::DidInitialize(int64_t* temporary_quota_override,
- int64_t* desired_available_space,
- bool success) {
- temporary_quota_override_ = *temporary_quota_override;
- desired_available_space_ = *desired_available_space;
- temporary_quota_initialized_ = true;
- DidDatabaseWork(success);
-
- if (!is_incognito_) {
- histogram_timer_.Start(FROM_HERE,
- base::TimeDelta::FromMilliseconds(
- kReportHistogramInterval),
- this, &QuotaManager::ReportHistogram);
- }
-
- db_initialization_callbacks_.Run();
- GetTemporaryGlobalQuota(
- base::Bind(&QuotaManager::DidGetInitialTemporaryGlobalQuota,
- weak_factory_.GetWeakPtr(), base::TimeTicks::Now()));
-}
-
void QuotaManager::DidGetLRUOrigin(const GURL* origin,
bool success) {
DidDatabaseWork(success);
@@ -1761,41 +1545,83 @@ void QuotaManager::DidGetLRUOrigin(const GURL* origin,
lru_origin_callback_.Reset();
}
-void QuotaManager::DidGetInitialTemporaryGlobalQuota(
- base::TimeTicks start_ticks,
- QuotaStatusCode status,
- int64_t quota_unused) {
- UMA_HISTOGRAM_LONG_TIMES(
- "Quota.TimeToInitializeGlobalQuota",
- base::TimeTicks::Now() - start_ticks);
+namespace {
+void DidGetSettingsThreadAdapter(base::TaskRunner* task_runner,
+ const OptionalQuotaSettingsCallback& callback,
+ base::Optional<QuotaSettings> settings) {
+ task_runner->PostTask(FROM_HERE, base::Bind(callback, std::move(settings)));
+}
+} // namespace
- if (eviction_disabled_)
+void QuotaManager::GetQuotaSettings(const QuotaSettingsCallback& callback) {
+ if (base::TimeTicks::Now() - settings_timestamp_ <
+ settings_.refresh_interval) {
+ callback.Run(settings_);
return;
+ }
- std::set<GURL>* origins = new std::set<GURL>;
- temporary_usage_tracker_->GetCachedOrigins(origins);
- // This will call the StartEviction() when initial origin registration
- // is completed.
- PostTaskAndReplyWithResultForDBThread(
+ if (!settings_callbacks_.Add(callback))
+ return;
+
+ // We invoke our clients GetQuotaSettingsFunc on the
+ // UI thread and plumb the resulting value back to this thread.
+ get_settings_task_runner_->PostTask(
FROM_HERE,
- base::Bind(&InitializeTemporaryOriginsInfoOnDBThread,
- base::Owned(origins)),
- base::Bind(&QuotaManager::DidInitializeTemporaryOriginsInfo,
+ base::Bind(
+ get_settings_function_,
+ base::Bind(
+ &DidGetSettingsThreadAdapter,
+ base::RetainedRef(base::ThreadTaskRunnerHandle::Get()),
+ base::Bind(&QuotaManager::DidGetSettings,
+ weak_factory_.GetWeakPtr(), base::TimeTicks::Now()))));
+}
+
+void QuotaManager::DidGetSettings(base::TimeTicks start_ticks,
+ base::Optional<QuotaSettings> settings) {
+ if (!settings) {
+ settings = settings_;
+ settings->refresh_interval = base::TimeDelta::FromMinutes(1);
+ }
+ SetQuotaSettings(*settings);
+ settings_callbacks_.Run(*settings);
+ UMA_HISTOGRAM_MBYTES("Quota.GlobalTemporaryPoolSize", settings->pool_size);
+ UMA_HISTOGRAM_LONG_TIMES("Quota.TimeToGetSettings",
+ base::TimeTicks::Now() - start_ticks);
+ LOG_IF(WARNING, settings->pool_size == 0)
+ << "No storage quota provided in QuotaSettings.";
+}
+
+void QuotaManager::GetStorageCapacity(const StorageCapacityCallback& callback) {
+ if (!storage_capacity_callbacks_.Add(callback))
+ return;
+ if (is_incognito_) {
+ GetQuotaSettings(
+ base::Bind(&QuotaManager::ContinueIncognitoGetStorageCapacity,
+ weak_factory_.GetWeakPtr()));
+ return;
+ }
+ base::PostTaskAndReplyWithResult(
+ db_thread_.get(), FROM_HERE,
+ base::Bind(&QuotaManager::CallGetVolumeInfo, get_volume_info_fn_,
+ profile_path_),
+ base::Bind(&QuotaManager::DidGetStorageCapacity,
weak_factory_.GetWeakPtr()));
}
-void QuotaManager::DidInitializeTemporaryOriginsInfo(bool success) {
- DidDatabaseWork(success);
- if (success)
- StartEviction();
+void QuotaManager::ContinueIncognitoGetStorageCapacity(
+ const QuotaSettings& settings) {
+ int64_t current_usage =
+ GetUsageTracker(kStorageTypeTemporary)->GetCachedUsage();
+ current_usage += GetUsageTracker(kStorageTypePersistent)->GetCachedUsage();
+ int64_t available_space =
+ std::max(INT64_C(0), settings.pool_size - current_usage);
+ DidGetStorageCapacity(std::make_tuple(settings.pool_size, available_space));
}
-void QuotaManager::DidGetAvailableSpace(int64_t space) {
- // crbug.com/349708
- TRACE_EVENT1("io", "QuotaManager::DidGetAvailableSpace",
- "n_callbacks", available_space_callbacks_.size());
-
- available_space_callbacks_.Run(kQuotaStatusOk, space);
+void QuotaManager::DidGetStorageCapacity(
+ const std::tuple<int64_t, int64_t>& total_and_available) {
+ storage_capacity_callbacks_.Run(std::get<0>(total_and_available),
+ std::get<1>(total_and_available));
}
void QuotaManager::DidDatabaseWork(bool success) {
@@ -1825,41 +1651,36 @@ void QuotaManager::PostTaskAndReplyWithResultForDBThread(
}
// static
-int64_t QuotaManager::CallGetAmountOfFreeDiskSpace(
+std::tuple<int64_t, int64_t> QuotaManager::CallGetVolumeInfo(
GetVolumeInfoFn get_volume_info_fn,
- const base::FilePath& profile_path) {
+ const base::FilePath& path) {
// crbug.com/349708
- TRACE_EVENT0("io", "CallSystemGetAmountOfFreeDiskSpace");
- if (!base::CreateDirectory(profile_path)) {
- LOG(WARNING) << "Create directory failed for path" << profile_path.value();
- return 0;
- }
- uint64_t available, total;
- if (!get_volume_info_fn(profile_path, &available, &total)) {
- return 0;
+ TRACE_EVENT0("io", "CallGetVolumeInfo");
+ if (!base::CreateDirectory(path)) {
+ LOG(WARNING) << "Create directory failed for path" << path.value();
+ return std::make_tuple<int64_t, int64_t>(0, 0);
+ }
+ int64_t total;
+ int64_t available;
+ std::tie(total, available) = get_volume_info_fn(path);
+ if (total < 0 || available < 0) {
+ LOG(WARNING) << "Unable to get volume info: " << path.value();
+ return std::make_tuple<int64_t, int64_t>(0, 0);
}
- UMA_HISTOGRAM_MBYTES("Quota.AvailableDiskSpace", available);
UMA_HISTOGRAM_MBYTES("Quota.TotalDiskSpace", total);
- return static_cast<int64_t>(available);
+ UMA_HISTOGRAM_MBYTES("Quota.AvailableDiskSpace", available);
+ if (total > 0) {
+ UMA_HISTOGRAM_PERCENTAGE("Quota.PercentDiskAvailable",
+ std::min(100, static_cast<int>((available * 100) / total)));
+ }
+ return std::make_tuple(total, available);
}
-//static
-bool QuotaManager::GetVolumeInfo(const base::FilePath& path,
- uint64_t* available_space,
- uint64_t* total_size) {
- // Inspired by similar code in the base::SysInfo class.
- base::ThreadRestrictions::AssertIOAllowed();
-
- int64_t available = base::SysInfo::AmountOfFreeDiskSpace(path);
- if (available < 0)
- return false;
- int64_t total = base::SysInfo::AmountOfTotalDiskSpace(path);
- if (total < 0)
- return false;
-
- *available_space = static_cast<uint64_t>(available);
- *total_size = static_cast<uint64_t>(total);
- return true;
+// static
+std::tuple<int64_t, int64_t> QuotaManager::GetVolumeInfo(
+ const base::FilePath& path) {
+ return std::make_tuple(base::SysInfo::AmountOfTotalDiskSpace(path),
+ base::SysInfo::AmountOfFreeDiskSpace(path));
}
} // namespace storage
« no previous file with comments | « storage/browser/quota/quota_manager.h ('k') | storage/browser/quota/quota_manager_proxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698