diff options
author | michaeln@google.com <michaeln@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-17 17:18:02 +0000 |
---|---|---|
committer | michaeln@google.com <michaeln@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-17 17:18:02 +0000 |
commit | 0179f39b00af02a9abde26f5003f213e25a4444a (patch) | |
tree | 4f0164d15fd13a7b9badbf2d52463a505a44060a /webkit | |
parent | 6658e7822f61494fbf91a8e9075ae81cf94d59be (diff) | |
download | chromium_src-0179f39b00af02a9abde26f5003f213e25a4444a.zip chromium_src-0179f39b00af02a9abde26f5003f213e25a4444a.tar.gz chromium_src-0179f39b00af02a9abde26f5003f213e25a4444a.tar.bz2 |
QuotaManager shouldn't crash if is_incognito is true.
BUG=82698
TEST=existing test chrome\test\functional\databases.py
Review URL: http://codereview.chromium.org/7031016
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@85645 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r-- | webkit/quota/quota_database.cc | 11 | ||||
-rw-r--r-- | webkit/quota/quota_database.h | 7 | ||||
-rw-r--r-- | webkit/quota/quota_database_unittest.cc | 244 | ||||
-rw-r--r-- | webkit/quota/quota_manager.cc | 50 |
4 files changed, 166 insertions, 146 deletions
diff --git a/webkit/quota/quota_database.cc b/webkit/quota/quota_database.cc index 23e4bab..cbe6cad 100644 --- a/webkit/quota/quota_database.cc +++ b/webkit/quota/quota_database.cc @@ -313,15 +313,20 @@ bool QuotaDatabase::LazyOpen(bool create_if_needed) { if (is_disabled_) return false; - if (!create_if_needed && !file_util::PathExists(db_file_path_)) + bool in_memory_only = db_file_path_.empty(); + if (!create_if_needed && + (in_memory_only || !file_util::PathExists(db_file_path_))) { return false; + } db_.reset(new sql::Connection); meta_table_.reset(new sql::MetaTable); bool opened = false; - if (!file_util::CreateDirectory(db_file_path_.DirName())) { - LOG(ERROR) << "Failed to create quota database directory."; + if (in_memory_only) { + opened = db_->OpenInMemory(); + } else if (!file_util::CreateDirectory(db_file_path_.DirName())) { + LOG(ERROR) << "Failed to create quota database directory."; } else { opened = db_->Open(db_file_path_); if (opened) diff --git a/webkit/quota/quota_database.h b/webkit/quota/quota_database.h index 001f473..2e27c1f 100644 --- a/webkit/quota/quota_database.h +++ b/webkit/quota/quota_database.h @@ -27,6 +27,7 @@ namespace quota { // All the methods of this class must run on the DB thread. class QuotaDatabase { public: + // If 'path' is empty, an in memory database will be used. explicit QuotaDatabase(const FilePath& path); ~QuotaDatabase(); @@ -68,11 +69,7 @@ class QuotaDatabase { bool is_recreating_; bool is_disabled_; - FRIEND_TEST_ALL_PREFIXES(QuotaDatabaseTest, LazyOpen); - FRIEND_TEST_ALL_PREFIXES(QuotaDatabaseTest, HostQuota); - FRIEND_TEST_ALL_PREFIXES(QuotaDatabaseTest, GlobalQuota); - FRIEND_TEST_ALL_PREFIXES(QuotaDatabaseTest, OriginLastAccessTimeLRU); - + friend class QuotaDatabaseTest; DISALLOW_COPY_AND_ASSIGN(QuotaDatabase); }; diff --git a/webkit/quota/quota_database_unittest.cc b/webkit/quota/quota_database_unittest.cc index 369ac3b0..5f6c1cc 100644 --- a/webkit/quota/quota_database_unittest.cc +++ b/webkit/quota/quota_database_unittest.cc @@ -27,141 +27,161 @@ class TestErrorDelegate : public sql::ErrorDelegate { namespace quota { -TEST(QuotaDatabaseTest, LazyOpen) { - ScopedTempDir data_dir; - ASSERT_TRUE(data_dir.CreateUniqueTempDir()); +class QuotaDatabaseTest : public testing::Test { + protected: + void LazyOpen(const FilePath& kDbFile) { + QuotaDatabase db(kDbFile); + EXPECT_FALSE(db.LazyOpen(false)); + ASSERT_TRUE(db.LazyOpen(true)); + EXPECT_TRUE(db.db_.get()); + EXPECT_TRUE(kDbFile.empty() || file_util::PathExists(kDbFile)); + } - const FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db"); - QuotaDatabase db(kDbFile); - EXPECT_FALSE(db.LazyOpen(false)); - ASSERT_TRUE(db.LazyOpen(true)); - EXPECT_TRUE(file_util::PathExists(kDbFile)); -} + void HostQuota(const FilePath& kDbFile) { + QuotaDatabase db(kDbFile); + ASSERT_TRUE(db.LazyOpen(true)); -TEST(QuotaDatabaseTest, HostQuota) { - ScopedTempDir data_dir; - ASSERT_TRUE(data_dir.CreateUniqueTempDir()); + const char* kHost = "foo.com"; + const int kQuota1 = 13579; + const int kQuota2 = kQuota1 + 1024; - const FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db"); - QuotaDatabase db(kDbFile); - ASSERT_TRUE(db.LazyOpen(true)); + int64 quota = -1; + EXPECT_FALSE(db.GetHostQuota(kHost, kStorageTypeTemporary, "a)); + EXPECT_FALSE(db.GetHostQuota(kHost, kStorageTypePersistent, "a)); - const char* kHost = "foo.com"; - const int kQuota1 = 13579; - const int kQuota2 = kQuota1 + 1024; + // Insert quota for temporary. + EXPECT_TRUE(db.SetHostQuota(kHost, kStorageTypeTemporary, kQuota1)); + EXPECT_TRUE(db.GetHostQuota(kHost, kStorageTypeTemporary, "a)); + EXPECT_EQ(kQuota1, quota); - int64 quota = -1; - EXPECT_FALSE(db.GetHostQuota(kHost, kStorageTypeTemporary, "a)); - EXPECT_FALSE(db.GetHostQuota(kHost, kStorageTypePersistent, "a)); + // Update quota for temporary. + EXPECT_TRUE(db.SetHostQuota(kHost, kStorageTypeTemporary, kQuota2)); + EXPECT_TRUE(db.GetHostQuota(kHost, kStorageTypeTemporary, "a)); + EXPECT_EQ(kQuota2, quota); - // Insert quota for temporary. - EXPECT_TRUE(db.SetHostQuota(kHost, kStorageTypeTemporary, kQuota1)); - EXPECT_TRUE(db.GetHostQuota(kHost, kStorageTypeTemporary, "a)); - EXPECT_EQ(kQuota1, quota); + // Quota for persistent must not be updated. + EXPECT_FALSE(db.GetHostQuota(kHost, kStorageTypePersistent, "a)); - // Update quota for temporary. - EXPECT_TRUE(db.SetHostQuota(kHost, kStorageTypeTemporary, kQuota2)); - EXPECT_TRUE(db.GetHostQuota(kHost, kStorageTypeTemporary, "a)); - EXPECT_EQ(kQuota2, quota); + // Delete temporary storage quota. + EXPECT_TRUE(db.DeleteHostQuota(kHost, kStorageTypeTemporary)); + EXPECT_FALSE(db.GetHostQuota(kHost, kStorageTypeTemporary, "a)); + } - // Quota for persistent must not be updated. - EXPECT_FALSE(db.GetHostQuota(kHost, kStorageTypePersistent, "a)); + void GlobalQuota(const FilePath& kDbFile) { + QuotaDatabase db(kDbFile); + ASSERT_TRUE(db.LazyOpen(true)); - // Delete temporary storage quota. - EXPECT_TRUE(db.DeleteHostQuota(kHost, kStorageTypeTemporary)); - EXPECT_FALSE(db.GetHostQuota(kHost, kStorageTypeTemporary, "a)); -} + const int kQuota1 = 9999; + const int kQuota2 = 86420; -TEST(QuotaDatabaseTest, GlobalQuota) { - ScopedTempDir data_dir; - ASSERT_TRUE(data_dir.CreateUniqueTempDir()); + int64 quota = -1; + EXPECT_FALSE(db.GetGlobalQuota(kStorageTypeTemporary, "a)); + EXPECT_FALSE(db.GetGlobalQuota(kStorageTypePersistent, "a)); - const FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db"); - QuotaDatabase db(kDbFile); - ASSERT_TRUE(db.LazyOpen(true)); + EXPECT_TRUE(db.SetGlobalQuota(kStorageTypeTemporary, kQuota1)); + EXPECT_TRUE(db.GetGlobalQuota(kStorageTypeTemporary, "a)); + EXPECT_EQ(kQuota1, quota); - const int kQuota1 = 9999; - const int kQuota2 = 86420; + EXPECT_TRUE(db.SetGlobalQuota(kStorageTypeTemporary, kQuota1 + 1024)); + EXPECT_TRUE(db.GetGlobalQuota(kStorageTypeTemporary, "a)); + EXPECT_EQ(kQuota1 + 1024, quota); - int64 quota = -1; - EXPECT_FALSE(db.GetGlobalQuota(kStorageTypeTemporary, "a)); - EXPECT_FALSE(db.GetGlobalQuota(kStorageTypePersistent, "a)); + EXPECT_FALSE(db.GetGlobalQuota(kStorageTypePersistent, "a)); - EXPECT_TRUE(db.SetGlobalQuota(kStorageTypeTemporary, kQuota1)); - EXPECT_TRUE(db.GetGlobalQuota(kStorageTypeTemporary, "a)); - EXPECT_EQ(kQuota1, quota); + EXPECT_TRUE(db.SetGlobalQuota(kStorageTypePersistent, kQuota2)); + EXPECT_TRUE(db.GetGlobalQuota(kStorageTypePersistent, "a)); + EXPECT_EQ(kQuota2, quota); + } - EXPECT_TRUE(db.SetGlobalQuota(kStorageTypeTemporary, kQuota1 + 1024)); - EXPECT_TRUE(db.GetGlobalQuota(kStorageTypeTemporary, "a)); - EXPECT_EQ(kQuota1 + 1024, quota); + void OriginLastAccessTimeLRU(const FilePath& kDbFile) { + QuotaDatabase db(kDbFile); + ASSERT_TRUE(db.LazyOpen(true)); + + std::set<GURL> exceptions; + GURL origin; + EXPECT_TRUE(db.GetLRUOrigin(kStorageTypeTemporary, exceptions, &origin)); + EXPECT_TRUE(origin.is_empty()); + + const GURL kOrigin1("http://a/"); + const GURL kOrigin2("http://b/"); + const GURL kOrigin3("http://c/"); + const GURL kOrigin4("http://p/"); + + // Adding three temporary storages, and + EXPECT_TRUE(db.SetOriginLastAccessTime( + kOrigin1, kStorageTypeTemporary, base::Time::FromInternalValue(10))); + EXPECT_TRUE(db.SetOriginLastAccessTime( + kOrigin2, kStorageTypeTemporary, base::Time::FromInternalValue(20))); + EXPECT_TRUE(db.SetOriginLastAccessTime( + kOrigin3, kStorageTypeTemporary, base::Time::FromInternalValue(30))); + + // one persistent. + EXPECT_TRUE(db.SetOriginLastAccessTime( + kOrigin4, kStorageTypePersistent, base::Time::FromInternalValue(40))); + + EXPECT_TRUE(db.GetLRUOrigin(kStorageTypeTemporary, exceptions, &origin)); + EXPECT_EQ(kOrigin1.spec(), origin.spec()); + + exceptions.insert(kOrigin1); + EXPECT_TRUE(db.GetLRUOrigin(kStorageTypeTemporary, exceptions, &origin)); + EXPECT_EQ(kOrigin2.spec(), origin.spec()); + + exceptions.insert(kOrigin2); + EXPECT_TRUE(db.GetLRUOrigin(kStorageTypeTemporary, exceptions, &origin)); + EXPECT_EQ(kOrigin3.spec(), origin.spec()); + + exceptions.insert(kOrigin3); + EXPECT_TRUE(db.GetLRUOrigin(kStorageTypeTemporary, exceptions, &origin)); + EXPECT_TRUE(origin.is_empty()); + + EXPECT_TRUE(db.SetOriginLastAccessTime( + kOrigin1, kStorageTypeTemporary, base::Time::Now())); + + // Delete origin/type last access time information. + EXPECT_TRUE(db.DeleteOriginLastAccessTime(kOrigin3, kStorageTypeTemporary)); + + // Querying again to see if the deletion has worked. + exceptions.clear(); + EXPECT_TRUE(db.GetLRUOrigin(kStorageTypeTemporary, exceptions, &origin)); + EXPECT_EQ(kOrigin2.spec(), origin.spec()); + + exceptions.insert(kOrigin1); + exceptions.insert(kOrigin2); + EXPECT_TRUE(db.GetLRUOrigin(kStorageTypeTemporary, exceptions, &origin)); + EXPECT_TRUE(origin.is_empty()); + } +}; - EXPECT_FALSE(db.GetGlobalQuota(kStorageTypePersistent, "a)); +TEST_F(QuotaDatabaseTest, LazyOpen) { + ScopedTempDir data_dir; + ASSERT_TRUE(data_dir.CreateUniqueTempDir()); + const FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db"); + LazyOpen(kDbFile); + LazyOpen(FilePath()); +} - EXPECT_TRUE(db.SetGlobalQuota(kStorageTypePersistent, kQuota2)); - EXPECT_TRUE(db.GetGlobalQuota(kStorageTypePersistent, "a)); - EXPECT_EQ(kQuota2, quota); +TEST_F(QuotaDatabaseTest, HostQuota) { + ScopedTempDir data_dir; + ASSERT_TRUE(data_dir.CreateUniqueTempDir()); + const FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db"); + HostQuota(kDbFile); + HostQuota(FilePath()); } -TEST(QuotaDatabaseTest, OriginLastAccessTimeLRU) { +TEST_F(QuotaDatabaseTest, GlobalQuota) { ScopedTempDir data_dir; ASSERT_TRUE(data_dir.CreateUniqueTempDir()); + const FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db"); + GlobalQuota(kDbFile); + GlobalQuota(FilePath()); +} +TEST_F(QuotaDatabaseTest, OriginLastAccessTimeLRU) { + ScopedTempDir data_dir; + ASSERT_TRUE(data_dir.CreateUniqueTempDir()); const FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db"); - QuotaDatabase db(kDbFile); - ASSERT_TRUE(db.LazyOpen(true)); - - std::set<GURL> exceptions; - GURL origin; - EXPECT_TRUE(db.GetLRUOrigin(kStorageTypeTemporary, exceptions, &origin)); - EXPECT_TRUE(origin.is_empty()); - - const GURL kOrigin1("http://a/"); - const GURL kOrigin2("http://b/"); - const GURL kOrigin3("http://c/"); - const GURL kOrigin4("http://p/"); - - // Adding three temporary storages, and - EXPECT_TRUE(db.SetOriginLastAccessTime( - kOrigin1, kStorageTypeTemporary, base::Time::FromInternalValue(10))); - EXPECT_TRUE(db.SetOriginLastAccessTime( - kOrigin2, kStorageTypeTemporary, base::Time::FromInternalValue(20))); - EXPECT_TRUE(db.SetOriginLastAccessTime( - kOrigin3, kStorageTypeTemporary, base::Time::FromInternalValue(30))); - - // one persistent. - EXPECT_TRUE(db.SetOriginLastAccessTime( - kOrigin4, kStorageTypePersistent, base::Time::FromInternalValue(40))); - - EXPECT_TRUE(db.GetLRUOrigin(kStorageTypeTemporary, exceptions, &origin)); - EXPECT_EQ(kOrigin1.spec(), origin.spec()); - - exceptions.insert(kOrigin1); - EXPECT_TRUE(db.GetLRUOrigin(kStorageTypeTemporary, exceptions, &origin)); - EXPECT_EQ(kOrigin2.spec(), origin.spec()); - - exceptions.insert(kOrigin2); - EXPECT_TRUE(db.GetLRUOrigin(kStorageTypeTemporary, exceptions, &origin)); - EXPECT_EQ(kOrigin3.spec(), origin.spec()); - - exceptions.insert(kOrigin3); - EXPECT_TRUE(db.GetLRUOrigin(kStorageTypeTemporary, exceptions, &origin)); - EXPECT_TRUE(origin.is_empty()); - - EXPECT_TRUE(db.SetOriginLastAccessTime( - kOrigin1, kStorageTypeTemporary, base::Time::Now())); - - // Delete origin/type last access time information. - EXPECT_TRUE(db.DeleteOriginLastAccessTime(kOrigin3, kStorageTypeTemporary)); - - // Querying again to see if the deletion has worked. - exceptions.clear(); - EXPECT_TRUE(db.GetLRUOrigin(kStorageTypeTemporary, exceptions, &origin)); - EXPECT_EQ(kOrigin2.spec(), origin.spec()); - - exceptions.insert(kOrigin1); - exceptions.insert(kOrigin2); - EXPECT_TRUE(db.GetLRUOrigin(kStorageTypeTemporary, exceptions, &origin)); - EXPECT_TRUE(origin.is_empty()); + OriginLastAccessTimeLRU(kDbFile); + OriginLastAccessTimeLRU(FilePath()); } } // namespace quota diff --git a/webkit/quota/quota_manager.cc b/webkit/quota/quota_manager.cc index 01f9c75..2782f6d 100644 --- a/webkit/quota/quota_manager.cc +++ b/webkit/quota/quota_manager.cc @@ -26,23 +26,28 @@ namespace { // 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) { +int64 GetInitialTemporaryStorageQuotaSize(const FilePath& path, + bool is_incognito) { int64 free_space = base::SysInfo::AmountOfFreeDiskSpace(path); + // 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) { + 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) { + 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) { + if (free_space < QuotaManager::kTemporaryStorageQuotaMaxSize * 20) return free_space / 20; - } + return QuotaManager::kTemporaryStorageQuotaMaxSize; } @@ -55,7 +60,7 @@ const int64 QuotaManager::kTemporaryStorageQuotaDefaultSize = 50 * MBytes; const int64 QuotaManager::kTemporaryStorageQuotaMaxSize = 1 * 1024 * MBytes; const char QuotaManager::kDatabaseName[] = "QuotaManager"; -const int64 QuotaManager::kIncognitoDefaultTemporaryQuota = 5 * MBytes; +const int64 QuotaManager::kIncognitoDefaultTemporaryQuota = 50 * MBytes; // This class is for posting GetUsage/GetQuota tasks, gathering // results and dispatching GetAndQuota callbacks. @@ -309,9 +314,11 @@ class QuotaManager::InitializeTask : public QuotaManager::DatabaseTaskBase { QuotaManager* manager, QuotaDatabase* database, scoped_refptr<base::MessageLoopProxy> db_message_loop, - const FilePath& profile_path) + const FilePath& profile_path, + bool is_incognito) : DatabaseTaskBase(manager, database, db_message_loop), profile_path_(profile_path), + is_incognito_(is_incognito), temporary_storage_quota_(-1) { } @@ -323,7 +330,7 @@ class QuotaManager::InitializeTask : public QuotaManager::DatabaseTaskBase { // 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_); + profile_path_, is_incognito_); if (!database()->SetGlobalQuota( kStorageTypeTemporary, temporary_storage_quota_)) { set_db_disabled(true); @@ -338,6 +345,7 @@ class QuotaManager::InitializeTask : public QuotaManager::DatabaseTaskBase { private: FilePath profile_path_; + bool is_incognito_; int64 temporary_storage_quota_; }; @@ -532,14 +540,6 @@ void QuotaManager::GetUsageAndQuota( GetUsageAndQuotaCallback* callback_ptr) { scoped_ptr<GetUsageAndQuotaCallback> callback(callback_ptr); LazyInitialize(); - if (is_incognito_) { - int64 quota = 0; - if (type == kStorageTypeTemporary) - quota = clients_.size() * kIncognitoDefaultTemporaryQuota; - // TODO(kinuko): This does not return useful usage value for now. - callback->Run(kQuotaStatusOk, 0, quota); - return; - } if (type == kStorageTypeUnknown) { // Quota only supports temporary/persistent types. @@ -641,10 +641,9 @@ void QuotaManager::LazyInitialize() { return; } - if (is_incognito_) - return; - - database_.reset(new QuotaDatabase(profile_path_.AppendASCII(kDatabaseName))); + // Use an empty path to open an in-memory only databse for incognito. + database_.reset(new QuotaDatabase(is_incognito_ ? FilePath() : + profile_path_.AppendASCII(kDatabaseName))); temporary_usage_tracker_.reset( new UsageTracker(clients_, kStorageTypeTemporary)); @@ -652,7 +651,8 @@ void QuotaManager::LazyInitialize() { new UsageTracker(clients_, kStorageTypePersistent)); scoped_refptr<InitializeTask> task( - new InitializeTask(this, database_.get(), db_thread_, profile_path_)); + new InitializeTask(this, database_.get(), db_thread_, + profile_path_, is_incognito_)); task->Start(); } @@ -672,9 +672,7 @@ void QuotaManager::NotifyStorageModified( QuotaClient::ID client_id, const GURL& origin, StorageType type, int64 delta) { LazyInitialize(); - UsageTracker* tracker = GetUsageTracker(type); - DCHECK(tracker); - tracker->UpdateUsageCache(client_id, origin, delta); + GetUsageTracker(type)->UpdateUsageCache(client_id, origin, delta); } void QuotaManager::NotifyOriginInUse(const GURL& origin) { |