diff options
author | michaeln@chromium.org <michaeln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-04 20:01:37 +0000 |
---|---|---|
committer | michaeln@chromium.org <michaeln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-04 20:01:37 +0000 |
commit | bae3069e31b61b1555f65272ec8973b2f4c56df5 (patch) | |
tree | 6edca4e598e62e1bbc87fc0a96ba99293d103686 /webkit/appcache | |
parent | 5fd7738372b76c4a1951e6b842e6387cd09d2521 (diff) | |
download | chromium_src-bae3069e31b61b1555f65272ec8973b2f4c56df5.zip chromium_src-bae3069e31b61b1555f65272ec8973b2f4c56df5.tar.gz chromium_src-bae3069e31b61b1555f65272ec8973b2f4c56df5.tar.bz2 |
AppCache: Provide a way to override the default quota for an origin. The intent is to use this to support the 'unlimited_storage' privilege of Chrome Applications.
BUG=49993
TEST=AppCacheStorageImplTest.FailStoreGroup
Review URL: http://codereview.chromium.org/3083014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@54949 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/appcache')
-rw-r--r-- | webkit/appcache/appcache_storage.cc | 19 | ||||
-rw-r--r-- | webkit/appcache/appcache_storage.h | 10 | ||||
-rw-r--r-- | webkit/appcache/appcache_storage_impl.cc | 12 | ||||
-rw-r--r-- | webkit/appcache/appcache_storage_impl_unittest.cc | 56 |
4 files changed, 92 insertions, 5 deletions
diff --git a/webkit/appcache/appcache_storage.cc b/webkit/appcache/appcache_storage.cc index 05b6269..52767ad 100644 --- a/webkit/appcache/appcache_storage.cc +++ b/webkit/appcache/appcache_storage.cc @@ -72,5 +72,24 @@ void AppCacheStorage::LoadResponseInfo( info_load->StartIfNeeded(); } +void AppCacheStorage::SetOriginQuotaInMemory(const GURL& origin, int64 quota) { + DCHECK(quota >= 0); + DCHECK(origin == origin.GetOrigin()); + in_memory_quotas_[origin] = quota; +} + +void AppCacheStorage::ResetOriginQuotaInMemory(const GURL& origin) { + DCHECK(origin == origin.GetOrigin()); + in_memory_quotas_.erase(origin); +} + +int64 AppCacheStorage::GetOriginQuotaInMemory(const GURL& origin) { + DCHECK(origin == origin.GetOrigin()); + QuotaMap::const_iterator found = in_memory_quotas_.find(origin); + if (found == in_memory_quotas_.end()) + return -1; + return found->second; +} + } // namespace appcache diff --git a/webkit/appcache/appcache_storage.h b/webkit/appcache/appcache_storage.h index 9b6596c..559237c 100644 --- a/webkit/appcache/appcache_storage.h +++ b/webkit/appcache/appcache_storage.h @@ -167,6 +167,11 @@ class AppCacheStorage { virtual void PurgeMemory() = 0; + // Maintain a collection of quota overrides in memory. + void SetOriginQuotaInMemory(const GURL& origin, int64 quota); + void ResetOriginQuotaInMemory(const GURL& origin); + int64 GetOriginQuotaInMemory(const GURL& origin); + // Generates unique storage ids for different object types. int64 NewCacheId() { return ++last_cache_id_; @@ -284,6 +289,11 @@ class AppCacheStorage { return ++last_response_id_; } + // Store quotas for extensions in memory, in order to prevent writing a row + // to quota_table_ every time an extention is loaded. + typedef std::map<GURL, int64> QuotaMap; + QuotaMap in_memory_quotas_; + // The last storage id used for different object types. int64 last_cache_id_; int64 last_group_id_; diff --git a/webkit/appcache/appcache_storage_impl.cc b/webkit/appcache/appcache_storage_impl.cc index c715863..2231234 100644 --- a/webkit/appcache/appcache_storage_impl.cc +++ b/webkit/appcache/appcache_storage_impl.cc @@ -402,13 +402,16 @@ class AppCacheStorageImpl::StoreGroupAndCacheTask : public StoreOrLoadTask { scoped_refptr<AppCache> cache_; bool success_; bool would_exceed_quota_; + int64 quota_override_; std::vector<int64> newly_deletable_response_ids_; }; AppCacheStorageImpl::StoreGroupAndCacheTask::StoreGroupAndCacheTask( AppCacheStorageImpl* storage, AppCacheGroup* group, AppCache* newest_cache) : StoreOrLoadTask(storage), group_(group), cache_(newest_cache), - success_(false), would_exceed_quota_(false) { + success_(false), would_exceed_quota_(false), + quota_override_( + storage->GetOriginQuotaInMemory(group->manifest_url().GetOrigin())) { group_record_.group_id = group->group_id(); group_record_.manifest_url = group->manifest_url(); group_record_.origin = group_record_.manifest_url.GetOrigin(); @@ -485,8 +488,11 @@ void AppCacheStorageImpl::StoreGroupAndCacheTask::Run() { if (!success_) return; - if (database_->GetOriginUsage(group_record_.origin) > - database_->GetOriginQuota(group_record_.origin)) { + int64 quota = (quota_override_ >= 0) ? + quota_override_ : + database_->GetOriginQuota(group_record_.origin); + + if (database_->GetOriginUsage(group_record_.origin) > quota) { would_exceed_quota_ = true; success_ = false; return; diff --git a/webkit/appcache/appcache_storage_impl_unittest.cc b/webkit/appcache/appcache_storage_impl_unittest.cc index 8367cf8..5fccade 100644 --- a/webkit/appcache/appcache_storage_impl_unittest.cc +++ b/webkit/appcache/appcache_storage_impl_unittest.cc @@ -73,8 +73,9 @@ class AppCacheStorageImplTest : public testing::Test { public: explicit MockStorageDelegate(AppCacheStorageImplTest* test) : loaded_cache_id_(0), stored_group_success_(false), - obsoleted_success_(false), found_cache_id_(kNoCacheId), - found_blocked_by_policy_(false), test_(test) { + would_exceed_quota_(false), obsoleted_success_(false), + found_cache_id_(kNoCacheId), found_blocked_by_policy_(false), + test_(test) { } void OnCacheLoaded(AppCache* cache, int64 cache_id) { @@ -96,6 +97,7 @@ class AppCacheStorageImplTest : public testing::Test { bool would_exceed_quota) { stored_group_ = group; stored_group_success_ = success; + would_exceed_quota_ = would_exceed_quota; test_->ScheduleNextTask(); } @@ -125,6 +127,7 @@ class AppCacheStorageImplTest : public testing::Test { scoped_refptr<AppCache> loaded_groups_newest_cache_; scoped_refptr<AppCacheGroup> stored_group_; bool stored_group_success_; + bool would_exceed_quota_; scoped_refptr<AppCacheGroup> obsoleted_group_; bool obsoleted_success_; GURL found_url_; @@ -532,6 +535,51 @@ class AppCacheStorageImplTest : public testing::Test { TestFinished(); } + // FailStoreGroup -------------------------------------- + + void FailStoreGroup() { + // Store a group and its newest cache. Should complete asyncly. + PushNextTask(NewRunnableMethod( + this, &AppCacheStorageImplTest::Verify_FailStoreGroup)); + + // Set a low quota to force a failure. + const GURL kOrigin(kManifestUrl.GetOrigin()); + EXPECT_EQ(-1L, storage()->GetOriginQuotaInMemory(kOrigin)); + storage()->SetOriginQuotaInMemory(kManifestUrl.GetOrigin(), 0); + EXPECT_EQ(0L, storage()->GetOriginQuotaInMemory(kOrigin)); + + // Setup some preconditions. Create a group and newest cache that + // appear to be "unstored". + group_ = new AppCacheGroup( + service(), kManifestUrl, storage()->NewGroupId()); + cache_ = new AppCache(service(), storage()->NewCacheId()); + cache_->AddEntry(kManifestUrl, + AppCacheEntry(AppCacheEntry::MANIFEST, 1, 1024)); + // Hold a ref to the cache simulate the UpdateJob holding that ref, + // and hold a ref to the group to simulate the CacheHost holding that ref. + + // Conduct the store test. + storage()->StoreGroupAndNewestCache(group_, cache_, delegate()); + EXPECT_FALSE(delegate()->stored_group_success_); // Expected to be async. + } + + void Verify_FailStoreGroup() { + EXPECT_FALSE(delegate()->stored_group_success_); + EXPECT_TRUE(delegate()->would_exceed_quota_); + + // Should not have been stored in the database. + AppCacheDatabase::GroupRecord group_record; + AppCacheDatabase::CacheRecord cache_record; + EXPECT_FALSE(database()->FindGroup(group_->group_id(), &group_record)); + EXPECT_FALSE(database()->FindCache(cache_->cache_id(), &cache_record)); + + const GURL kOrigin(kManifestUrl.GetOrigin()); + storage()->ResetOriginQuotaInMemory(kOrigin); + EXPECT_EQ(-1L, storage()->GetOriginQuotaInMemory(kOrigin)); + + TestFinished(); + } + // MakeGroupObsolete ------------------------------- void MakeGroupObsolete() { @@ -1006,6 +1054,10 @@ TEST_F(AppCacheStorageImplTest, StoreExistingGroupExistingCache) { RunTestOnIOThread(&AppCacheStorageImplTest::StoreExistingGroupExistingCache); } +TEST_F(AppCacheStorageImplTest, FailStoreGroup) { + RunTestOnIOThread(&AppCacheStorageImplTest::FailStoreGroup); +} + TEST_F(AppCacheStorageImplTest, MakeGroupObsolete) { RunTestOnIOThread(&AppCacheStorageImplTest::MakeGroupObsolete); } |