diff options
author | mkwst@chromium.org <mkwst@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-09 19:40:27 +0000 |
---|---|---|
committer | mkwst@chromium.org <mkwst@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-09 19:40:27 +0000 |
commit | 72f40864f540e393c941ceeea770d34f141c68d6 (patch) | |
tree | 3e40f159c9ec5977d968907b078bec713e21185e /webkit | |
parent | 138c6ec7f5ddaccb176a50e0cc4fbcfbadb34e45 (diff) | |
download | chromium_src-72f40864f540e393c941ceeea770d34f141c68d6.zip chromium_src-72f40864f540e393c941ceeea770d34f141c68d6.tar.gz chromium_src-72f40864f540e393c941ceeea770d34f141c68d6.tar.bz2 |
QuotaManager::DeleteOriginData allows deletion of specific QuotaClients
To enable a more fine-grained extension API that would allow removal of specific data types, this CL changes the QuotaClient::ID enum values to bitmasky flags, and adds a bitmask parameter to QuotaManager::DeleteOriginData and QuotaManager::DeleteHostData to filter the clients that are deleted for each origin.
BUG=94334
TEST=test_shell_tests,unit_tests
Review URL: http://codereview.chromium.org/7839029
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@121269 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r-- | webkit/quota/mock_quota_manager.cc | 39 | ||||
-rw-r--r-- | webkit/quota/mock_quota_manager.h | 26 | ||||
-rw-r--r-- | webkit/quota/mock_quota_manager_unittest.cc | 118 | ||||
-rw-r--r-- | webkit/quota/mock_storage_client.cc | 18 | ||||
-rw-r--r-- | webkit/quota/mock_storage_client.h | 11 | ||||
-rw-r--r-- | webkit/quota/quota_client.h | 16 | ||||
-rw-r--r-- | webkit/quota/quota_manager.cc | 40 | ||||
-rw-r--r-- | webkit/quota/quota_manager.h | 14 | ||||
-rw-r--r-- | webkit/quota/quota_manager_unittest.cc | 242 |
9 files changed, 430 insertions, 94 deletions
diff --git a/webkit/quota/mock_quota_manager.cc b/webkit/quota/mock_quota_manager.cc index 52d2735..bac3fcc 100644 --- a/webkit/quota/mock_quota_manager.cc +++ b/webkit/quota/mock_quota_manager.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -75,16 +75,20 @@ class MockQuotaManager::DeleteOriginDataTask : public QuotaThreadTask { MockQuotaManager::OriginInfo::OriginInfo( const GURL& origin, StorageType type, + int quota_client_mask, base::Time modified) : origin(origin), type(type), + quota_client_mask(quota_client_mask), modified(modified) { } MockQuotaManager::OriginInfo::~OriginInfo() {} -MockQuotaManager::MockQuotaManager(bool is_incognito, - const FilePath& profile_path, base::MessageLoopProxy* io_thread, +MockQuotaManager::MockQuotaManager( + bool is_incognito, + const FilePath& profile_path, + base::MessageLoopProxy* io_thread, base::MessageLoopProxy* db_thread, SpecialStoragePolicy* special_storage_policy) : QuotaManager(is_incognito, profile_path, io_thread, db_thread, @@ -93,18 +97,25 @@ MockQuotaManager::MockQuotaManager(bool is_incognito, MockQuotaManager::~MockQuotaManager() {} -bool MockQuotaManager::AddOrigin(const GURL& origin, StorageType type, +bool MockQuotaManager::AddOrigin( + const GURL& origin, + StorageType type, + int quota_client_mask, base::Time modified) { - origins_.push_back(OriginInfo(origin, type, modified)); + origins_.push_back(OriginInfo(origin, type, quota_client_mask, modified)); return true; } -bool MockQuotaManager::OriginHasData(const GURL& origin, - StorageType type) const { +bool MockQuotaManager::OriginHasData( + const GURL& origin, + StorageType type, + QuotaClient::ID quota_client) const { for (std::vector<OriginInfo>::const_iterator current = origins_.begin(); current != origins_.end(); ++current) { - if (current->origin == origin && current->type == type) + if (current->origin == origin && + current->type == type && + current->quota_client_mask & quota_client) return true; } return false; @@ -125,13 +136,19 @@ void MockQuotaManager::GetOriginsModifiedSince( callback))->Start(); } -void MockQuotaManager::DeleteOriginData(const GURL& origin, StorageType type, - const StatusCallback& callback) { +void MockQuotaManager::DeleteOriginData( + const GURL& origin, + StorageType type, + int quota_client_mask, + const StatusCallback& callback) { for (std::vector<OriginInfo>::iterator current = origins_.begin(); current != origins_.end(); ++current) { if (current->origin == origin && current->type == type) { - origins_.erase(current); + // Modify the mask: if it's 0 after "deletion", remove the origin. + current->quota_client_mask &= ~quota_client_mask; + if (current->quota_client_mask == 0) + origins_.erase(current); break; } } diff --git a/webkit/quota/mock_quota_manager.h b/webkit/quota/mock_quota_manager.h index 1f6fb0b..317c476 100644 --- a/webkit/quota/mock_quota_manager.h +++ b/webkit/quota/mock_quota_manager.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -31,11 +31,13 @@ class MockQuotaManager : public QuotaManager { struct OriginInfo { OriginInfo(const GURL& origin, StorageType type, + int quota_client_mask, base::Time modified); ~OriginInfo(); GURL origin; StorageType type; + int quota_client_mask; base::Time modified; }; @@ -48,13 +50,20 @@ class MockQuotaManager : public QuotaManager { virtual ~MockQuotaManager(); // Adds an origin to the canned list that will be searched through via - // GetOriginsModifiedSince. - bool AddOrigin(const GURL& origin, StorageType type, base::Time modified); + // GetOriginsModifiedSince. The caller must provide |quota_client_mask| + // which specifies the types of QuotaClients this canned origin contains + // as a bitmask built from QuotaClient::IDs. + bool AddOrigin(const GURL& origin, + StorageType type, + int quota_client_mask, + base::Time modified); // Checks an origin and type against the origins that have been added via // AddOrigin and removed via DeleteOriginData. If the origin exists in the - // canned list with the proper StorageType, returns true. - bool OriginHasData(const GURL& origin, StorageType type) const; + // canned list with the proper StorageType and client, returns true. + bool OriginHasData(const GURL& origin, + StorageType type, + QuotaClient::ID quota_client) const; // Overrides QuotaManager's implementation with a canned implementation that // allows clients to set up the origin database that should be queried. This @@ -65,9 +74,14 @@ class MockQuotaManager : public QuotaManager { const GetOriginsCallback& callback) OVERRIDE; // Removes an origin from the canned list of origins, but doesn't touch - // anything on disk. + // anything on disk. The caller must provide |quota_client_mask| which + // specifies the types of QuotaClients which should be removed from this + // origin as a bitmask built from QuotaClient::IDs. Setting the mask to + // QuotaClient::kAllClientsMask will remove all clients from the origin, + // regardless of type. virtual void DeleteOriginData(const GURL& origin, StorageType type, + int quota_client_mask, const StatusCallback& callback) OVERRIDE; private: diff --git a/webkit/quota/mock_quota_manager_unittest.cc b/webkit/quota/mock_quota_manager_unittest.cc index 5f1d1b6..30229af 100644 --- a/webkit/quota/mock_quota_manager_unittest.cc +++ b/webkit/quota/mock_quota_manager_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -26,6 +26,12 @@ const GURL kOrigin1(kTestOrigin1); const GURL kOrigin2(kTestOrigin2); const GURL kOrigin3(kTestOrigin3); +const StorageType kTemporary = kStorageTypeTemporary; +const StorageType kPersistent = kStorageTypePersistent; + +const QuotaClient::ID kClientFile = QuotaClient::kFileSystem; +const QuotaClient::ID kClientDB = QuotaClient::kIndexedDatabase; + class MockQuotaManagerTest : public testing::Test { public: MockQuotaManagerTest() @@ -62,9 +68,10 @@ class MockQuotaManagerTest : public testing::Test { type_ = type; } - void DeleteOriginData(const GURL& origin, StorageType type) { + void DeleteOriginData(const GURL& origin, StorageType type, + int quota_client_mask) { manager_->DeleteOriginData( - origin, type, + origin, type, quota_client_mask, base::Bind(&MockQuotaManagerTest::DeletedOriginData, weak_factory_.GetWeakPtr())); } @@ -105,40 +112,73 @@ class MockQuotaManagerTest : public testing::Test { }; TEST_F(MockQuotaManagerTest, BasicOriginManipulation) { - EXPECT_FALSE(manager()->OriginHasData(kOrigin1, kStorageTypeTemporary)); - EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kStorageTypeTemporary)); - EXPECT_FALSE(manager()->OriginHasData(kOrigin1, kStorageTypePersistent)); - EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kStorageTypePersistent)); - - manager()->AddOrigin(kOrigin1, kStorageTypeTemporary, base::Time::Now()); - EXPECT_TRUE(manager()->OriginHasData(kOrigin1, kStorageTypeTemporary)); - EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kStorageTypeTemporary)); - EXPECT_FALSE(manager()->OriginHasData(kOrigin1, kStorageTypePersistent)); - EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kStorageTypePersistent)); - - manager()->AddOrigin(kOrigin1, kStorageTypePersistent, base::Time::Now()); - EXPECT_TRUE(manager()->OriginHasData(kOrigin1, kStorageTypeTemporary)); - EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kStorageTypeTemporary)); - EXPECT_TRUE(manager()->OriginHasData(kOrigin1, kStorageTypePersistent)); - EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kStorageTypePersistent)); - - manager()->AddOrigin(kOrigin2, kStorageTypeTemporary, base::Time::Now()); - EXPECT_TRUE(manager()->OriginHasData(kOrigin1, kStorageTypeTemporary)); - EXPECT_TRUE(manager()->OriginHasData(kOrigin2, kStorageTypeTemporary)); - EXPECT_TRUE(manager()->OriginHasData(kOrigin1, kStorageTypePersistent)); - EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kStorageTypePersistent)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin1, kTemporary, kClientFile)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin1, kTemporary, kClientDB)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin1, kPersistent, kClientFile)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin1, kPersistent, kClientDB)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kTemporary, kClientFile)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kTemporary, kClientDB)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kPersistent, kClientFile)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kPersistent, kClientDB)); + + manager()->AddOrigin(kOrigin1, kTemporary, kClientFile, base::Time::Now()); + EXPECT_TRUE(manager()->OriginHasData(kOrigin1, kTemporary, kClientFile)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin1, kTemporary, kClientDB)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin1, kPersistent, kClientFile)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin1, kPersistent, kClientDB)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kTemporary, kClientFile)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kTemporary, kClientDB)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kPersistent, kClientFile)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kPersistent, kClientDB)); + + manager()->AddOrigin(kOrigin1, kPersistent, kClientFile, base::Time::Now()); + EXPECT_TRUE(manager()->OriginHasData(kOrigin1, kTemporary, kClientFile)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin1, kTemporary, kClientDB)); + EXPECT_TRUE(manager()->OriginHasData(kOrigin1, kPersistent, kClientFile)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin1, kPersistent, kClientDB)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kTemporary, kClientFile)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kTemporary, kClientDB)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kPersistent, kClientFile)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kPersistent, kClientDB)); + + manager()->AddOrigin(kOrigin2, kTemporary, kClientFile | kClientDB, + base::Time::Now()); + EXPECT_TRUE(manager()->OriginHasData(kOrigin1, kTemporary, kClientFile)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin1, kTemporary, kClientDB)); + EXPECT_TRUE(manager()->OriginHasData(kOrigin1, kPersistent, kClientFile)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin1, kPersistent, kClientDB)); + EXPECT_TRUE(manager()->OriginHasData(kOrigin2, kTemporary, kClientFile)); + EXPECT_TRUE(manager()->OriginHasData(kOrigin2, kTemporary, kClientDB)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kPersistent, kClientFile)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kPersistent, kClientDB)); } TEST_F(MockQuotaManagerTest, OriginDeletion) { - manager()->AddOrigin(kOrigin1, kStorageTypeTemporary, base::Time::Now()); - manager()->AddOrigin(kOrigin2, kStorageTypeTemporary, base::Time::Now()); + manager()->AddOrigin(kOrigin1, kTemporary, kClientFile, base::Time::Now()); + manager()->AddOrigin(kOrigin2, kTemporary, kClientFile | kClientDB, + base::Time::Now()); + manager()->AddOrigin(kOrigin3, kTemporary, kClientFile | kClientDB, + base::Time::Now()); - DeleteOriginData(kOrigin2, kStorageTypeTemporary); + DeleteOriginData(kOrigin2, kTemporary, kClientFile); MessageLoop::current()->RunAllPending(); EXPECT_EQ(1, deletion_callback_count()); - EXPECT_TRUE(manager()->OriginHasData(kOrigin1, kStorageTypeTemporary)); - EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kStorageTypeTemporary)); + EXPECT_TRUE(manager()->OriginHasData(kOrigin1, kTemporary, kClientFile)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kTemporary, kClientFile)); + EXPECT_TRUE(manager()->OriginHasData(kOrigin2, kTemporary, kClientDB)); + EXPECT_TRUE(manager()->OriginHasData(kOrigin3, kTemporary, kClientFile)); + EXPECT_TRUE(manager()->OriginHasData(kOrigin3, kTemporary, kClientDB)); + + DeleteOriginData(kOrigin3, kTemporary, kClientFile | kClientDB); + MessageLoop::current()->RunAllPending(); + + EXPECT_EQ(2, deletion_callback_count()); + EXPECT_TRUE(manager()->OriginHasData(kOrigin1, kTemporary, kClientFile)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kTemporary, kClientFile)); + EXPECT_TRUE(manager()->OriginHasData(kOrigin2, kTemporary, kClientDB)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin3, kTemporary, kClientFile)); + EXPECT_FALSE(manager()->OriginHasData(kOrigin3, kTemporary, kClientDB)); } TEST_F(MockQuotaManagerTest, ModifiedOrigins) { @@ -147,34 +187,34 @@ TEST_F(MockQuotaManagerTest, ModifiedOrigins) { base::TimeDelta an_hour = base::TimeDelta::FromMilliseconds(3600000); base::TimeDelta a_minute = base::TimeDelta::FromMilliseconds(60000); - GetModifiedOrigins(kStorageTypeTemporary, then); + GetModifiedOrigins(kTemporary, then); MessageLoop::current()->RunAllPending(); EXPECT_TRUE(origins().empty()); - manager()->AddOrigin(kOrigin1, kStorageTypeTemporary, now - an_hour); + manager()->AddOrigin(kOrigin1, kTemporary, kClientFile, now - an_hour); - GetModifiedOrigins(kStorageTypeTemporary, then); + GetModifiedOrigins(kTemporary, then); MessageLoop::current()->RunAllPending(); - EXPECT_EQ(kStorageTypeTemporary, type()); + EXPECT_EQ(kTemporary, type()); EXPECT_EQ(1UL, origins().size()); EXPECT_EQ(1UL, origins().count(kOrigin1)); EXPECT_EQ(0UL, origins().count(kOrigin2)); - manager()->AddOrigin(kOrigin2, kStorageTypeTemporary, now); + manager()->AddOrigin(kOrigin2, kTemporary, kClientFile, now); - GetModifiedOrigins(kStorageTypeTemporary, then); + GetModifiedOrigins(kTemporary, then); MessageLoop::current()->RunAllPending(); - EXPECT_EQ(kStorageTypeTemporary, type()); + EXPECT_EQ(kTemporary, type()); EXPECT_EQ(2UL, origins().size()); EXPECT_EQ(1UL, origins().count(kOrigin1)); EXPECT_EQ(1UL, origins().count(kOrigin2)); - GetModifiedOrigins(kStorageTypeTemporary, now - a_minute); + GetModifiedOrigins(kTemporary, now - a_minute); MessageLoop::current()->RunAllPending(); - EXPECT_EQ(kStorageTypeTemporary, type()); + EXPECT_EQ(kTemporary, type()); EXPECT_EQ(1UL, origins().size()); EXPECT_EQ(0UL, origins().count(kOrigin1)); EXPECT_EQ(1UL, origins().count(kOrigin2)); diff --git a/webkit/quota/mock_storage_client.cc b/webkit/quota/mock_storage_client.cc index 66ed587..6a07989 100644 --- a/webkit/quota/mock_storage_client.cc +++ b/webkit/quota/mock_storage_client.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -50,6 +50,22 @@ MockStorageClient::MockStorageClient( id_(MockStorageClientIDSequencer::GetInstance()->NextMockID()), mock_time_counter_(0), ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { + Populate(mock_data, mock_data_size); +} + +MockStorageClient::MockStorageClient( + QuotaManagerProxy* quota_manager_proxy, + const MockOriginData* mock_data, QuotaClient::ID id, size_t mock_data_size) + : quota_manager_proxy_(quota_manager_proxy), + id_(id), + mock_time_counter_(0), + ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { + Populate(mock_data, mock_data_size); +} + +void MockStorageClient::Populate( + const MockOriginData* mock_data, + size_t mock_data_size) { for (size_t i = 0; i < mock_data_size; ++i) { origin_data_[make_pair(GURL(mock_data[i].origin), mock_data[i].type)] = mock_data[i].usage; diff --git a/webkit/quota/mock_storage_client.h b/webkit/quota/mock_storage_client.h index 41abdaf..d6a7a46 100644 --- a/webkit/quota/mock_storage_client.h +++ b/webkit/quota/mock_storage_client.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -30,7 +30,12 @@ struct MockOriginData { class MockStorageClient : public QuotaClient { public: MockStorageClient(QuotaManagerProxy* quota_manager_proxy, - const MockOriginData* mock_data, size_t mock_data_size); + const MockOriginData* mock_data, + size_t mock_data_size); + MockStorageClient(QuotaManagerProxy* quota_manager_proxy, + const MockOriginData* mock_data, + QuotaClient::ID id, + size_t mock_data_size); virtual ~MockStorageClient(); // To add or modify mock data in this client. @@ -71,6 +76,8 @@ class MockStorageClient : public QuotaClient { StorageType type, const DeletionCallback& callback); + void Populate(const MockOriginData* mock_data, size_t mock_data_size); + scoped_refptr<QuotaManagerProxy> quota_manager_proxy_; const ID id_; diff --git a/webkit/quota/quota_client.h b/webkit/quota/quota_client.h index eb26c24..ab870c2 100644 --- a/webkit/quota/quota_client.h +++ b/webkit/quota/quota_client.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -30,14 +30,16 @@ class QuotaClient { virtual ~QuotaClient() {} enum ID { - kUnknown, - kFileSystem, - kDatabase, - kAppcache, - kIndexedDatabase, - kMockStart, // This needs to be the end of the enum. + kUnknown = 1 << 0, + kFileSystem = 1 << 1, + kDatabase = 1 << 2, + kAppcache = 1 << 3, + kIndexedDatabase = 1 << 4, + kMockStart = 1 << 5, // This needs to be the end of the enum. }; + static const int kAllClientsMask = -1; + virtual ID id() const = 0; // Called when the quota manager is destroyed. diff --git a/webkit/quota/quota_manager.cc b/webkit/quota/quota_manager.cc index dc2b27b..edc6ee6 100644 --- a/webkit/quota/quota_manager.cc +++ b/webkit/quota/quota_manager.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -461,12 +461,15 @@ class QuotaManager::OriginDataDeleter : public QuotaTask { OriginDataDeleter(QuotaManager* manager, const GURL& origin, StorageType type, + int quota_client_mask, const StatusCallback& callback) : QuotaTask(manager), origin_(origin), type_(type), + quota_client_mask_(quota_client_mask), error_count_(0), remaining_clients_(-1), + skipped_clients_(0), callback_(callback), weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {} @@ -476,16 +479,24 @@ class QuotaManager::OriginDataDeleter : public QuotaTask { remaining_clients_ = manager()->clients_.size(); for (QuotaClientList::iterator iter = manager()->clients_.begin(); iter != manager()->clients_.end(); ++iter) { - (*iter)->DeleteOriginData( - origin_, type_, - base::Bind(&OriginDataDeleter::DidDeleteOriginData, - weak_factory_.GetWeakPtr())); + if (quota_client_mask_ & (*iter)->id()) { + (*iter)->DeleteOriginData( + origin_, type_, + base::Bind(&OriginDataDeleter::DidDeleteOriginData, + weak_factory_.GetWeakPtr())); + } else { + ++skipped_clients_; + if (--remaining_clients_ == 0) + CallCompleted(); + } } } virtual void Completed() OVERRIDE { if (error_count_ == 0) { - manager()->DeleteOriginFromDatabase(origin_, type_); + // Only remove the entire origin if we didn't skip any client types. + if (skipped_clients_ == 0) + manager()->DeleteOriginFromDatabase(origin_, type_); callback_.Run(kQuotaStatusOk); } else { callback_.Run(kQuotaErrorInvalidModification); @@ -514,8 +525,10 @@ class QuotaManager::OriginDataDeleter : public QuotaTask { GURL origin_; StorageType type_; + int quota_client_mask_; int error_count_; int remaining_clients_; + int skipped_clients_; StatusCallback callback_; base::WeakPtrFactory<OriginDataDeleter> weak_factory_; @@ -527,10 +540,12 @@ class QuotaManager::HostDataDeleter : public QuotaTask { HostDataDeleter(QuotaManager* manager, const std::string& host, StorageType type, + int quota_client_mask, const StatusCallback& callback) : QuotaTask(manager), host_(host), type_(type), + quota_client_mask_(quota_client_mask), error_count_(0), remaining_clients_(-1), remaining_deleters_(-1), @@ -584,7 +599,7 @@ class QuotaManager::HostDataDeleter : public QuotaTask { ++p) { OriginDataDeleter* deleter = new OriginDataDeleter( - manager(), *p, type_, + manager(), *p, type_, quota_client_mask_, base::Bind(&HostDataDeleter::DidDeleteOriginData, weak_factory_.GetWeakPtr())); deleter->Start(); @@ -607,6 +622,7 @@ class QuotaManager::HostDataDeleter : public QuotaTask { std::string host_; StorageType type_; + int quota_client_mask_; std::set<GURL> origins_; int error_count_; int remaining_clients_; @@ -1313,7 +1329,8 @@ void QuotaManager::NotifyOriginNoLongerInUse(const GURL& origin) { } void QuotaManager::DeleteOriginData( - const GURL& origin, StorageType type, const StatusCallback& callback) { + const GURL& origin, StorageType type, int quota_client_mask, + const StatusCallback& callback) { LazyInitialize(); if (origin.is_empty() || clients_.empty()) { @@ -1322,12 +1339,13 @@ void QuotaManager::DeleteOriginData( } OriginDataDeleter* deleter = - new OriginDataDeleter(this, origin, type, callback); + new OriginDataDeleter(this, origin, type, quota_client_mask, callback); deleter->Start(); } void QuotaManager::DeleteHostData(const std::string& host, StorageType type, + int quota_client_mask, const StatusCallback& callback) { LazyInitialize(); @@ -1338,7 +1356,7 @@ void QuotaManager::DeleteHostData(const std::string& host, } HostDataDeleter* deleter = - new HostDataDeleter(this, host, type, callback); + new HostDataDeleter(this, host, type, quota_client_mask, callback); deleter->Start(); } @@ -1527,7 +1545,7 @@ void QuotaManager::EvictOriginData( eviction_context_.evicted_type = type; eviction_context_.evict_origin_data_callback = callback; - DeleteOriginData(origin, type, + DeleteOriginData(origin, type, QuotaClient::kAllClientsMask, base::Bind(&QuotaManager::DidOriginDataEvicted, weak_factory_.GetWeakPtr())); } diff --git a/webkit/quota/quota_manager.h b/webkit/quota/quota_manager.h index 70254c0..51d3a10 100644 --- a/webkit/quota/quota_manager.h +++ b/webkit/quota/quota_manager.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -148,12 +148,22 @@ class QuotaManager : public QuotaTaskObserver, return origins_in_use_.find(origin) != origins_in_use_.end(); } - // Called by UI. + // DeleteOriginData and DeleteHostData (surprisingly enough) delete data of a + // particular StorageType associated with either a specific origin or set of + // origins. Each method additionally requires a |quota_client_mask| which + // specifies the types of QuotaClients to delete from the origin. This is + // specified by the caller as a bitmask built from QuotaClient::IDs. Setting + // the mask to QuotaClient::kAllClientsMask will remove all clients from the + // origin, regardless of type. + // + // Both methods must be called on the UI thread. virtual void DeleteOriginData(const GURL& origin, StorageType type, + int quota_client_mask, const StatusCallback& callback); void DeleteHostData(const std::string& host, StorageType type, + int quota_client_mask, const StatusCallback& callback); // Called by UI and internal modules. diff --git a/webkit/quota/quota_manager_unittest.cc b/webkit/quota/quota_manager_unittest.cc index 54f74dd..949e6ab 100644 --- a/webkit/quota/quota_manager_unittest.cc +++ b/webkit/quota/quota_manager_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -31,6 +31,8 @@ namespace quota { const StorageType kTemp = kStorageTypeTemporary; const StorageType kPerm = kStorageTypePersistent; +const int kAllClients = QuotaClient::kAllClientsMask; + class QuotaManagerTest : public testing::Test { protected: typedef QuotaManager::QuotaTableEntry QuotaTableEntry; @@ -69,6 +71,13 @@ class QuotaManagerTest : public testing::Test { return new MockStorageClient(quota_manager_->proxy(), mock_data, mock_data_size); } + MockStorageClient* CreateClient( + const MockOriginData* mock_data, + size_t mock_data_size, + QuotaClient::ID id) { + return new MockStorageClient(quota_manager_->proxy(), + mock_data, id, mock_data_size); + } void RegisterClient(MockStorageClient* client) { quota_manager_->proxy()->RegisterClient(client); @@ -178,19 +187,21 @@ class QuotaManagerTest : public testing::Test { } void DeleteOriginData(const GURL& origin, - StorageType type) { + StorageType type, + int quota_client_mask) { quota_status_ = kQuotaStatusUnknown; quota_manager_->DeleteOriginData( - origin, type, + origin, type, quota_client_mask, base::Bind(&QuotaManagerTest::StatusCallback, weak_factory_.GetWeakPtr())); } void DeleteHostData(const std::string& host, - StorageType type) { + StorageType type, + int quota_client_mask) { quota_status_ = kQuotaStatusUnknown; quota_manager_->DeleteHostData( - host, type, + host, type, quota_client_mask, base::Bind(&QuotaManagerTest::StatusCallback, weak_factory_.GetWeakPtr())); } @@ -724,8 +735,8 @@ TEST_F(QuotaManagerTest, GetTemporaryUsageAndQuota_NukeManager) { RunAdditionalUsageAndQuotaTask(GURL("http://bar.com/"), kTemp); - DeleteOriginData(GURL("http://foo.com/"), kTemp); - DeleteOriginData(GURL("http://bar.com/"), kTemp); + DeleteOriginData(GURL("http://foo.com/"), kTemp, kAllClients); + DeleteOriginData(GURL("http://bar.com/"), kTemp, kAllClients); // Nuke before waiting for callbacks. set_quota_manager(NULL); @@ -1319,7 +1330,7 @@ TEST_F(QuotaManagerTest, DeleteHostDataSimple) { MessageLoop::current()->RunAllPending(); int64 predelete_host_pers = usage(); - DeleteHostData("", kTemp); + DeleteHostData("", kTemp, kAllClients); MessageLoop::current()->RunAllPending(); EXPECT_EQ(kQuotaStatusOk, status()); @@ -1335,7 +1346,7 @@ TEST_F(QuotaManagerTest, DeleteHostDataSimple) { MessageLoop::current()->RunAllPending(); EXPECT_EQ(predelete_host_pers, usage()); - DeleteHostData("foo.com", kTemp); + DeleteHostData("foo.com", kTemp, kAllClients); MessageLoop::current()->RunAllPending(); EXPECT_EQ(kQuotaStatusOk, status()); @@ -1392,9 +1403,9 @@ TEST_F(QuotaManagerTest, DeleteHostDataMultiple) { const int64 predelete_bar_pers = usage(); reset_status_callback_count(); - DeleteHostData("foo.com", kTemp); - DeleteHostData("bar.com", kTemp); - DeleteHostData("foo.com", kTemp); + DeleteHostData("foo.com", kTemp, kAllClients); + DeleteHostData("bar.com", kTemp, kAllClients); + DeleteHostData("foo.com", kTemp, kAllClients); MessageLoop::current()->RunAllPending(); EXPECT_EQ(3, status_callback_count()); @@ -1486,9 +1497,9 @@ TEST_F(QuotaManagerTest, DeleteOriginDataMultiple) { MessageLoop::current()->RunAllPending(); reset_status_callback_count(); - DeleteOriginData(GURL("http://foo.com/"), kTemp); - DeleteOriginData(GURL("http://bar.com/"), kTemp); - DeleteOriginData(GURL("http://foo.com/"), kTemp); + DeleteOriginData(GURL("http://foo.com/"), kTemp, kAllClients); + DeleteOriginData(GURL("http://bar.com/"), kTemp, kAllClients); + DeleteOriginData(GURL("http://foo.com/"), kTemp, kAllClients); MessageLoop::current()->RunAllPending(); EXPECT_EQ(3, status_callback_count()); @@ -1796,4 +1807,205 @@ TEST_F(QuotaManagerTest, QuotaForEmptyHost) { MessageLoop::current()->RunAllPending(); EXPECT_EQ(kQuotaErrorNotSupported, status()); } + +TEST_F(QuotaManagerTest, DeleteSpecificClientTypeSingleOrigin) { + static const MockOriginData kData1[] = { + { "http://foo.com/", kTemp, 1 }, + }; + static const MockOriginData kData2[] = { + { "http://foo.com/", kTemp, 2 }, + }; + static const MockOriginData kData3[] = { + { "http://foo.com/", kTemp, 4 }, + }; + static const MockOriginData kData4[] = { + { "http://foo.com/", kTemp, 8 }, + }; + MockStorageClient* client1 = CreateClient(kData1, ARRAYSIZE_UNSAFE(kData1), + QuotaClient::kFileSystem); + MockStorageClient* client2 = CreateClient(kData2, ARRAYSIZE_UNSAFE(kData2), + QuotaClient::kAppcache); + MockStorageClient* client3 = CreateClient(kData3, ARRAYSIZE_UNSAFE(kData3), + QuotaClient::kDatabase); + MockStorageClient* client4 = CreateClient(kData4, ARRAYSIZE_UNSAFE(kData4), + QuotaClient::kIndexedDatabase); + RegisterClient(client1); + RegisterClient(client2); + RegisterClient(client3); + RegisterClient(client4); + + GetHostUsage("foo.com", kTemp); + MessageLoop::current()->RunAllPending(); + const int64 predelete_foo_tmp = usage(); + + DeleteOriginData(GURL("http://foo.com/"), kTemp, QuotaClient::kFileSystem); + MessageLoop::current()->RunAllPending(); + GetHostUsage("foo.com", kTemp); + MessageLoop::current()->RunAllPending(); + EXPECT_EQ(predelete_foo_tmp - 1, usage()); + + DeleteOriginData(GURL("http://foo.com/"), kTemp, QuotaClient::kAppcache); + MessageLoop::current()->RunAllPending(); + GetHostUsage("foo.com", kTemp); + MessageLoop::current()->RunAllPending(); + EXPECT_EQ(predelete_foo_tmp - 2 - 1, usage()); + + DeleteOriginData(GURL("http://foo.com/"), kTemp, QuotaClient::kDatabase); + MessageLoop::current()->RunAllPending(); + GetHostUsage("foo.com", kTemp); + MessageLoop::current()->RunAllPending(); + EXPECT_EQ(predelete_foo_tmp - 4 - 2 - 1, usage()); + + DeleteOriginData(GURL("http://foo.com/"), kTemp, + QuotaClient::kIndexedDatabase); + MessageLoop::current()->RunAllPending(); + GetHostUsage("foo.com", kTemp); + MessageLoop::current()->RunAllPending(); + EXPECT_EQ(predelete_foo_tmp - 8 - 4 - 2 - 1, usage()); +} + +TEST_F(QuotaManagerTest, DeleteSpecificClientTypeSingleHost) { + static const MockOriginData kData1[] = { + { "http://foo.com:1111/", kTemp, 1 }, + }; + static const MockOriginData kData2[] = { + { "http://foo.com:2222/", kTemp, 2 }, + }; + static const MockOriginData kData3[] = { + { "http://foo.com:3333/", kTemp, 4 }, + }; + static const MockOriginData kData4[] = { + { "http://foo.com:4444/", kTemp, 8 }, + }; + MockStorageClient* client1 = CreateClient(kData1, ARRAYSIZE_UNSAFE(kData1), + QuotaClient::kFileSystem); + MockStorageClient* client2 = CreateClient(kData2, ARRAYSIZE_UNSAFE(kData2), + QuotaClient::kAppcache); + MockStorageClient* client3 = CreateClient(kData3, ARRAYSIZE_UNSAFE(kData3), + QuotaClient::kDatabase); + MockStorageClient* client4 = CreateClient(kData4, ARRAYSIZE_UNSAFE(kData4), + QuotaClient::kIndexedDatabase); + RegisterClient(client1); + RegisterClient(client2); + RegisterClient(client3); + RegisterClient(client4); + + GetHostUsage("foo.com", kTemp); + MessageLoop::current()->RunAllPending(); + const int64 predelete_foo_tmp = usage(); + + DeleteHostData("foo.com", kTemp, QuotaClient::kFileSystem); + MessageLoop::current()->RunAllPending(); + GetHostUsage("foo.com", kTemp); + MessageLoop::current()->RunAllPending(); + EXPECT_EQ(predelete_foo_tmp - 1, usage()); + + DeleteHostData("foo.com", kTemp, QuotaClient::kAppcache); + MessageLoop::current()->RunAllPending(); + GetHostUsage("foo.com", kTemp); + MessageLoop::current()->RunAllPending(); + EXPECT_EQ(predelete_foo_tmp - 2 - 1, usage()); + + DeleteHostData("foo.com", kTemp, QuotaClient::kDatabase); + MessageLoop::current()->RunAllPending(); + GetHostUsage("foo.com", kTemp); + MessageLoop::current()->RunAllPending(); + EXPECT_EQ(predelete_foo_tmp - 4 - 2 - 1, usage()); + + DeleteHostData("foo.com", kTemp, QuotaClient::kIndexedDatabase); + MessageLoop::current()->RunAllPending(); + GetHostUsage("foo.com", kTemp); + MessageLoop::current()->RunAllPending(); + EXPECT_EQ(predelete_foo_tmp - 8 - 4 - 2 - 1, usage()); +} + +TEST_F(QuotaManagerTest, DeleteMultipleClientTypesSingleOrigin) { + static const MockOriginData kData1[] = { + { "http://foo.com/", kTemp, 1 }, + }; + static const MockOriginData kData2[] = { + { "http://foo.com/", kTemp, 2 }, + }; + static const MockOriginData kData3[] = { + { "http://foo.com/", kTemp, 4 }, + }; + static const MockOriginData kData4[] = { + { "http://foo.com/", kTemp, 8 }, + }; + MockStorageClient* client1 = CreateClient(kData1, ARRAYSIZE_UNSAFE(kData1), + QuotaClient::kFileSystem); + MockStorageClient* client2 = CreateClient(kData2, ARRAYSIZE_UNSAFE(kData2), + QuotaClient::kAppcache); + MockStorageClient* client3 = CreateClient(kData3, ARRAYSIZE_UNSAFE(kData3), + QuotaClient::kDatabase); + MockStorageClient* client4 = CreateClient(kData4, ARRAYSIZE_UNSAFE(kData4), + QuotaClient::kIndexedDatabase); + RegisterClient(client1); + RegisterClient(client2); + RegisterClient(client3); + RegisterClient(client4); + + GetHostUsage("foo.com", kTemp); + MessageLoop::current()->RunAllPending(); + const int64 predelete_foo_tmp = usage(); + + DeleteOriginData(GURL("http://foo.com/"), kTemp, + QuotaClient::kFileSystem | QuotaClient::kDatabase); + MessageLoop::current()->RunAllPending(); + GetHostUsage("foo.com", kTemp); + MessageLoop::current()->RunAllPending(); + EXPECT_EQ(predelete_foo_tmp - 4 - 1, usage()); + + DeleteOriginData(GURL("http://foo.com/"), kTemp, + QuotaClient::kAppcache | QuotaClient::kIndexedDatabase); + MessageLoop::current()->RunAllPending(); + GetHostUsage("foo.com", kTemp); + MessageLoop::current()->RunAllPending(); + EXPECT_EQ(predelete_foo_tmp - 8 - 4 - 2 - 1, usage()); +} + +TEST_F(QuotaManagerTest, DeleteMultipleClientTypesSingleHost) { + static const MockOriginData kData1[] = { + { "http://foo.com:1111/", kTemp, 1 }, + }; + static const MockOriginData kData2[] = { + { "http://foo.com:2222/", kTemp, 2 }, + }; + static const MockOriginData kData3[] = { + { "http://foo.com:3333/", kTemp, 4 }, + }; + static const MockOriginData kData4[] = { + { "http://foo.com:4444/", kTemp, 8 }, + }; + MockStorageClient* client1 = CreateClient(kData1, ARRAYSIZE_UNSAFE(kData1), + QuotaClient::kFileSystem); + MockStorageClient* client2 = CreateClient(kData2, ARRAYSIZE_UNSAFE(kData2), + QuotaClient::kAppcache); + MockStorageClient* client3 = CreateClient(kData3, ARRAYSIZE_UNSAFE(kData3), + QuotaClient::kDatabase); + MockStorageClient* client4 = CreateClient(kData4, ARRAYSIZE_UNSAFE(kData4), + QuotaClient::kIndexedDatabase); + RegisterClient(client1); + RegisterClient(client2); + RegisterClient(client3); + RegisterClient(client4); + + GetHostUsage("foo.com", kTemp); + MessageLoop::current()->RunAllPending(); + const int64 predelete_foo_tmp = usage(); + + DeleteHostData("foo.com", kTemp, + QuotaClient::kFileSystem | QuotaClient::kAppcache); + MessageLoop::current()->RunAllPending(); + GetHostUsage("foo.com", kTemp); + MessageLoop::current()->RunAllPending(); + EXPECT_EQ(predelete_foo_tmp - 2 - 1, usage()); + + DeleteHostData("foo.com", kTemp, + QuotaClient::kDatabase | QuotaClient::kIndexedDatabase); + MessageLoop::current()->RunAllPending(); + GetHostUsage("foo.com", kTemp); + MessageLoop::current()->RunAllPending(); + EXPECT_EQ(predelete_foo_tmp - 8 - 4 - 2 - 1, usage()); +} } // namespace quota |