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

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 4 years, 2 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
Index: storage/browser/quota/quota_manager.cc
diff --git a/storage/browser/quota/quota_manager.cc b/storage/browser/quota/quota_manager.cc
index 44ba5f1019d3833427b24a81568fddd3afe5ac0b..09f7ceab913532fe5a27ec57ecd17fe93f46daea 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"
@@ -26,6 +27,7 @@
#include "base/strings/string_number_conversions.h"
#include "base/sys_info.h"
#include "base/task_runner_util.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"
@@ -47,38 +49,26 @@ 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
-// 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;
-
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;
@@ -89,11 +79,6 @@ const char QuotaManager::kEvictedOriginAccessedCountHistogram[] =
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;
-
namespace {
void CountOriginType(const std::set<GURL>& origins,
@@ -234,277 +219,230 @@ 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),
+ type_(type),
+ is_unlimited_(is_unlimited),
+ is_incognito_(is_incognito),
+ callback_(callback),
+ weak_factory_(this) {}
- void set_quota(int64_t quota) {
- usage_and_quota_.quota = quota;
- has_quota_ = true;
+ protected:
+ // Start the async process of gathering the info we need.
+ void Run() override {
+ // Gather 4 pieces of info before computing an answer:
+ // config, 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()->GetTemporaryStorageConfig(
+ base::Bind(&UsageAndQuotaHelper::OnGotConfigInfo,
+ weak_factory_.GetWeakPtr(), barrier));
+ manager()->GetDeviceStorageCapacity(
+ 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, OnGetConfig 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_ - config_.must_remain_available));
+ callback_.Run(kQuotaStatusOk, host_usage_, host_quota);
+ if (type_ == kStorageTypeTemporary && !is_incognito_ && !is_unlimited_)
+ UMA_HISTOGRAM_MBYTES("Quota.QuotaForOrigin", 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 OnGotConfigInfo(const base::Closure& barrier_closure,
+ const TemporaryStorageConfiguration& config) {
+ config_ = config;
+ barrier_closure.Run();
+ if (type_ == kStorageTypeTemporary && !is_unlimited_) {
+ SetDesiredHostQuota(barrier_closure, kQuotaStatusOk,
+ config.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;
+ TemporaryStorageConfiguration config_;
+ 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:
+ // config, device_storage_capacity.
+ base::Closure barrier = base::BarrierClosure(2,
+ base::Bind(&EvictionRoundInfoHelper::OnBarrierComplete,
+ weak_factory_.GetWeakPtr()));
+
+ manager()->GetTemporaryStorageConfig(
+ base::Bind(&EvictionRoundInfoHelper::OnGotConfigInfo,
+ weak_factory_.GetWeakPtr(), barrier));
+ manager()->GetDeviceStorageCapacity(
+ base::Bind(&EvictionRoundInfoHelper::OnGotCapacity,
+ weak_factory_.GetWeakPtr(), barrier));
}
void Aborted() override {
- callback_.Run(kQuotaErrorAbort, UsageAndQuota());
+ weak_factory_.InvalidateWeakPtrs();
+ callback_.Run(
+ kQuotaErrorAbort, TemporaryStorageConfiguration(), 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, config_, 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 OnGotConfigInfo(const base::Closure& barrier_closure,
+ const TemporaryStorageConfiguration& config) {
+ config_ = config;
+ 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 < config_.pool_size &&
+ available_space_ > config_.must_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;
+ CallCompleted();
+ }
+
+ EvictionRoundInfoCallback callback_;
+ TemporaryStorageConfiguration config_;
+ 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 {
@@ -866,21 +804,35 @@ 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 GetTemporaryStorageConfigurationFunc& get_config_function)
: is_incognito_(is_incognito),
profile_path_(profile_path),
proxy_(new QuotaManagerProxy(this, io_thread)),
db_disabled_(false),
eviction_disabled_(false),
+ get_config_function_(get_config_function),
io_thread_(io_thread),
db_thread_(db_thread),
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(storage_config_.refresh_interval, base::TimeDelta::Max());
+ if (!get_config_function.is_null()) {
+ // Reset the interval to ensure we use the get_config_function
+ // the first times storage_config_ is needed.
+ storage_config_.refresh_interval = base::TimeDelta();
+ get_config_task_runner_ = base::ThreadTaskRunnerHandle::Get();
+ }
+}
+
+void QuotaManager::SetTemporaryStorageConfiguration(
+ const TemporaryStorageConfiguration& config) {
+ storage_config_ = config;
+ storage_config_timestamp_ = base::TimeTicks::Now();
+}
void QuotaManager::GetUsageInfo(const GetUsageInfoCallback& callback) {
LazyInitialize();
@@ -891,61 +843,32 @@ 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"));
+ const UsageAndQuotaCallback& callback) {
+ DCHECK(origin == origin.GetOrigin());
if (type != kStorageTypeTemporary &&
type != kStorageTypePersistent &&
type != kStorageTypeSyncable) {
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);
- }
+ if (is_incognito_ && type != kStorageTypeTemporary) {
+ callback.Run(kQuotaErrorNotSupported, 0, 0);
+ return;
}
-
- 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));
+ LazyInitialize();
+ 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) {
+ const UsageAndQuotaCallback& callback) {
DCHECK(origin == origin.GetOrigin());
if (IsStorageUnlimited(origin, type)) {
+ // TODO: This seems like a non-obvious odd behavior.
callback.Run(kQuotaStatusOk, 0, kNoLimit);
return;
}
@@ -1019,72 +942,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();
@@ -1126,10 +983,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);
@@ -1185,7 +1040,7 @@ bool QuotaManager::IsTrackingHostUsage(StorageType type,
return tracker && tracker->GetClientTracker(client_id);
}
-void QuotaManager::GetStatistics(
+void QuotaManager::GetStatistics( // GetEvictionStatistics
std::map<std::string, std::string>* statistics) {
DCHECK(statistics);
if (temporary_storage_evictor_) {
@@ -1289,7 +1144,7 @@ QuotaManager::EvictionContext::~EvictionContext() {
void QuotaManager::LazyInitialize() {
DCHECK(io_thread_->BelongsToCurrentThread());
if (database_) {
- // Initialization seems to be done already.
+ // Already initialized.
return;
}
@@ -1307,17 +1162,24 @@ 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);
- 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)));
+ if (!is_incognito_) {
+ histogram_timer_.Start(
+ FROM_HERE,
+ base::TimeDelta::FromMilliseconds(kReportHistogramInterval),
+ this, &QuotaManager::ReportHistogram);
+ }
+
+ //// TODO???
+ //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(
+ // FROM_HERE,
+ // base::Bind(&InitializeTemporaryOriginsInfoOnDBThread,
+ // base::Owned(origins)),
+ // base::Bind(&QuotaManager::DidInitializeTemporaryOriginsInfo,
+ // weak_factory_.GetWeakPtr()));
}
void QuotaManager::RegisterClient(QuotaClient* client) {
@@ -1414,9 +1276,6 @@ void QuotaManager::StartEviction() {
DCHECK(!temporary_storage_evictor_.get());
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();
}
@@ -1621,7 +1480,7 @@ void QuotaManager::GetEvictionOrigin(StorageType type,
void QuotaManager::EvictOriginData(const GURL& origin,
StorageType type,
- const EvictOriginDataCallback& callback) {
+ const StatusCallback& callback) {
DCHECK(io_thread_->BelongsToCurrentThread());
DCHECK_EQ(type, kStorageTypeTemporary);
@@ -1634,47 +1493,13 @@ 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,
@@ -1699,28 +1524,13 @@ 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,
@@ -1731,27 +1541,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);
@@ -1760,41 +1549,88 @@ 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);
+void QuotaManager::DidInitializeTemporaryOriginsInfo(bool success) {
+ DidDatabaseWork(success);
+ if (success)
+ StartEviction();
+}
- if (eviction_disabled_)
+namespace {
+void DidGetTempStorageConfigThreadAdapter(
+ base::TaskRunner* task_runner,
+ const TemporaryStorageConfigurationCallback& callback,
+ const TemporaryStorageConfiguration& storage_config) {
+ task_runner->PostTask(FROM_HERE, base::Bind(callback, storage_config));
+}
+} // namespace
+
+void QuotaManager::GetTemporaryStorageConfig(
+ const TemporaryStorageConfigurationCallback& callback) {
+ if (base::TimeTicks::Now() - storage_config_timestamp_ <
+ storage_config_.refresh_interval) {
+ callback.Run(storage_config_);
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 (!storage_config_callbacks_.Add(callback))
+ return;
+
+ // We invoke our clients GetTemporaryPoolConfigurationFunc on the
+ // UI thread and plumb the resulting value back to this thread.
+ get_config_task_runner_->PostTask(
FROM_HERE,
- base::Bind(&InitializeTemporaryOriginsInfoOnDBThread,
- base::Owned(origins)),
- base::Bind(&QuotaManager::DidInitializeTemporaryOriginsInfo,
- weak_factory_.GetWeakPtr()));
+ base::Bind(
+ get_config_function_,
+ profile_path_, is_incognito_,
+ base::Bind(
+ &DidGetTempStorageConfigThreadAdapter,
+ base::RetainedRef(base::ThreadTaskRunnerHandle::Get()),
+ base::Bind(
+ &QuotaManager::DidGetTemporaryStorageConfig,
+ weak_factory_.GetWeakPtr()))));
+}
+
+void QuotaManager::DidGetTemporaryStorageConfig(
+ const TemporaryStorageConfiguration& config) {
+ SetTemporaryStorageConfiguration(config);
+ storage_config_callbacks_.Run(config);
+}
+
+void QuotaManager::GetDeviceStorageCapacity(
+ const StorageCapacityCallback& callback) {
+ if (!storage_capacity_callbacks_.Add(callback))
+ return;
+ if (is_incognito_) {
+ GetTemporaryStorageConfig(
+ 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::DidGetDeviceStorageCapacity,
+ weak_factory_.GetWeakPtr()));
}
-void QuotaManager::DidInitializeTemporaryOriginsInfo(bool success) {
- DidDatabaseWork(success);
- if (success)
- StartEviction();
+void QuotaManager::ContinueIncognitoGetStorageCapacity(
+ const TemporaryStorageConfiguration& config) {
+ int64_t current_usage =
+ GetUsageTracker(kStorageTypeTemporary)->GetCachedUsage();
+ int64_t available_space = std::max(
+ INT64_C(0), config.pool_size - current_usage);
+ DidGetDeviceStorageCapacity(
+ std::make_pair(config.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::DidGetDeviceStorageCapacity(
+ const std::pair<int64_t, int64_t>& total_and_available) {
+ storage_capacity_callbacks_.Run(
+ total_and_available.first, total_and_available.second);
}
void QuotaManager::DidDatabaseWork(bool success) {
@@ -1824,41 +1660,29 @@ void QuotaManager::PostTaskAndReplyWithResultForDBThread(
}
// static
-int64_t QuotaManager::CallGetAmountOfFreeDiskSpace(
+std::pair<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_pair<int64_t, int64_t>(0, 0);
}
- UMA_HISTOGRAM_MBYTES("Quota.AvailableDiskSpace", available);
- UMA_HISTOGRAM_MBYTES("Quota.TotalDiskSpace", total);
- return static_cast<int64_t>(available);
+ std::pair<int64_t, int64_t> total_and_available = get_volume_info_fn(path);
+ UMA_HISTOGRAM_MBYTES("Quota.TotalDiskSpace", total_and_available.first);
+ UMA_HISTOGRAM_MBYTES("Quota.AvailableDiskSpace", total_and_available.second);
+ return total_and_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::pair<int64_t,int64_t>
+QuotaManager::GetVolumeInfo(const base::FilePath& path) {
+ return std::make_pair(
+ base::SysInfo::AmountOfTotalDiskSpace(path),
+ base::SysInfo::AmountOfFreeDiskSpace(path));
}
} // namespace storage
+

Powered by Google App Engine
This is Rietveld 408576698