summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/browser/file_system/file_system_browsertest.cc15
-rw-r--r--content/browser/in_process_webkit/indexed_db_browsertest.cc14
-rw-r--r--webkit/quota/quota_database.cc28
-rw-r--r--webkit/quota/quota_database.h8
-rw-r--r--webkit/quota/quota_database_unittest.cc44
-rw-r--r--webkit/quota/quota_manager.cc623
-rw-r--r--webkit/quota/quota_manager.h91
-rw-r--r--webkit/quota/quota_manager_unittest.cc55
-rw-r--r--webkit/quota/quota_temporary_storage_evictor.cc36
-rw-r--r--webkit/quota/quota_temporary_storage_evictor.h11
-rw-r--r--webkit/quota/quota_temporary_storage_evictor_unittest.cc12
-rw-r--r--webkit/tools/test_shell/test_shell.gypi6
12 files changed, 462 insertions, 481 deletions
diff --git a/content/browser/file_system/file_system_browsertest.cc b/content/browser/file_system/file_system_browsertest.cc
index 52a28b4..06715014 100644
--- a/content/browser/file_system/file_system_browsertest.cc
+++ b/content/browser/file_system/file_system_browsertest.cc
@@ -63,19 +63,6 @@ class FileSystemBrowserTestWithLowQuota : public FileSystemBrowserTest {
kTemporaryStorageQuotaMaxSize, browser()->profile()->GetQuotaManager());
}
- class SetTempQuotaCallback : public quota::QuotaCallback {
- public:
- void Run(quota::QuotaStatusCode, quota::StorageType, int64) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- }
-
- void RunWithParams(const Tuple3<quota::QuotaStatusCode,
- quota::StorageType,
- int64>& params) {
- Run(params.a, params.b, params.c);
- }
- };
-
static void SetTempQuota(int64 bytes, scoped_refptr<QuotaManager> qm) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
@@ -84,7 +71,7 @@ class FileSystemBrowserTestWithLowQuota : public FileSystemBrowserTest {
return;
}
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- qm->SetTemporaryGlobalQuota(bytes, new SetTempQuotaCallback);
+ qm->SetTemporaryGlobalOverrideQuota(bytes, NULL);
// Don't return until the quota has been set.
scoped_refptr<base::ThreadTestHelper> helper(
new base::ThreadTestHelper(
diff --git a/content/browser/in_process_webkit/indexed_db_browsertest.cc b/content/browser/in_process_webkit/indexed_db_browsertest.cc
index 636973a..62b0a28 100644
--- a/content/browser/in_process_webkit/indexed_db_browsertest.cc
+++ b/content/browser/in_process_webkit/indexed_db_browsertest.cc
@@ -225,18 +225,6 @@ class IndexedDBBrowserTestWithLowQuota : public IndexedDBBrowserTest {
kTemporaryStorageQuotaMaxSize, browser()->profile()->GetQuotaManager());
}
- class SetTempQuotaCallback : public quota::QuotaCallback {
- public:
- void Run(quota::QuotaStatusCode, quota::StorageType, int64) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- }
-
- void RunWithParams(const Tuple3<quota::QuotaStatusCode,
- quota::StorageType, int64>& params) {
- Run(params.a, params.b, params.c);
- }
- };
-
static void SetTempQuota(int64 bytes, scoped_refptr<QuotaManager> qm) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
@@ -245,7 +233,7 @@ class IndexedDBBrowserTestWithLowQuota : public IndexedDBBrowserTest {
return;
}
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- qm->SetTemporaryGlobalQuota(bytes, new SetTempQuotaCallback);
+ qm->SetTemporaryGlobalOverrideQuota(bytes, NULL);
// Don't return until the quota has been set.
scoped_refptr<base::ThreadTestHelper> helper(
new base::ThreadTestHelper(
diff --git a/webkit/quota/quota_database.cc b/webkit/quota/quota_database.cc
index d34451e..0563535 100644
--- a/webkit/quota/quota_database.cc
+++ b/webkit/quota/quota_database.cc
@@ -23,12 +23,11 @@ namespace {
// Definitions for database schema.
-const int kCurrentVersion = 3;
+const int kCurrentVersion = 4;
const int kCompatibleVersion = 2;
const char kHostQuotaTable[] = "HostQuotaTable";
const char kOriginInfoTable[] = "OriginInfoTable";
-const char kGlobalQuotaKeyPrefix[] = "GlobalQuota-";
const char kIsOriginTableBootstrapped[] = "IsOriginTableBootstrapped";
class HistogramUniquifier {
@@ -48,13 +47,10 @@ bool PrepareCachedStatement(
return true;
}
-std::string GetGlobalQuotaKey(quota::StorageType type) {
- if (type == quota::kStorageTypeTemporary)
- return std::string(kGlobalQuotaKeyPrefix) + "temporary";
- else if (type == quota::kStorageTypePersistent)
- return std::string(kGlobalQuotaKeyPrefix) + "persistent";
- NOTREACHED() << "Unknown storage type " << type;
- return std::string();
+bool VerifyValidQuotaConfig(const char* key) {
+ return (key != NULL &&
+ (!strcmp(key, QuotaDatabase::kDesiredAvailableSpaceKey) ||
+ !strcmp(key, QuotaDatabase::kTemporaryQuotaOverrideKey)));
}
const int kCommitIntervalMs = 30000;
@@ -62,6 +58,10 @@ const int kCommitIntervalMs = 30000;
} // anonymous namespace
// static
+const char QuotaDatabase::kDesiredAvailableSpaceKey[] = "DesiredAvailableSpace";
+const char QuotaDatabase::kTemporaryQuotaOverrideKey[] =
+ "TemporaryQuotaOverride";
+
const QuotaDatabase::TableSchema QuotaDatabase::kTables[] = {
{ kHostQuotaTable,
"(host TEXT NOT NULL,"
@@ -334,16 +334,18 @@ bool QuotaDatabase::DeleteOriginInfo(
return true;
}
-bool QuotaDatabase::GetGlobalQuota(StorageType type, int64* quota) {
+bool QuotaDatabase::GetQuotaConfigValue(const char* key, int64* value) {
if (!LazyOpen(false))
return false;
- return meta_table_->GetValue(GetGlobalQuotaKey(type).c_str(), quota);
+ DCHECK(VerifyValidQuotaConfig(key));
+ return meta_table_->GetValue(key, value);
}
-bool QuotaDatabase::SetGlobalQuota(StorageType type, int64 quota) {
+bool QuotaDatabase::SetQuotaConfigValue(const char* key, int64 value) {
if (!LazyOpen(true))
return false;
- return meta_table_->SetValue(GetGlobalQuotaKey(type).c_str(), quota);
+ DCHECK(VerifyValidQuotaConfig(key));
+ return meta_table_->SetValue(key, value);
}
bool QuotaDatabase::GetLRUOrigin(
diff --git a/webkit/quota/quota_database.h b/webkit/quota/quota_database.h
index ec437f1..7a816f6 100644
--- a/webkit/quota/quota_database.h
+++ b/webkit/quota/quota_database.h
@@ -33,6 +33,10 @@ class SpecialStoragePolicy;
// All the methods of this class must run on the DB thread.
class QuotaDatabase {
public:
+ // Constants for {Get,Set}QuotaConfigValue keys.
+ static const char kDesiredAvailableSpaceKey[];
+ static const char kTemporaryQuotaOverrideKey[];
+
// If 'path' is empty, an in memory database will be used.
explicit QuotaDatabase(const FilePath& path);
~QuotaDatabase();
@@ -59,8 +63,8 @@ class QuotaDatabase {
bool DeleteOriginInfo(const GURL& origin, StorageType type);
- bool GetGlobalQuota(StorageType type, int64* quota);
- bool SetGlobalQuota(StorageType type, int64 quota);
+ bool GetQuotaConfigValue(const char* key, int64* value);
+ bool SetQuotaConfigValue(const char* key, int64 value);
// Sets |origin| to the least recently used origin of origins not included
// in |exceptions| and not granted the special unlimited storage right.
diff --git a/webkit/quota/quota_database_unittest.cc b/webkit/quota/quota_database_unittest.cc
index 05001a7..7045f7f 100644
--- a/webkit/quota/quota_database_unittest.cc
+++ b/webkit/quota/quota_database_unittest.cc
@@ -106,26 +106,30 @@ class QuotaDatabaseTest : public testing::Test {
QuotaDatabase db(kDbFile);
ASSERT_TRUE(db.LazyOpen(true));
- const int kQuota1 = 9999;
- const int kQuota2 = 86420;
-
- int64 quota = -1;
- EXPECT_FALSE(db.GetGlobalQuota(kStorageTypeTemporary, &quota));
- EXPECT_FALSE(db.GetGlobalQuota(kStorageTypePersistent, &quota));
-
- EXPECT_TRUE(db.SetGlobalQuota(kStorageTypeTemporary, kQuota1));
- EXPECT_TRUE(db.GetGlobalQuota(kStorageTypeTemporary, &quota));
- EXPECT_EQ(kQuota1, quota);
-
- EXPECT_TRUE(db.SetGlobalQuota(kStorageTypeTemporary, kQuota1 + 1024));
- EXPECT_TRUE(db.GetGlobalQuota(kStorageTypeTemporary, &quota));
- EXPECT_EQ(kQuota1 + 1024, quota);
-
- EXPECT_FALSE(db.GetGlobalQuota(kStorageTypePersistent, &quota));
-
- EXPECT_TRUE(db.SetGlobalQuota(kStorageTypePersistent, kQuota2));
- EXPECT_TRUE(db.GetGlobalQuota(kStorageTypePersistent, &quota));
- EXPECT_EQ(kQuota2, quota);
+ const char* kTempQuotaKey = QuotaDatabase::kTemporaryQuotaOverrideKey;
+ const char* kAvailSpaceKey = QuotaDatabase::kDesiredAvailableSpaceKey;
+
+ int64 value = 0;
+ const int64 kValue1 = 456;
+ const int64 kValue2 = 123000;
+ EXPECT_FALSE(db.GetQuotaConfigValue(kTempQuotaKey, &value));
+ EXPECT_FALSE(db.GetQuotaConfigValue(kAvailSpaceKey, &value));
+
+ EXPECT_TRUE(db.SetQuotaConfigValue(kTempQuotaKey, kValue1));
+ EXPECT_TRUE(db.GetQuotaConfigValue(kTempQuotaKey, &value));
+ EXPECT_EQ(kValue1, value);
+
+ EXPECT_TRUE(db.SetQuotaConfigValue(kTempQuotaKey, kValue2));
+ EXPECT_TRUE(db.GetQuotaConfigValue(kTempQuotaKey, &value));
+ EXPECT_EQ(kValue2, value);
+
+ EXPECT_TRUE(db.SetQuotaConfigValue(kAvailSpaceKey, kValue1));
+ EXPECT_TRUE(db.GetQuotaConfigValue(kAvailSpaceKey, &value));
+ EXPECT_EQ(kValue1, value);
+
+ EXPECT_TRUE(db.SetQuotaConfigValue(kAvailSpaceKey, kValue2));
+ EXPECT_TRUE(db.GetQuotaConfigValue(kAvailSpaceKey, &value));
+ EXPECT_EQ(kValue2, value);
}
void OriginLastAccessTimeLRU(const FilePath& kDbFile) {
diff --git a/webkit/quota/quota_manager.cc b/webkit/quota/quota_manager.cc
index 4ade94f..ad71c02 100644
--- a/webkit/quota/quota_manager.cc
+++ b/webkit/quota/quota_manager.cc
@@ -36,38 +36,12 @@ namespace quota {
namespace {
-const char kEnableQuotaEviction[] = "enable-quota-eviction";
const int64 kMBytes = 1024 * 1024;
const int kMinutesInMilliSeconds = 60 * 1000;
-// Returns the initial size of the temporary storage quota.
-// (This just gives a default initial size; once its initial size is determined
-// it won't automatically be adjusted.)
-int64 GetInitialTemporaryStorageQuotaSize(const FilePath& path,
- bool is_incognito) {
- int64 free_space = base::SysInfo::AmountOfFreeDiskSpace(path);
- UMA_HISTOGRAM_MBYTES("Quota.FreeDiskSpaceForProfile", free_space);
-
- // Returns 0 (disables the temporary storage) if the available space is
- // less than the twice of the default quota size.
- if (free_space < QuotaManager::kTemporaryStorageQuotaDefaultSize * 2)
- return 0;
-
- if (is_incognito)
- return QuotaManager::kIncognitoDefaultTemporaryQuota;
-
- // Returns the default quota size while it is more than 5% of the
- // available space.
- if (free_space < QuotaManager::kTemporaryStorageQuotaDefaultSize * 20)
- return QuotaManager::kTemporaryStorageQuotaDefaultSize;
-
- // Returns the 5% of the available space while it does not exceed the
- // maximum quota size (1GB).
- if (free_space < QuotaManager::kTemporaryStorageQuotaMaxSize * 20)
- return free_space / 20;
-
- return QuotaManager::kTemporaryStorageQuotaMaxSize;
-}
+const int64 kIncognitoDefaultTemporaryQuota = 50 * kMBytes;
+const int64 kReportHistogramInterval = 60 * 60 * 1000; // 1 hour
+const double kTemporaryQuotaRatioToAvail = 0.5; // 50%
void CountOriginType(const std::set<GURL>& origins,
SpecialStoragePolicy* policy,
@@ -91,12 +65,6 @@ void CountOriginType(const std::set<GURL>& origins,
} // anonymous namespace
-// TODO(kinuko): We will need to have different sizes for different platforms
-// (e.g. larger for desktop etc) and may want to have them in preferences.
-const int64 QuotaManager::kTemporaryStorageQuotaDefaultSize = 50 * kMBytes;
-const int64 QuotaManager::kTemporaryStorageQuotaMaxSize = 1 * 1024 * kMBytes;
-const int64 QuotaManager::kIncognitoDefaultTemporaryQuota = 50 * kMBytes;
-
const int QuotaManager::kPerHostTemporaryPortion = 5; // 20%
const char QuotaManager::kDatabaseName[] = "QuotaManager";
@@ -106,94 +74,114 @@ const int QuotaManager::kThresholdOfErrorsToBeBlacklisted = 3;
const int QuotaManager::kEvictionIntervalInMilliSeconds =
30 * kMinutesInMilliSeconds;
-const base::TimeDelta QuotaManager::kReportHistogramInterval =
- base::TimeDelta::FromMilliseconds(60 * 60 * 1000); // 1 hour
+// Callback translators.
+void CallGetUsageAndQuotaCallback(
+ QuotaManager::GetUsageAndQuotaCallback* callback,
+ bool unlimited,
+ QuotaStatusCode status,
+ const QuotaAndUsage& quota_and_usage) {
+ int64 usage =
+ unlimited ? quota_and_usage.unlimited_usage : quota_and_usage.usage;
+ int64 quota = unlimited ? kint64max : quota_and_usage.quota;
+ callback->Run(status, usage, quota);
+ delete callback;
+}
+
+void CallQuotaCallback(
+ QuotaCallback* callback,
+ StorageType type,
+ QuotaStatusCode status,
+ const QuotaAndUsage& quota_and_usage) {
+ callback->Run(status, type, quota_and_usage.quota);
+ delete callback;
+}
// This class is for posting GetUsage/GetQuota tasks, gathering
// results and dispatching GetAndQuota callbacks.
// This class is self-destructed.
class QuotaManager::UsageAndQuotaDispatcherTask : public QuotaTask {
public:
- typedef std::deque<GetUsageAndQuotaCallback*> CallbackList;
+ typedef UsageAndQuotaDispatcherCallback Callback;
+ typedef std::deque<Callback> CallbackList;
static UsageAndQuotaDispatcherTask* Create(
- QuotaManager* manager, const std::string& host, StorageType type);
+ QuotaManager* manager,
+ bool global,
+ const HostAndType& host_and_type);
// Returns true if it is the first call for this task; which means
// the caller needs to call Start().
- bool AddCallback(GetUsageAndQuotaCallback* callback, bool unlimited) {
- if (unlimited)
- unlimited_callbacks_.push_back(callback);
- else
- callbacks_.push_back(callback);
- return (callbacks_.size() + unlimited_callbacks_.size() == 1);
+ bool AddCallback(const Callback& callback) {
+ callbacks_.push_back(callback);
+ return (callbacks_.size() == 1);
}
- void DidGetGlobalUsage(StorageType type, int64 usage,
- int64 unlimited_usage) {
- DCHECK_EQ(type_, type);
+ void DidGetGlobalUsage(StorageType type, int64 usage, int64 unlimited_usage) {
+ DCHECK_EQ(this->type(), type);
DCHECK_GE(usage, unlimited_usage);
+ if (quota_status_ == kQuotaStatusUnknown)
+ quota_status_ = kQuotaStatusOk;
global_usage_ = usage;
global_unlimited_usage_ = unlimited_usage;
CheckCompleted();
}
- void DidGetHostUsage(const std::string& host,
- StorageType type,
- int64 usage) {
- DCHECK_EQ(host_, host);
- DCHECK_EQ(type_, type);
+ void DidGetHostUsage(const std::string& host, StorageType type, int64 usage) {
+ DCHECK_EQ(this->host(), host);
+ DCHECK_EQ(this->type(), type);
host_usage_ = usage;
CheckCompleted();
}
- void DidGetGlobalQuota(QuotaStatusCode status,
- StorageType type,
- int64 quota) {
- DCHECK_EQ(type_, type);
- quota_status_ = status;
- quota_ = quota;
- CheckCompleted();
- }
-
void DidGetHostQuota(QuotaStatusCode status,
const std::string& host,
StorageType type,
- int64 quota) {
- DCHECK_EQ(host_, host);
- DCHECK_EQ(type_, type);
- quota_status_ = status;
- quota_ = quota;
+ int64 host_quota) {
+ DCHECK_EQ(this->host(), host);
+ DCHECK_EQ(this->type(), type);
+ if (quota_status_ == kQuotaStatusUnknown || quota_status_ == kQuotaStatusOk)
+ quota_status_ = status;
+ host_quota_ = host_quota;
CheckCompleted();
}
+ void DidGetAvailableSpace(QuotaStatusCode status, int64 space) {
+ DCHECK_GE(space, 0);
+ if (quota_status_ == kQuotaStatusUnknown || quota_status_ == kQuotaStatusOk)
+ quota_status_ = status;
+ available_space_ = space;
+ CheckCompleted();
+ }
+
+ bool IsStartable() const {
+ return !started_ && !callbacks_.empty();
+ }
+
protected:
UsageAndQuotaDispatcherTask(
QuotaManager* manager,
- const std::string& host,
- StorageType type)
+ const HostAndType& host_and_type)
: QuotaTask(manager),
- host_(host),
- type_(type),
- quota_(-1),
+ host_and_type_(host_and_type),
+ started_(false),
+ host_quota_(-1),
global_usage_(-1),
global_unlimited_usage_(-1),
host_usage_(-1),
+ available_space_(-1),
quota_status_(kQuotaStatusUnknown),
waiting_callbacks_(1),
callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {}
- virtual ~UsageAndQuotaDispatcherTask() {
- STLDeleteContainerPointers(callbacks_.begin(), callbacks_.end());
- STLDeleteContainerPointers(unlimited_callbacks_.begin(),
- unlimited_callbacks_.end());
- }
+ virtual ~UsageAndQuotaDispatcherTask() {}
// Subclasses must implement them.
virtual void RunBody() = 0;
virtual void DispatchCallbacks() = 0;
virtual void Run() OVERRIDE {
+ DCHECK(!started_);
+ started_ = true;
RunBody();
// We initialize waiting_callbacks to 1 so that we won't run
// the completion callback until here even some of the callbacks
@@ -202,8 +190,7 @@ class QuotaManager::UsageAndQuotaDispatcherTask : public QuotaTask {
}
virtual void Aborted() OVERRIDE {
- CallCallbacksAndClear(&callbacks_, kQuotaErrorAbort, 0, 0);
- CallCallbacksAndClear(&unlimited_callbacks_, kQuotaErrorAbort, 0, 0);
+ CallCallbacksAndClear(kQuotaErrorAbort, 0, 0, 0, 0);
DeleteSoon();
}
@@ -212,29 +199,50 @@ class QuotaManager::UsageAndQuotaDispatcherTask : public QuotaTask {
}
void CallCallbacksAndClear(
- CallbackList* callbacks, QuotaStatusCode status,
- int64 usage, int64 quota) {
- for (CallbackList::iterator iter = callbacks->begin();
- iter != callbacks->end(); ++iter) {
- (*iter)->Run(status, usage, quota);
- delete *iter;
+ QuotaStatusCode status,
+ int64 usage, int64 unlimited_usage, int64 quota,
+ int64 available_space) {
+ QuotaAndUsage qau = { usage, unlimited_usage, quota, available_space };
+ for (CallbackList::iterator iter = callbacks_.begin();
+ iter != callbacks_.end(); ++iter) {
+ (*iter).Run(status, qau);
}
- callbacks->clear();
+ callbacks_.clear();
}
QuotaManager* manager() const {
return static_cast<QuotaManager*>(observer());
}
- std::string host() const { return host_; }
- StorageType type() const { return type_; }
- int64 quota() const { return quota_; }
+ std::string host() const { return host_and_type_.first; }
+ virtual StorageType type() const { return host_and_type_.second; }
+ int64 host_quota() const { return host_quota_; }
int64 global_usage() const { return global_usage_; }
int64 global_unlimited_usage() const { return global_unlimited_usage_; }
int64 host_usage() const { return host_usage_; }
+ int64 available_space() const { return available_space_; }
QuotaStatusCode quota_status() const { return quota_status_; }
CallbackList& callbacks() { return callbacks_; }
- CallbackList& unlimited_callbacks() { return unlimited_callbacks_; }
+
+ // The main logic that determines the temporary global quota.
+ int64 temporary_global_quota() const {
+ DCHECK_EQ(type(), kStorageTypeTemporary);
+ DCHECK(manager());
+ DCHECK_GE(global_usage(), global_unlimited_usage());
+ if (manager()->temporary_quota_override_ > 0) {
+ // If the user has specified an explicit temporary quota, use the value.
+ return manager()->temporary_quota_override_;
+ }
+ int64 limited_usage = global_usage() - global_unlimited_usage();
+ int64 avail_space = available_space();
+ if (avail_space < kint64max - 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 += limited_usage;
+ }
+ return avail_space * kTemporaryQuotaRatioToAvail;
+ }
// Subclasses must call following methods to create a new 'waitable'
// callback, which decrements waiting_callbacks when it is called.
@@ -248,15 +256,15 @@ class QuotaManager::UsageAndQuotaDispatcherTask : public QuotaTask {
return callback_factory_.NewCallback(
&UsageAndQuotaDispatcherTask::DidGetHostUsage);
}
- QuotaCallback* NewWaitableGlobalQuotaCallback() {
+ HostQuotaCallback* NewWaitableHostQuotaCallback() {
++waiting_callbacks_;
return callback_factory_.NewCallback(
- &UsageAndQuotaDispatcherTask::DidGetGlobalQuota);
+ &UsageAndQuotaDispatcherTask::DidGetHostQuota);
}
- HostQuotaCallback* NewWaitableHostQuotaCallback() {
+ AvailableSpaceCallback* NewWaitableAvailableSpaceCallback() {
++waiting_callbacks_;
return callback_factory_.NewCallback(
- &UsageAndQuotaDispatcherTask::DidGetHostQuota);
+ &UsageAndQuotaDispatcherTask::DidGetAvailableSpace);
}
private:
@@ -264,26 +272,25 @@ class QuotaManager::UsageAndQuotaDispatcherTask : public QuotaTask {
if (--waiting_callbacks_ <= 0) {
DispatchCallbacks();
DCHECK(callbacks_.empty());
- DCHECK(unlimited_callbacks_.empty());
UsageAndQuotaDispatcherTaskMap& dispatcher_map =
manager()->usage_and_quota_dispatchers_;
- DCHECK(dispatcher_map.find(std::make_pair(host_, type_)) !=
- dispatcher_map.end());
- dispatcher_map.erase(std::make_pair(host_, type_));
+ DCHECK(dispatcher_map.find(host_and_type_) != dispatcher_map.end());
+ dispatcher_map.erase(host_and_type_);
CallCompleted();
}
}
const std::string host_;
- const StorageType type_;
- int64 quota_;
+ const HostAndType host_and_type_;
+ bool started_;
+ int64 host_quota_;
int64 global_usage_;
int64 global_unlimited_usage_;
int64 host_usage_;
+ int64 available_space_;
QuotaStatusCode quota_status_;
CallbackList callbacks_;
- CallbackList unlimited_callbacks_;
int waiting_callbacks_;
ScopedCallbackFactory<UsageAndQuotaDispatcherTask> callback_factory_;
@@ -355,8 +362,8 @@ class QuotaManager::UsageAndQuotaDispatcherTaskForTemporary
: public QuotaManager::UsageAndQuotaDispatcherTask {
public:
UsageAndQuotaDispatcherTaskForTemporary(
- QuotaManager* manager, const std::string& host)
- : UsageAndQuotaDispatcherTask(manager, host, kStorageTypeTemporary) {}
+ QuotaManager* manager, const HostAndType& host_and_type)
+ : UsageAndQuotaDispatcherTask(manager, host_and_type) {}
protected:
virtual void RunBody() OVERRIDE {
@@ -364,34 +371,24 @@ class QuotaManager::UsageAndQuotaDispatcherTaskForTemporary
NewWaitableGlobalUsageCallback());
manager()->temporary_usage_tracker_->GetHostUsage(
host(), NewWaitableHostUsageCallback());
- manager()->GetTemporaryGlobalQuota(NewWaitableGlobalQuotaCallback());
+ manager()->GetAvailableSpace(NewWaitableAvailableSpaceCallback());
}
virtual void DispatchCallbacks() OVERRIDE {
- // Due to a mismatch of models between same-origin (required by stds) vs
- // per-host (as this info is viewed in the UI) vs the extension systems
- // notion of webextents (the basis of granting unlimited rights),
- // we can end up with both 'unlimited' and 'limited' callbacks to invoke.
- // Should be rare, but it can happen.
-
- CallCallbacksAndClear(&unlimited_callbacks(), quota_status(),
- host_usage(), kint64max);
-
- if (!callbacks().empty()) {
- // Allow an individual host to utilize a fraction of the total
- // pool available for temp storage.
- int64 host_quota = quota() / kPerHostTemporaryPortion;
-
- // But if total temp usage is over-budget, stop letting new data in
- // until we reclaim space.
- DCHECK_GE(global_usage(), global_unlimited_usage());
- int64 limited_global_usage = global_usage() - global_unlimited_usage();
- if (limited_global_usage > quota())
- host_quota = std::min(host_quota, host_usage());
-
- CallCallbacksAndClear(&callbacks(), quota_status(),
- host_usage(), host_quota);
- }
+ // Allow an individual host to utilize a fraction of the total
+ // pool available for temp storage.
+ int64 host_quota = temporary_global_quota() / kPerHostTemporaryPortion;
+
+ // But if total temp usage is over-budget, stop letting new data in
+ // until we reclaim space.
+ DCHECK_GE(global_usage(), global_unlimited_usage());
+ int64 limited_global_usage = global_usage() - global_unlimited_usage();
+ if (limited_global_usage > temporary_global_quota())
+ host_quota = std::min(host_quota, host_usage());
+
+ CallCallbacksAndClear(quota_status(),
+ host_usage(), host_usage(), host_quota,
+ available_space());
}
};
@@ -399,8 +396,8 @@ class QuotaManager::UsageAndQuotaDispatcherTaskForPersistent
: public QuotaManager::UsageAndQuotaDispatcherTask {
public:
UsageAndQuotaDispatcherTaskForPersistent(
- QuotaManager* manager, const std::string& host)
- : UsageAndQuotaDispatcherTask(manager, host, kStorageTypePersistent) {}
+ QuotaManager* manager, const HostAndType& host_and_type)
+ : UsageAndQuotaDispatcherTask(manager, host_and_type) {}
protected:
virtual void RunBody() OVERRIDE {
@@ -411,24 +408,51 @@ class QuotaManager::UsageAndQuotaDispatcherTaskForPersistent
}
virtual void DispatchCallbacks() OVERRIDE {
- CallCallbacksAndClear(&callbacks(), quota_status(),
- host_usage(), quota());
- CallCallbacksAndClear(&unlimited_callbacks(), quota_status(),
- host_usage(), kint64max);
+ CallCallbacksAndClear(quota_status(),
+ host_usage(), host_usage(), host_quota(),
+ available_space());
}
};
+class QuotaManager::UsageAndQuotaDispatcherTaskForTemporaryGlobal
+ : public QuotaManager::UsageAndQuotaDispatcherTask {
+ public:
+ UsageAndQuotaDispatcherTaskForTemporaryGlobal(
+ QuotaManager* manager, const HostAndType& host_and_type)
+ : UsageAndQuotaDispatcherTask(manager, host_and_type) {}
+
+ protected:
+ virtual void RunBody() OVERRIDE {
+ manager()->temporary_usage_tracker_->GetGlobalUsage(
+ NewWaitableGlobalUsageCallback());
+ manager()->GetAvailableSpace(NewWaitableAvailableSpaceCallback());
+ }
+
+ virtual void DispatchCallbacks() OVERRIDE {
+ CallCallbacksAndClear(quota_status(),
+ global_usage(), global_unlimited_usage(),
+ temporary_global_quota(),
+ available_space());
+ }
+
+ virtual StorageType type() const { return kStorageTypeTemporary; }
+};
+
// static
QuotaManager::UsageAndQuotaDispatcherTask*
QuotaManager::UsageAndQuotaDispatcherTask::Create(
- QuotaManager* manager, const std::string& host, StorageType type) {
- switch (type) {
+ QuotaManager* manager, bool global,
+ const QuotaManager::HostAndType& host_and_type) {
+ if (global)
+ return new UsageAndQuotaDispatcherTaskForTemporaryGlobal(
+ manager, host_and_type);
+ switch (host_and_type.second) {
case kStorageTypeTemporary:
return new UsageAndQuotaDispatcherTaskForTemporary(
- manager, host);
+ manager, host_and_type);
case kStorageTypePersistent:
return new UsageAndQuotaDispatcherTaskForPersistent(
- manager, host);
+ manager, host_and_type);
default:
NOTREACHED();
}
@@ -534,83 +558,72 @@ class QuotaManager::DatabaseTaskBase : public QuotaThreadTask {
class QuotaManager::InitializeTask : public QuotaManager::DatabaseTaskBase {
public:
- InitializeTask(
- QuotaManager* manager,
- const FilePath& profile_path,
- bool is_incognito)
+ InitializeTask(QuotaManager* manager)
: DatabaseTaskBase(manager),
- profile_path_(profile_path),
- is_incognito_(is_incognito),
- need_initialize_origins_(false),
- temporary_storage_quota_(-1) {
+ temporary_quota_override_(-1),
+ desired_available_space_(-1) {
+ DCHECK(manager);
}
protected:
virtual void RunOnTargetThread() OVERRIDE {
- // Initializes the global temporary quota.
- if (!database()->GetGlobalQuota(
- kStorageTypeTemporary, &temporary_storage_quota_)) {
- // If the temporary storage quota size has not been initialized,
- // make up one and store it in the database.
- temporary_storage_quota_ = GetInitialTemporaryStorageQuotaSize(
- profile_path_, is_incognito_);
- UMA_HISTOGRAM_MBYTES("Quota.InitialTemporaryGlobalStorageQuota",
- temporary_storage_quota_);
- if (!database()->SetGlobalQuota(
- kStorageTypeTemporary, temporary_storage_quota_)) {
- set_db_disabled(true);
- }
- }
- if (!db_disabled())
- need_initialize_origins_ = !database()->IsOriginDatabaseBootstrapped();
+ // See if we have overriding temporary quota configuration.
+ database()->GetQuotaConfigValue(QuotaDatabase::kTemporaryQuotaOverrideKey,
+ &temporary_quota_override_);
+ database()->GetQuotaConfigValue(QuotaDatabase::kDesiredAvailableSpaceKey,
+ &desired_available_space_);
}
virtual void DatabaseTaskCompleted() OVERRIDE {
- manager()->need_initialize_origins_ = need_initialize_origins_;
- manager()->DidInitializeTemporaryGlobalQuota(temporary_storage_quota_);
- manager()->histogram_timer_.Start(FROM_HERE,
- QuotaManager::kReportHistogramInterval,
- manager(),
- &QuotaManager::ReportHistogram);
+ manager()->temporary_quota_override_ = temporary_quota_override_;
+ manager()->desired_available_space_ = desired_available_space_;
+ manager()->temporary_quota_initialized_ = true;
+ manager()->DidRunInitializeTask();
}
private:
- FilePath profile_path_;
- bool is_incognito_;
- bool need_initialize_origins_;
- int64 temporary_storage_quota_;
+ int64 temporary_quota_override_;
+ int64 desired_available_space_;
};
-class QuotaManager::UpdateTemporaryGlobalQuotaTask
+class QuotaManager::UpdateTemporaryQuotaOverrideTask
: public QuotaManager::DatabaseTaskBase {
public:
- UpdateTemporaryGlobalQuotaTask(
+ UpdateTemporaryQuotaOverrideTask(
QuotaManager* manager,
int64 new_quota,
QuotaCallback* callback)
: DatabaseTaskBase(manager),
new_quota_(new_quota),
- callback_(callback) {
- DCHECK_GE(new_quota, 0);
- }
+ callback_(callback) {}
protected:
virtual void RunOnTargetThread() OVERRIDE {
- if (!database()->SetGlobalQuota(kStorageTypeTemporary, new_quota_)) {
+ if (!database()->SetQuotaConfigValue(
+ QuotaDatabase::kTemporaryQuotaOverrideKey, new_quota_)) {
set_db_disabled(true);
- new_quota_ = 0;
+ new_quota_ = -1;
+ return;
}
}
virtual void DatabaseTaskCompleted() OVERRIDE {
- callback_->Run(db_disabled() ? kQuotaErrorInvalidAccess : kQuotaStatusOk,
- kStorageTypeTemporary, new_quota_);
if (!db_disabled()) {
- manager()->temporary_global_quota_ = new_quota_;
+ manager()->temporary_quota_override_ = new_quota_;
+ CallCallback(kQuotaStatusOk, kStorageTypeTemporary, new_quota_);
+ } else {
+ CallCallback(kQuotaErrorInvalidAccess, kStorageTypeTemporary, new_quota_);
}
}
private:
+ void CallCallback(QuotaStatusCode status, StorageType type, int64 quota) {
+ if (callback_.get()) {
+ callback_->Run(status, type, quota);
+ callback_.reset();
+ }
+ }
+
int64 new_quota_;
scoped_ptr<QuotaCallback> callback_;
};
@@ -708,9 +721,8 @@ class QuotaManager::GetLRUOriginTask
protected:
virtual void RunOnTargetThread() OVERRIDE {
- if (!database()->GetLRUOrigin(type_, exceptions_,
- special_storage_policy_, &url_))
- set_db_disabled(true);
+ database()->GetLRUOrigin(
+ type_, exceptions_, special_storage_policy_, &url_);
}
virtual void DatabaseTaskCompleted() OVERRIDE {
@@ -792,13 +804,12 @@ class QuotaManager::AvailableSpaceQueryTask : public QuotaThreadTask {
public:
AvailableSpaceQueryTask(
QuotaManager* manager,
- scoped_refptr<base::MessageLoopProxy> db_message_loop,
- const FilePath& profile_path,
AvailableSpaceCallback* callback)
- : QuotaThreadTask(manager, db_message_loop),
- profile_path_(profile_path),
+ : QuotaThreadTask(manager, manager->db_thread_),
+ profile_path_(manager->profile_path_),
space_(-1),
- callback_(callback) {}
+ callback_(callback) {
+ }
virtual ~AvailableSpaceQueryTask() {}
protected:
@@ -807,7 +818,7 @@ class QuotaManager::AvailableSpaceQueryTask : public QuotaThreadTask {
}
virtual void Aborted() OVERRIDE {
- callback_->Run(kQuotaErrorAbort, -1);
+ callback_.reset();
}
virtual void Completed() OVERRIDE {
@@ -1010,8 +1021,9 @@ QuotaManager::QuotaManager(bool is_incognito,
eviction_disabled_(false),
io_thread_(io_thread),
db_thread_(db_thread),
- need_initialize_origins_(false),
- temporary_global_quota_(-1),
+ temporary_quota_initialized_(false),
+ temporary_quota_override_(-1),
+ desired_available_space_(-1),
special_storage_policy_(special_storage_policy),
callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
}
@@ -1033,71 +1045,54 @@ void QuotaManager::GetUsageInfo(GetUsageInfoCallback* callback) {
void QuotaManager::GetUsageAndQuota(
const GURL& origin, StorageType type,
- GetUsageAndQuotaCallback* callback_ptr) {
- scoped_ptr<GetUsageAndQuotaCallback> callback(callback_ptr);
- LazyInitialize();
-
- if (type == kStorageTypeUnknown) {
- // Quota only supports temporary/persistent types.
- callback->Run(kQuotaErrorNotSupported, 0, 0);
- return;
- }
-
- // note: returns host usage and quota
- std::string host = net::GetHostOrSpecFromURL(origin);
- UsageAndQuotaDispatcherTaskMap::iterator found =
- usage_and_quota_dispatchers_.find(std::make_pair(host, type));
- if (found == usage_and_quota_dispatchers_.end()) {
- UsageAndQuotaDispatcherTask* dispatcher =
- UsageAndQuotaDispatcherTask::Create(this, host, type);
- found = usage_and_quota_dispatchers_.insert(
- std::make_pair(std::make_pair(host, type), dispatcher)).first;
- }
- if (found->second->AddCallback(
- callback.release(), IsStorageUnlimited(origin))) {
- found->second->Start();
- }
+ GetUsageAndQuotaCallback* callback) {
+ GetUsageAndQuotaInternal(origin, type, false /* global */,
+ base::Bind(&CallGetUsageAndQuotaCallback,
+ callback, IsStorageUnlimited(origin)));
}
void QuotaManager::GetAvailableSpace(AvailableSpaceCallback* callback) {
- scoped_refptr<AvailableSpaceQueryTask> task(
- new AvailableSpaceQueryTask(this, db_thread_, profile_path_, callback));
- task->Start();
+ if (is_incognito_) {
+ callback->Run(kQuotaStatusOk, kIncognitoDefaultTemporaryQuota);
+ delete callback;
+ return;
+ }
+ make_scoped_refptr(new AvailableSpaceQueryTask(this, callback))->Start();
}
void QuotaManager::GetTemporaryGlobalQuota(QuotaCallback* callback) {
- LazyInitialize();
- if (temporary_global_quota_ >= 0) {
- // TODO(kinuko): We may want to adjust the quota when the current
- // available space in the hard drive is getting tight.
- callback->Run(kQuotaStatusOk,
- kStorageTypeTemporary, temporary_global_quota_);
+ if (temporary_quota_override_ > 0) {
+ callback->Run(kQuotaStatusOk, kStorageTypeTemporary,
+ temporary_quota_override_);
delete callback;
return;
}
- // They are called upon completion of InitializeTask.
- temporary_global_quota_callbacks_.Add(callback);
+ GetUsageAndQuotaInternal(
+ GURL(), kStorageTypeTemporary, true /* global */,
+ base::Bind(&CallQuotaCallback, callback, kStorageTypeTemporary));
}
-void QuotaManager::SetTemporaryGlobalQuota(int64 new_quota,
- QuotaCallback* callback) {
+void QuotaManager::SetTemporaryGlobalOverrideQuota(
+ int64 new_quota, QuotaCallback* callback_ptr) {
+ scoped_ptr<QuotaCallback> callback(callback_ptr);
LazyInitialize();
+
if (new_quota < 0) {
- callback->Run(kQuotaErrorInvalidModification,
- kStorageTypeTemporary, -1);
- delete callback;
+ if (callback.get())
+ callback->Run(kQuotaErrorInvalidModification,
+ kStorageTypeTemporary, -1);
return;
}
- if (!db_disabled_) {
- scoped_refptr<UpdateTemporaryGlobalQuotaTask> task(
- new UpdateTemporaryGlobalQuotaTask(this, new_quota, callback));
- task->Start();
- } else {
- callback->Run(kQuotaErrorInvalidAccess,
- kStorageTypeTemporary, -1);
- delete callback;
+ if (db_disabled_) {
+ if (callback.get())
+ callback->Run(kQuotaErrorInvalidAccess,
+ kStorageTypeTemporary, -1);
+ return;
}
+
+ make_scoped_refptr(new UpdateTemporaryQuotaOverrideTask(
+ this, new_quota, callback.release()))->Start();
}
void QuotaManager::GetPersistentHostQuota(const std::string& host,
@@ -1196,9 +1191,7 @@ void QuotaManager::LazyInitialize() {
new UsageTracker(clients_, kStorageTypePersistent,
special_storage_policy_));
- scoped_refptr<InitializeTask> task(
- new InitializeTask(this, profile_path_, is_incognito_));
- task->Start();
+ make_scoped_refptr(new InitializeTask(this))->Start();
}
void QuotaManager::RegisterClient(QuotaClient* client) {
@@ -1329,6 +1322,46 @@ void QuotaManager::NotifyStorageModifiedInternal(
this, origin, type, modified_time))->Start();
}
+void QuotaManager::GetUsageAndQuotaInternal(
+ const GURL& origin, StorageType type, bool global,
+ const UsageAndQuotaDispatcherCallback& callback) {
+ LazyInitialize();
+
+ StorageType requested_type = type;
+ if (type == kStorageTypeUnknown) {
+ // Quota only supports temporary/persistent types.
+ callback.Run(kQuotaErrorNotSupported, QuotaAndUsage());
+ return;
+ }
+
+ // Special internal type for querying global usage and quota.
+ const int kStorageTypeTemporaryGlobal = kStorageTypeTemporary + 100;
+ if (global) {
+ DCHECK_EQ(kStorageTypeTemporary, type);
+ type = static_cast<StorageType>(kStorageTypeTemporaryGlobal);
+ }
+
+ std::string host = net::GetHostOrSpecFromURL(origin);
+ HostAndType host_and_type = std::make_pair(host, type);
+ UsageAndQuotaDispatcherTaskMap::iterator found =
+ usage_and_quota_dispatchers_.find(host_and_type);
+ if (found == usage_and_quota_dispatchers_.end()) {
+ UsageAndQuotaDispatcherTask* dispatcher =
+ UsageAndQuotaDispatcherTask::Create(this, global, host_and_type);
+ found = usage_and_quota_dispatchers_.insert(
+ std::make_pair(host_and_type, dispatcher)).first;
+ }
+ // Start the dispatcher if it is the first one and temporary_quota_override
+ // is already initialized iff the requested type is temporary.
+ // (The first dispatcher task for temporary will be kicked in
+ // DidRunInitializeTask if temporary_quota_initialized_ is false here.)
+ if (found->second->AddCallback(callback) &&
+ (requested_type != kStorageTypeTemporary ||
+ temporary_quota_initialized_)) {
+ found->second->Start();
+ }
+}
+
void QuotaManager::DumpQuotaTable(DumpQuotaTableCallback* callback) {
make_scoped_refptr(new DumpQuotaTableTask(this, callback))->Start();
}
@@ -1398,58 +1431,20 @@ void QuotaManager::EvictOriginData(
&QuotaManager::DidOriginDataEvicted));
}
-void QuotaManager::DidGetAvailableSpaceForEviction(
- QuotaStatusCode status,
- int64 available_space) {
- eviction_context_.get_usage_and_quota_callback->Run(status,
- eviction_context_.usage,
- eviction_context_.unlimited_usage,
- eviction_context_.quota, available_space);
- eviction_context_.get_usage_and_quota_callback.reset();
-}
-
-void QuotaManager::DidGetGlobalQuotaForEviction(
- QuotaStatusCode status,
- StorageType type,
- int64 quota) {
- DCHECK_EQ(type, kStorageTypeTemporary);
- if (status != kQuotaStatusOk) {
- eviction_context_.get_usage_and_quota_callback->Run(
- status, 0, 0, 0, 0);
- eviction_context_.get_usage_and_quota_callback.reset();
- return;
- }
-
- eviction_context_.quota = quota;
- GetAvailableSpace(callback_factory_.
- NewCallback(&QuotaManager::DidGetAvailableSpaceForEviction));
-}
-
-void QuotaManager::DidGetGlobalUsageForEviction(
- StorageType type, int64 usage, int64 unlimited_usage) {
- DCHECK_EQ(type, kStorageTypeTemporary);
- DCHECK_GE(usage, unlimited_usage);
- eviction_context_.usage = usage;
- eviction_context_.unlimited_usage = unlimited_usage;
- GetTemporaryGlobalQuota(callback_factory_.
- NewCallback(&QuotaManager::DidGetGlobalQuotaForEviction));
-}
-
void QuotaManager::GetUsageAndQuotaForEviction(
- GetUsageAndQuotaForEvictionCallback* callback) {
+ const GetUsageAndQuotaForEvictionCallback& callback) {
DCHECK(io_thread_->BelongsToCurrentThread());
- DCHECK(!eviction_context_.get_usage_and_quota_callback.get());
-
- eviction_context_.get_usage_and_quota_callback.reset(callback);
- // TODO(dmikurube): Make kStorageTypeTemporary an argument.
- GetGlobalUsage(kStorageTypeTemporary, callback_factory_.
- NewCallback(&QuotaManager::DidGetGlobalUsageForEviction));
+ GetUsageAndQuotaInternal(
+ GURL(), kStorageTypeTemporary, true /* global */, callback);
}
void QuotaManager::StartEviction() {
DCHECK(!temporary_storage_evictor_.get());
- temporary_storage_evictor_.reset(new QuotaTemporaryStorageEvictor(this,
- kEvictionIntervalInMilliSeconds));
+ 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();
}
@@ -1508,38 +1503,40 @@ void QuotaManager::DidGetPersistentGlobalUsageForHistogram(
unlimited_origins);
}
-void QuotaManager::DidInitializeTemporaryGlobalQuota(int64 quota) {
- temporary_global_quota_ = quota;
- temporary_global_quota_callbacks_.Run(
- db_disabled_ ? kQuotaErrorInvalidAccess : kQuotaStatusOk,
- kStorageTypeTemporary, quota);
+void QuotaManager::DidRunInitializeTask() {
+ histogram_timer_.Start(FROM_HERE,
+ base::TimeDelta::FromMilliseconds(
+ kReportHistogramInterval),
+ this, &QuotaManager::ReportHistogram);
- if (db_disabled_ || eviction_disabled_)
- return;
+ DCHECK(temporary_quota_initialized_);
- if (!need_initialize_origins_) {
- StartEviction();
- return;
+ // Kick the tasks that have been waiting for the
+ // temporary_quota_initialized_ to be initialized (if there're any).
+ for (UsageAndQuotaDispatcherTaskMap::iterator iter =
+ usage_and_quota_dispatchers_.begin();
+ iter != usage_and_quota_dispatchers_.end(); ++iter) {
+ if (iter->second->IsStartable())
+ iter->second->Start();
}
- // We seem to need to initialize the origin table in the database.
- // Kick the first GetGlobalUsage for temporary storage to cache a list
- // of origins that have data in temporary storage to register them
- // in the database. (We'll need the global temporary usage anyway
- // for eviction later.)
- temporary_usage_tracker_->GetGlobalUsage(callback_factory_.NewCallback(
- &QuotaManager::DidRunInitialGetTemporaryGlobalUsage));
+ // Kick the first GetTemporaryGlobalQuota. This internally fetches (and
+ // caches) the usage of all origins and checks the available disk space.
+ GetTemporaryGlobalQuota(callback_factory_.NewCallback(
+ &QuotaManager::DidGetInitialTemporaryGlobalQuota));
}
-void QuotaManager::DidRunInitialGetTemporaryGlobalUsage(
- StorageType type, int64 usage_unused, int64 unlimited_usage_unused) {
+void QuotaManager::DidGetInitialTemporaryGlobalQuota(
+ QuotaStatusCode status, StorageType type, int64 quota_unused) {
DCHECK_EQ(type, kStorageTypeTemporary);
+
+ if (eviction_disabled_)
+ return;
+
// This will call the StartEviction() when initial origin registration
// is completed.
- scoped_refptr<InitializeTemporaryOriginsInfoTask> task(
- new InitializeTemporaryOriginsInfoTask(
- this, temporary_usage_tracker_.get()));
- task->Start();
+ make_scoped_refptr(new InitializeTemporaryOriginsInfoTask(
+ this, temporary_usage_tracker_.get()))->Start();
}
void QuotaManager::DidGetDatabaseLRUOrigin(const GURL& origin) {
diff --git a/webkit/quota/quota_manager.h b/webkit/quota/quota_manager.h
index 2d0de6a..df701d6 100644
--- a/webkit/quota/quota_manager.h
+++ b/webkit/quota/quota_manager.h
@@ -45,20 +45,24 @@ class QuotaTemporaryStorageEvictor;
class UsageTracker;
class MockQuotaManager;
+struct QuotaAndUsage {
+ int64 usage;
+ int64 unlimited_usage;
+ int64 quota;
+ int64 available_disk_space;
+};
+
// An interface called by QuotaTemporaryStorageEvictor.
class QuotaEvictionHandler {
public:
- virtual ~QuotaEvictionHandler() {}
-
typedef Callback1<const GURL&>::Type GetLRUOriginCallback;
typedef StatusCallback EvictOriginDataCallback;
- typedef Callback5<QuotaStatusCode,
- int64 /* usage */,
- int64 /* unlimited_usage */,
- int64 /* quota */,
- int64 /* physical_available */ >::Type
+ typedef base::Callback<void(QuotaStatusCode,
+ const QuotaAndUsage& quota_and_usage)>
GetUsageAndQuotaForEvictionCallback;
+ virtual ~QuotaEvictionHandler() {}
+
// Returns the least recently used origin. It might return empty
// GURL when there are no evictable origins.
virtual void GetLRUOrigin(
@@ -71,7 +75,7 @@ class QuotaEvictionHandler {
EvictOriginDataCallback* callback) = 0;
virtual void GetUsageAndQuotaForEviction(
- GetUsageAndQuotaForEvictionCallback* callback) = 0;
+ const GetUsageAndQuotaForEvictionCallback& callback) = 0;
};
struct UsageInfo {
@@ -149,7 +153,11 @@ class QuotaManager : public QuotaTaskObserver,
// Called by UI and internal modules.
void GetAvailableSpace(AvailableSpaceCallback* callback);
void GetTemporaryGlobalQuota(QuotaCallback* callback);
- void SetTemporaryGlobalQuota(int64 new_quota, QuotaCallback* callback);
+
+ // Ok to call with NULL callback.
+ void SetTemporaryGlobalOverrideQuota(int64 new_quota,
+ QuotaCallback* callback);
+
void GetPersistentHostQuota(const std::string& host,
HostQuotaCallback* callback);
void SetPersistentHostQuota(const std::string& host,
@@ -172,11 +180,6 @@ class QuotaManager : public QuotaTaskObserver,
bool ResetUsageTracker(StorageType type);
- // Used to determine the total size of the temp pool.
- static const int64 kTemporaryStorageQuotaDefaultSize;
- static const int64 kTemporaryStorageQuotaMaxSize;
- static const int64 kIncognitoDefaultTemporaryQuota;
-
// Determines the portion of the temp pool that can be
// utilized by a single host (ie. 5 for 20%).
static const int kPerHostTemporaryPortion;
@@ -186,12 +189,11 @@ class QuotaManager : public QuotaTaskObserver,
static const int kThresholdOfErrorsToBeBlacklisted;
static const int kEvictionIntervalInMilliSeconds;
- static const base::TimeDelta kReportHistogramInterval;
private:
class DatabaseTaskBase;
class InitializeTask;
- class UpdateTemporaryGlobalQuotaTask;
+ class UpdateTemporaryQuotaOverrideTask;
class GetPersistentHostQuotaTask;
class UpdatePersistentHostQuotaTask;
class GetLRUOriginTask;
@@ -205,6 +207,7 @@ class QuotaManager : public QuotaTaskObserver,
class UsageAndQuotaDispatcherTask;
class UsageAndQuotaDispatcherTaskForTemporary;
class UsageAndQuotaDispatcherTaskForPersistent;
+ class UsageAndQuotaDispatcherTaskForTemporaryGlobal;
class OriginDataDeleter;
@@ -222,29 +225,20 @@ class QuotaManager : public QuotaTaskObserver,
DumpOriginInfoTableCallback;
struct EvictionContext {
- EvictionContext()
- : evicted_type(kStorageTypeUnknown),
- usage(0),
- unlimited_usage(0),
- quota(0) {}
+ EvictionContext() : evicted_type(kStorageTypeUnknown) {}
virtual ~EvictionContext() {}
-
GURL evicted_origin;
StorageType evicted_type;
-
scoped_ptr<EvictOriginDataCallback> evict_origin_data_callback;
-
- scoped_ptr<GetUsageAndQuotaForEvictionCallback>
- get_usage_and_quota_callback;
- int64 usage;
- int64 unlimited_usage;
- int64 quota;
};
typedef std::pair<std::string, StorageType> HostAndType;
typedef std::map<HostAndType, UsageAndQuotaDispatcherTask*>
UsageAndQuotaDispatcherTaskMap;
+ typedef QuotaEvictionHandler::GetUsageAndQuotaForEvictionCallback
+ UsageAndQuotaDispatcherCallback;
+
friend class quota_internals::QuotaInternalsProxy;
friend struct QuotaManagerDeleter;
friend class MockStorageClient;
@@ -283,6 +277,13 @@ class QuotaManager : public QuotaTaskObserver,
int64 delta,
base::Time modified_time);
+ // |origin| can be empty if |global| is true.
+ void GetUsageAndQuotaInternal(
+ const GURL& origin,
+ StorageType type,
+ bool global,
+ const UsageAndQuotaDispatcherCallback& callback);
+
void DumpQuotaTable(DumpQuotaTableCallback* callback);
void DumpOriginInfoTable(DumpOriginInfoTableCallback* callback);
@@ -291,16 +292,12 @@ class QuotaManager : public QuotaTaskObserver,
void DeleteOriginFromDatabase(const GURL& origin, StorageType type);
void DidOriginDataEvicted(QuotaStatusCode status);
- void DidGetAvailableSpaceForEviction(
- QuotaStatusCode status,
- int64 available_space);
- void DidGetGlobalQuotaForEviction(
- QuotaStatusCode status,
- StorageType type,
- int64 quota);
- void DidGetGlobalUsageForEviction(StorageType type,
- int64 usage,
- int64 unlimited_usage);
+ void DidGetGlobalUsageAndQuotaForEviction(QuotaStatusCode status,
+ StorageType type,
+ int64 usage,
+ int64 unlimited_usage,
+ int64 quota,
+ int64 available_space);
void ReportHistogram();
void DidGetTemporaryGlobalUsageForHistogram(StorageType type,
@@ -319,11 +316,12 @@ class QuotaManager : public QuotaTaskObserver,
StorageType type,
EvictOriginDataCallback* callback) OVERRIDE;
virtual void GetUsageAndQuotaForEviction(
- GetUsageAndQuotaForEvictionCallback* callback) OVERRIDE;
+ const GetUsageAndQuotaForEvictionCallback& callback) OVERRIDE;
- void DidInitializeTemporaryGlobalQuota(int64 quota);
- void DidRunInitialGetTemporaryGlobalUsage(StorageType type, int64 usage,
- int64 unlimited_usage);
+ void DidRunInitializeTask();
+ void DidGetInitialTemporaryGlobalQuota(QuotaStatusCode status,
+ StorageType type,
+ int64 quota_unused);
void DidGetDatabaseLRUOrigin(const GURL& origin);
void DeleteOnCorrectThread() const;
@@ -338,7 +336,6 @@ class QuotaManager : public QuotaTaskObserver,
scoped_refptr<base::MessageLoopProxy> db_thread_;
mutable scoped_ptr<QuotaDatabase> database_;
- bool need_initialize_origins_;
scoped_ptr<GetLRUOriginCallback> lru_origin_callback_;
std::set<GURL> access_notified_origins_;
@@ -354,8 +351,10 @@ class QuotaManager : public QuotaTaskObserver,
UsageAndQuotaDispatcherTaskMap usage_and_quota_dispatchers_;
- int64 temporary_global_quota_;
- QuotaCallbackQueue temporary_global_quota_callbacks_;
+ bool temporary_quota_initialized_;
+ int64 temporary_quota_override_;
+
+ int64 desired_available_space_;
// Map from origin to count.
std::map<GURL, int> origins_in_use_;
diff --git a/webkit/quota/quota_manager_unittest.cc b/webkit/quota/quota_manager_unittest.cc
index e9f4ab3..3a34e9f 100644
--- a/webkit/quota/quota_manager_unittest.cc
+++ b/webkit/quota/quota_manager_unittest.cc
@@ -6,9 +6,11 @@
#include <sstream>
#include <vector>
+#include "base/bind.h"
#include "base/file_util.h"
#include "base/memory/scoped_callback_factory.h"
#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
#include "base/message_loop.h"
#include "base/message_loop_proxy.h"
#include "base/scoped_temp_dir.h"
@@ -17,16 +19,12 @@
#include "base/time.h"
#include "googleurl/src/gurl.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebStorageQuotaError.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebStorageQuotaType.h"
#include "webkit/quota/mock_special_storage_policy.h"
#include "webkit/quota/mock_storage_client.h"
#include "webkit/quota/quota_database.h"
#include "webkit/quota/quota_manager.h"
using base::MessageLoopProxy;
-using WebKit::WebStorageQuotaError;
-using WebKit::WebStorageQuotaType;
namespace quota {
@@ -43,6 +41,7 @@ class QuotaManagerTest : public testing::Test {
public:
QuotaManagerTest()
: callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
+ weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
mock_time_counter_(0) {
}
@@ -103,7 +102,8 @@ class QuotaManagerTest : public testing::Test {
void SetTemporaryGlobalQuota(int64 new_quota) {
quota_status_ = kQuotaStatusUnknown;
quota_ = -1;
- quota_manager_->SetTemporaryGlobalQuota(new_quota,
+ quota_manager_->SetTemporaryGlobalOverrideQuota(
+ new_quota,
callback_factory_.NewCallback(
&QuotaManagerTest::DidGetQuota));
}
@@ -193,8 +193,8 @@ class QuotaManagerTest : public testing::Test {
quota_ = -1;
available_space_ = -1;
quota_manager_->GetUsageAndQuotaForEviction(
- callback_factory_.NewCallback(
- &QuotaManagerTest::DidGetUsageAndQuotaForEviction));
+ base::Bind(&QuotaManagerTest::DidGetUsageAndQuotaForEviction,
+ weak_factory_.GetWeakPtr()));
}
void GetCachedOrigins(StorageType type, std::set<GURL>* origins) {
@@ -305,12 +305,12 @@ class QuotaManagerTest : public testing::Test {
}
void DidGetUsageAndQuotaForEviction(QuotaStatusCode status,
- int64 usage, int64 unlimited_usage, int64 quota, int64 available_space) {
+ const QuotaAndUsage& quota_and_usage) {
quota_status_ = status;
- usage_ = usage;
- unlimited_usage_ = unlimited_usage;
- quota_ = quota;
- available_space_ = available_space;
+ usage_ = quota_and_usage.usage;
+ unlimited_usage_ = quota_and_usage.unlimited_usage;
+ quota_ = quota_and_usage.quota;
+ available_space_ = quota_and_usage.available_disk_space;
}
void DidGetLRUOrigin(const GURL& origin) {
@@ -375,6 +375,7 @@ class QuotaManagerTest : public testing::Test {
ScopedTempDir data_dir_;
base::ScopedCallbackFactory<QuotaManagerTest> callback_factory_;
+ base::WeakPtrFactory<QuotaManagerTest> weak_factory_;
scoped_refptr<QuotaManager> quota_manager_;
scoped_refptr<MockSpecialStoragePolicy> mock_special_storage_policy_;
@@ -440,7 +441,7 @@ TEST_F(QuotaManagerTest, GetUsageInfo) {
TEST_F(QuotaManagerTest, GetUsageAndQuota_Simple) {
static const MockOriginData kData[] = {
- { "http://foo.com/", kTemp, 10 },
+ { "http://foo.com/", kTemp, 10 },
{ "http://foo.com/", kPerm, 80 },
};
RegisterClient(CreateClient(kData, ARRAYSIZE_UNSAFE(kData)));
@@ -456,7 +457,6 @@ TEST_F(QuotaManagerTest, GetUsageAndQuota_Simple) {
EXPECT_EQ(kQuotaStatusOk, status());
EXPECT_EQ(10, usage());
EXPECT_LE(0, quota());
- EXPECT_GE(QuotaManager::kTemporaryStorageQuotaMaxSize, quota());
int64 quota_returned_for_foo = quota();
GetUsageAndQuota(GURL("http://bar.com/"), kTemp);
@@ -534,7 +534,7 @@ TEST_F(QuotaManagerTest, GetTemporaryUsageAndQuota_MultiOrigins) {
{ "http://bar.com/", kTemp, 5 },
{ "https://bar.com/", kTemp, 7 },
{ "http://baz.com/", kTemp, 30 },
- { "http://foo.com/", kPerm, 40 },
+ { "http://foo.com/", kPerm, 40 },
};
RegisterClient(CreateClient(kData, ARRAYSIZE_UNSAFE(kData)));
@@ -655,9 +655,9 @@ TEST_F(QuotaManagerTest, GetTemporaryUsage_WithModify) {
TEST_F(QuotaManagerTest, GetTemporaryUsageAndQuota_WithAdditionalTasks) {
static const MockOriginData kData[] = {
- { "http://foo.com/", kTemp, 10 },
- { "http://foo.com:8080/", kTemp, 20 },
- { "http://bar.com/", kTemp, 13 },
+ { "http://foo.com/", kTemp, 10 },
+ { "http://foo.com:8080/", kTemp, 20 },
+ { "http://bar.com/", kTemp, 13 },
{ "http://foo.com/", kPerm, 40 },
};
RegisterClient(CreateClient(kData, ARRAYSIZE_UNSAFE(kData)));
@@ -689,9 +689,9 @@ TEST_F(QuotaManagerTest, GetTemporaryUsageAndQuota_WithAdditionalTasks) {
TEST_F(QuotaManagerTest, GetTemporaryUsageAndQuota_NukeManager) {
static const MockOriginData kData[] = {
- { "http://foo.com/", kTemp, 10 },
- { "http://foo.com:8080/", kTemp, 20 },
- { "http://bar.com/", kTemp, 13 },
+ { "http://foo.com/", kTemp, 10 },
+ { "http://foo.com:8080/", kTemp, 20 },
+ { "http://bar.com/", kTemp, 13 },
{ "http://foo.com/", kPerm, 40 },
};
RegisterClient(CreateClient(kData, ARRAYSIZE_UNSAFE(kData)));
@@ -1259,10 +1259,10 @@ TEST_F(QuotaManagerTest, EvictOriginDataWithDeletionError) {
TEST_F(QuotaManagerTest, GetUsageAndQuotaForEviction) {
static const MockOriginData kData[] = {
- { "http://foo.com/", kTemp, 1 },
- { "http://foo.com:1/", kTemp, 20 },
+ { "http://foo.com/", kTemp, 1 },
+ { "http://foo.com:1/", kTemp, 20 },
{ "http://foo.com/", kPerm, 300 },
- { "http://unlimited/", kTemp, 4000 },
+ { "http://unlimited/", kTemp, 4000 },
};
mock_special_storage_policy()->AddUnlimited(GURL("http://unlimited/"));
@@ -1388,16 +1388,17 @@ TEST_F(QuotaManagerTest, GetCachedOrigins) {
GetCachedOrigins(kTemp, &origins);
EXPECT_TRUE(origins.empty());
- // Make the cache hot.
+ // No matter how we make queries the quota manager tries to cache all
+ // the origins at startup.
GetHostUsage("a.com", kTemp);
MessageLoop::current()->RunAllPending();
GetCachedOrigins(kTemp, &origins);
- EXPECT_EQ(2U, origins.size());
+ EXPECT_EQ(3U, origins.size());
GetHostUsage("b.com", kTemp);
MessageLoop::current()->RunAllPending();
GetCachedOrigins(kTemp, &origins);
- EXPECT_EQ(2U, origins.size());
+ EXPECT_EQ(3U, origins.size());
GetCachedOrigins(kPerm, &origins);
EXPECT_TRUE(origins.empty());
diff --git a/webkit/quota/quota_temporary_storage_evictor.cc b/webkit/quota/quota_temporary_storage_evictor.cc
index f4b6750..1ad329a 100644
--- a/webkit/quota/quota_temporary_storage_evictor.cc
+++ b/webkit/quota/quota_temporary_storage_evictor.cc
@@ -4,6 +4,7 @@
#include "webkit/quota/quota_temporary_storage_evictor.h"
+#include "base/bind.h"
#include "base/metrics/histogram.h"
#include "googleurl/src/gurl.h"
#include "webkit/quota/quota_manager.h"
@@ -21,17 +22,16 @@
namespace {
const int64 kMBytes = 1024 * 1024;
+const double kUsageRatioToStartEviction = 0.7;
+const int kThresholdOfErrorsToStopEviction = 5;
+const base::TimeDelta kHistogramReportInterval =
+ base::TimeDelta::FromMilliseconds(60 * 60 * 1000); // 1 hour
}
namespace quota {
-const double QuotaTemporaryStorageEvictor::kUsageRatioToStartEviction = 0.7;
const int QuotaTemporaryStorageEvictor::
kMinAvailableDiskSpaceToStartEvictionNotSpecified = -1;
-const int QuotaTemporaryStorageEvictor::kThresholdOfErrorsToStopEviction = 5;
-
-const base::TimeDelta QuotaTemporaryStorageEvictor::kHistogramReportInterval =
- base::TimeDelta::FromMilliseconds(60 * 60 * 1000); // 1 hour
QuotaTemporaryStorageEvictor::QuotaTemporaryStorageEvictor(
QuotaEvictionHandler* quota_eviction_handler,
@@ -41,7 +41,8 @@ QuotaTemporaryStorageEvictor::QuotaTemporaryStorageEvictor(
quota_eviction_handler_(quota_eviction_handler),
interval_ms_(interval_ms),
repeated_eviction_(true),
- callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+ callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
+ weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
DCHECK(quota_eviction_handler);
}
@@ -143,32 +144,33 @@ void QuotaTemporaryStorageEvictor::ConsiderEviction() {
OnEvictionRoundStarted();
// Get usage and disk space, then continue.
- quota_eviction_handler_->GetUsageAndQuotaForEviction(callback_factory_.
- NewCallback(
- &QuotaTemporaryStorageEvictor::OnGotUsageAndQuotaForEviction));
+ quota_eviction_handler_->GetUsageAndQuotaForEviction(
+ base::Bind(&QuotaTemporaryStorageEvictor::OnGotUsageAndQuotaForEviction,
+ weak_factory_.GetWeakPtr()));
}
void QuotaTemporaryStorageEvictor::OnGotUsageAndQuotaForEviction(
QuotaStatusCode status,
- int64 usage,
- int64 unlimited_usage,
- int64 quota,
- int64 available_disk_space) {
+ const QuotaAndUsage& qau) {
DCHECK(CalledOnValidThread());
- DCHECK_GE(usage, unlimited_usage); // unlimited_usage is a subset of usage
- usage -= unlimited_usage;
+ // unlimited_usage is a subset of usage
+ DCHECK_GE(qau.usage, qau.unlimited_usage);
+
+ int64 usage = qau.usage - qau.unlimited_usage;
if (status != kQuotaStatusOk)
++statistics_.num_errors_on_getting_usage_and_quota;
int64 usage_overage = std::max(
static_cast<int64>(0),
- usage - static_cast<int64>(quota * kUsageRatioToStartEviction));
+ usage - static_cast<int64>(qau.quota * kUsageRatioToStartEviction));
+ // min_available_disk_space_to_start_eviction_ might be < 0 if no value
+ // is explicitly configured yet.
int64 diskspace_shortage = std::max(
static_cast<int64>(0),
- min_available_disk_space_to_start_eviction_ - available_disk_space);
+ min_available_disk_space_to_start_eviction_ - qau.available_disk_space);
if (!round_statistics_.is_initialized) {
round_statistics_.usage_overage_at_round = usage_overage;
diff --git a/webkit/quota/quota_temporary_storage_evictor.h b/webkit/quota/quota_temporary_storage_evictor.h
index e65dd80..a537171 100644
--- a/webkit/quota/quota_temporary_storage_evictor.h
+++ b/webkit/quota/quota_temporary_storage_evictor.h
@@ -10,6 +10,7 @@
#include <string>
#include "base/memory/scoped_callback_factory.h"
+#include "base/memory/weak_ptr.h"
#include "base/threading/non_thread_safe.h"
#include "base/timer.h"
#include "webkit/quota/quota_types.h"
@@ -23,6 +24,7 @@ class MessageLoopProxy;
namespace quota {
class QuotaEvictionHandler;
+struct QuotaAndUsage;
class QuotaTemporaryStorageEvictor : public base::NonThreadSafe {
public:
@@ -100,10 +102,7 @@ class QuotaTemporaryStorageEvictor : public base::NonThreadSafe {
void ConsiderEviction();
void OnGotUsageAndQuotaForEviction(
QuotaStatusCode status,
- int64 usage,
- int64 unlimited_usage,
- int64 quota,
- int64 available_disk_space);
+ const QuotaAndUsage& quota_and_usage);
void OnGotLRUOrigin(const GURL& origin);
void OnEvictionComplete(QuotaStatusCode status);
@@ -115,10 +114,7 @@ class QuotaTemporaryStorageEvictor : public base::NonThreadSafe {
repeated_eviction_ = repeated_eviction;
}
- static const double kUsageRatioToStartEviction;
static const int kMinAvailableDiskSpaceToStartEvictionNotSpecified;
- static const int kThresholdOfErrorsToStopEviction;
- static const base::TimeDelta kHistogramReportInterval;
int64 min_available_disk_space_to_start_eviction_;
@@ -138,6 +134,7 @@ class QuotaTemporaryStorageEvictor : public base::NonThreadSafe {
base::RepeatingTimer<QuotaTemporaryStorageEvictor> histogram_timer_;
base::ScopedCallbackFactory<QuotaTemporaryStorageEvictor> callback_factory_;
+ base::WeakPtrFactory<QuotaTemporaryStorageEvictor> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(QuotaTemporaryStorageEvictor);
};
diff --git a/webkit/quota/quota_temporary_storage_evictor_unittest.cc b/webkit/quota/quota_temporary_storage_evictor_unittest.cc
index 6e857c7..398ba50 100644
--- a/webkit/quota/quota_temporary_storage_evictor_unittest.cc
+++ b/webkit/quota/quota_temporary_storage_evictor_unittest.cc
@@ -7,6 +7,7 @@
#include <list>
#include <map>
+#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "base/message_loop_proxy.h"
@@ -48,17 +49,16 @@ class MockQuotaEvictionHandler : public quota::QuotaEvictionHandler {
}
virtual void GetUsageAndQuotaForEviction(
- GetUsageAndQuotaForEvictionCallback* callback) OVERRIDE {
+ const GetUsageAndQuotaForEvictionCallback& callback) OVERRIDE {
if (error_on_get_usage_and_quota_) {
- callback->Run(quota::kQuotaErrorInvalidAccess, 0, 0, 0, 0);
- delete callback;
+ callback.Run(quota::kQuotaErrorInvalidAccess, QuotaAndUsage());
return;
}
if (task_for_get_usage_and_quota_.get())
task_for_get_usage_and_quota_->Run();
- callback->Run(quota::kQuotaStatusOk, GetUsage(), unlimited_usage_,
- quota_, available_space_);
- delete callback;
+ QuotaAndUsage quota_and_usage = {
+ GetUsage(), unlimited_usage_, quota_, available_space_ };
+ callback.Run(quota::kQuotaStatusOk, quota_and_usage);
}
virtual void GetLRUOrigin(
diff --git a/webkit/tools/test_shell/test_shell.gypi b/webkit/tools/test_shell/test_shell.gypi
index 886f7f6..ff8c757 100644
--- a/webkit/tools/test_shell/test_shell.gypi
+++ b/webkit/tools/test_shell/test_shell.gypi
@@ -448,13 +448,13 @@
'../../plugins/ppapi/resource_tracker_unittest.cc',
'../../plugins/ppapi/time_conversion_unittest.cc',
'../../plugins/ppapi/url_request_info_unittest.cc',
+ '../../quota/mock_quota_manager.cc',
+ '../../quota/mock_quota_manager.h',
+ '../../quota/mock_quota_manager_unittest.cc',
'../../quota/mock_special_storage_policy.cc',
'../../quota/mock_special_storage_policy.h',
'../../quota/mock_storage_client.cc',
'../../quota/mock_storage_client.h',
- '../../quota/mock_quota_manager.cc',
- '../../quota/mock_quota_manager.h',
- '../../quota/mock_quota_manager_unittest.cc',
'../../quota/quota_database_unittest.cc',
'../../quota/quota_manager_unittest.cc',
'../../quota/quota_temporary_storage_evictor_unittest.cc',