diff options
author | lazyboy@chromium.org <lazyboy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-25 03:22:20 +0000 |
---|---|---|
committer | lazyboy@chromium.org <lazyboy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-25 03:22:20 +0000 |
commit | a34addf5a368f78c2f3957a369c89af78d144c7e (patch) | |
tree | 200a2ce05ced83c334a60faa8a443f48f4f26034 /content | |
parent | 98c19886b3d01f3adeded3c4d4297e404cc0b934 (diff) | |
download | chromium_src-a34addf5a368f78c2f3957a369c89af78d144c7e.zip chromium_src-a34addf5a368f78c2f3957a369c89af78d144c7e.tar.gz chromium_src-a34addf5a368f78c2f3957a369c89af78d144c7e.tar.bz2 |
Add support for selectively deleting different bits of StoragePartition related data.
This CL makes the deletion work similar to BrowsingDataRemover in chrome/.
This CL is a result of the discussion in crrev.com/16188005
BUG=180118
Test=built: libwebviewchromium, manually tested with browser plugin guest's storage partition, checked clearing cookies and local storage data.
Review URL: https://chromiumcodereview.appspot.com/17701002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@213582 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r-- | content/browser/storage_partition_impl.cc | 505 | ||||
-rw-r--r-- | content/browser/storage_partition_impl.h | 35 | ||||
-rw-r--r-- | content/browser/storage_partition_impl_map.cc | 4 | ||||
-rw-r--r-- | content/browser/storage_partition_impl_unittest.cc | 6 | ||||
-rw-r--r-- | content/public/browser/storage_partition.h | 65 |
5 files changed, 454 insertions, 161 deletions
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc index ec092d2..a5e1aa1 100644 --- a/content/browser/storage_partition_impl.cc +++ b/content/browser/storage_partition_impl.cc @@ -26,132 +26,233 @@ namespace content { namespace { -void DoNothingStatusCallback(quota::QuotaStatusCode status) { - // Do nothing. +int GenerateQuotaClientMask(uint32 remove_mask) { + int quota_client_mask = 0; + + if (remove_mask & StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS) + quota_client_mask |= quota::QuotaClient::kFileSystem; + if (remove_mask & StoragePartition::REMOVE_DATA_MASK_WEBSQL) + quota_client_mask |= quota::QuotaClient::kDatabase; + if (remove_mask & StoragePartition::REMOVE_DATA_MASK_APPCACHE) + quota_client_mask |= quota::QuotaClient::kAppcache; + if (remove_mask & StoragePartition::REMOVE_DATA_MASK_INDEXEDDB) + quota_client_mask |= quota::QuotaClient::kIndexedDatabase; + + return quota_client_mask; } -void ClearQuotaManagedOriginsOnIOThread( - const scoped_refptr<quota::QuotaManager>& quota_manager, - const std::set<GURL>& origins, - quota::StorageType quota_storage_type) { - // The QuotaManager manages all storage other than cookies, LocalStorage, - // and SessionStorage. This loop wipes out most HTML5 storage for the given - // origins. - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - std::set<GURL>::const_iterator origin; - for (std::set<GURL>::const_iterator origin = origins.begin(); - origin != origins.end(); ++origin) { - quota_manager->DeleteOriginData(*origin, quota_storage_type, - quota::QuotaClient::kAllClientsMask, - base::Bind(&DoNothingStatusCallback)); +void OnClearedCookies(const base::Closure& callback, int num_deleted) { + // The final callback needs to happen from UI thread. + if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&OnClearedCookies, callback, num_deleted)); + return; } + + callback.Run(); } -void ClearOriginOnIOThread( - uint32 storage_mask, - const GURL& storage_origin, - const scoped_refptr<net::URLRequestContextGetter>& request_context, - const scoped_refptr<quota::QuotaManager>& quota_manager) { +void ClearCookiesOnIOThread( + const scoped_refptr<net::URLRequestContextGetter>& rq_context, + const base::Time begin, + const base::Time end, + const base::Closure& callback) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + net::CookieStore* cookie_store = rq_context-> + GetURLRequestContext()->cookie_store(); + cookie_store->DeleteAllCreatedBetweenAsync(begin, end, + base::Bind(&OnClearedCookies, callback)); +} - if (storage_mask & StoragePartition::kCookies) { - // Handle the cookies. - net::CookieMonster* cookie_monster = - request_context->GetURLRequestContext()->cookie_store()-> - GetCookieMonster(); - if (cookie_monster) - cookie_monster->DeleteAllForHostAsync( - storage_origin, net::CookieMonster::DeleteCallback()); +void OnQuotaManagedOriginDeleted(const GURL& origin, + quota::StorageType type, + size_t* origins_to_delete_count, + const base::Closure& callback, + quota::QuotaStatusCode status) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + DCHECK_GT(*origins_to_delete_count, 0u); + if (status != quota::kQuotaStatusOk) { + DLOG(ERROR) << "Couldn't remove data of type " << type << " for origin " + << origin << ". Status: " << status; } - // Handle all HTML5 storage other than DOMStorageContext. - std::set<GURL> origins; - origins.insert(storage_origin); - if (storage_mask & StoragePartition::kQuotaManagedTemporaryStorage) { - ClearQuotaManagedOriginsOnIOThread(quota_manager, - origins, - quota::kStorageTypeTemporary); - } - if (storage_mask & StoragePartition::kQuotaManagedPersistentStorage) { - ClearQuotaManagedOriginsOnIOThread(quota_manager, - origins, - quota::kStorageTypePersistent); - } - if (storage_mask & StoragePartition::kQuotaManagedSyncableStorage) { - ClearQuotaManagedOriginsOnIOThread(quota_manager, - origins, - quota::kStorageTypeSyncable); + (*origins_to_delete_count)--; + if (*origins_to_delete_count == 0) { + delete origins_to_delete_count; + callback.Run(); } } -void ClearAllDataOnIOThread( - uint32 storage_mask, - const scoped_refptr<net::URLRequestContextGetter>& request_context, - const scoped_refptr<quota::QuotaManager>& quota_manager) { +void ClearQuotaManagedOriginsOnIOThread(quota::QuotaManager* quota_manager, + uint32 remove_mask, + const base::Closure& callback, + const std::set<GURL>& origins, + quota::StorageType quota_storage_type) { + // The QuotaManager manages all storage other than cookies, LocalStorage, + // and SessionStorage. This loop wipes out most HTML5 storage for the given + // origins. DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - if (storage_mask & StoragePartition::kCookies) { - // Handle the cookies. - net::CookieMonster* cookie_monster = - request_context->GetURLRequestContext()->cookie_store()-> - GetCookieMonster(); - if (cookie_monster) - cookie_monster->DeleteAllAsync(net::CookieMonster::DeleteCallback()); + if (!origins.size()) { + // No origins to clear. + callback.Run(); + return; } - // Handle all HTML5 storage other than DOMStorageContext. - if (storage_mask & StoragePartition::kQuotaManagedTemporaryStorage) { - quota_manager->GetOriginsModifiedSince( - quota::kStorageTypeTemporary, base::Time(), - base::Bind(&ClearQuotaManagedOriginsOnIOThread, quota_manager)); - } - if (storage_mask & StoragePartition::kQuotaManagedPersistentStorage) { - quota_manager->GetOriginsModifiedSince( - quota::kStorageTypePersistent, base::Time(), - base::Bind(&ClearQuotaManagedOriginsOnIOThread, quota_manager)); - } - if (storage_mask & StoragePartition::kQuotaManagedSyncableStorage) { - quota_manager->GetOriginsModifiedSince( - quota::kStorageTypeSyncable, base::Time(), - base::Bind(&ClearQuotaManagedOriginsOnIOThread, quota_manager)); + std::set<GURL>::const_iterator origin; + size_t* origins_to_delete_count = new size_t(origins.size()); + for (std::set<GURL>::const_iterator origin = origins.begin(); + origin != origins.end(); ++origin) { + quota_manager->DeleteOriginData( + *origin, quota_storage_type, + GenerateQuotaClientMask(remove_mask), + base::Bind(&OnQuotaManagedOriginDeleted, + origin->GetOrigin(), quota_storage_type, + origins_to_delete_count, callback)); } } -void ClearedShaderCacheOnIOThread(base::Closure callback) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback); -} - -void ClearShaderCacheOnIOThread(base::FilePath path, - base::Time begin, base::Time end, base::Closure callback) { +void ClearShaderCacheOnIOThread(const base::FilePath& path, + const base::Time begin, + const base::Time end, + const base::Closure& callback) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - ShaderCacheFactory::GetInstance()->ClearByPath( - path, begin, end, - base::Bind(&ClearedShaderCacheOnIOThread, callback)); + ShaderCacheFactory::GetInstance()->ClearByPath(path, begin, end, callback); } void OnLocalStorageUsageInfo( const scoped_refptr<DOMStorageContextImpl>& dom_storage_context, + const base::Time delete_begin, + const base::Time delete_end, + const base::Closure& callback, const std::vector<dom_storage::LocalStorageUsageInfo>& infos) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); for (size_t i = 0; i < infos.size(); ++i) { - dom_storage_context->DeleteLocalStorage(infos[i].origin); + if (infos[i].last_modified >= delete_begin && + infos[i].last_modified <= delete_end) { + dom_storage_context->DeleteLocalStorage(infos[i].origin); + } } + callback.Run(); } void OnSessionStorageUsageInfo( const scoped_refptr<DOMStorageContextImpl>& dom_storage_context, + const base::Closure& callback, const std::vector<dom_storage::SessionStorageUsageInfo>& infos) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - for (size_t i = 0; i < infos.size(); ++i) { + for (size_t i = 0; i < infos.size(); ++i) dom_storage_context->DeleteSessionStorage(infos[i]); + + callback.Run(); +} + +void ClearLocalStorageOnUIThread( + const scoped_refptr<DOMStorageContextImpl>& dom_storage_context, + const GURL& remove_origin, + const base::Time begin, + const base::Time end, + const base::Closure& callback) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + if (!remove_origin.is_empty()) { + dom_storage_context->DeleteLocalStorage(remove_origin); + callback.Run(); + return; } + + dom_storage_context->GetLocalStorageUsage( + base::Bind(&OnLocalStorageUsageInfo, + dom_storage_context, begin, end, callback)); +} + +void ClearSessionStorageOnUIThread( + const scoped_refptr<DOMStorageContextImpl>& dom_storage_context, + const base::Closure& callback) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + dom_storage_context->GetSessionStorageUsage( + base::Bind(&OnSessionStorageUsageInfo, dom_storage_context, callback)); } } // namespace +// Helper for deleting quota managed data from a partition. +// +// Most of the operations in this class are done on IO thread. +struct StoragePartitionImpl::QuotaManagedDataDeletionHelper { + QuotaManagedDataDeletionHelper(const base::Closure& callback) + : callback(callback), task_count(0) { + } + + void IncrementTaskCountOnIO(); + void DecrementTaskCountOnIO(); + + void ClearDataOnIOThread( + const scoped_refptr<quota::QuotaManager>& quota_manager, + const base::Time begin, + uint32 remove_mask, + uint32 quota_storage_remove_mask, + const GURL& remove_origin); + + // Accessed on IO thread. + const base::Closure callback; + // Accessed on IO thread. + int task_count; +}; + +// Helper for deleting all sorts of data from a partition, keeps track of +// deletion status. +// +// StoragePartitionImpl creates an instance of this class to keep track of +// data deletion progress. Deletion requires deleting multiple bits of data +// (e.g. cookies, local storage, session storage etc.) and hopping between UI +// and IO thread. An instance of this class is created in the beginning of +// deletion process (StoragePartitionImpl::ClearDataImpl) and the instance is +// forwarded and updated on each (sub) deletion's callback. The instance is +// finally destroyed when deletion completes (and |callback| is invoked). +struct StoragePartitionImpl::DataDeletionHelper { + DataDeletionHelper(const base::Closure& callback) + : callback(callback), task_count(0) { + } + + void IncrementTaskCountOnUI(); + void DecrementTaskCountOnUI(); + + void ClearDataOnUIThread(uint32 remove_mask, + uint32 quota_storage_remove_mask, + const GURL& remove_origin, + const base::FilePath& path, + net::URLRequestContextGetter* rq_context, + DOMStorageContextImpl* dom_storage_context, + quota::QuotaManager* quota_manager, + const base::Time begin, + const base::Time end); + + // Accessed on UI thread. + const base::Closure callback; + // Accessed on UI thread. + int task_count; +}; + +void ClearQuotaManagedDataOnIOThread( + const scoped_refptr<quota::QuotaManager>& quota_manager, + const base::Time begin, + uint32 remove_mask, + uint32 quota_storage_remove_mask, + const GURL& remove_origin, + const base::Closure& callback) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + StoragePartitionImpl::QuotaManagedDataDeletionHelper* helper = + new StoragePartitionImpl::QuotaManagedDataDeletionHelper(callback); + helper->ClearDataOnIOThread(quota_manager, begin, + remove_mask, quota_storage_remove_mask, remove_origin); +} + StoragePartitionImpl::StoragePartitionImpl( const base::FilePath& partition_path, quota::QuotaManager* quota_manager, @@ -293,59 +394,221 @@ IndexedDBContextImpl* StoragePartitionImpl::GetIndexedDBContext() { return indexed_db_context_.get(); } -void StoragePartitionImpl::AsyncClearDataForOrigin( - uint32 storage_mask, - const GURL& storage_origin, - net::URLRequestContextGetter* request_context_getter) { +void StoragePartitionImpl::ClearDataImpl( + uint32 remove_mask, + uint32 quota_storage_remove_mask, + const GURL& remove_origin, + net::URLRequestContextGetter* rq_context, + const base::Time begin, + const base::Time end, + const base::Closure& callback) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DataDeletionHelper* helper = new DataDeletionHelper(callback); + // |helper| deletes itself when done in + // DataDeletionHelper::DecrementTaskCountOnUI(). + helper->ClearDataOnUIThread( + remove_mask, quota_storage_remove_mask, remove_origin, + GetPath(), rq_context, dom_storage_context_, quota_manager_, begin, end); +} - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - base::Bind(&ClearOriginOnIOThread, - storage_mask, - storage_origin, - make_scoped_refptr(request_context_getter), - quota_manager_)); +void StoragePartitionImpl:: + QuotaManagedDataDeletionHelper::IncrementTaskCountOnIO() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + ++task_count; +} + +void StoragePartitionImpl:: + QuotaManagedDataDeletionHelper::DecrementTaskCountOnIO() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + DCHECK_GT(task_count, 0); + --task_count; + if (task_count) + return; - if (storage_mask & kLocalDomStorage) - GetDOMStorageContext()->DeleteLocalStorage(storage_origin); + callback.Run(); + delete this; } -void StoragePartitionImpl::AsyncClearData(uint32 storage_mask) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); +void StoragePartitionImpl::QuotaManagedDataDeletionHelper::ClearDataOnIOThread( + const scoped_refptr<quota::QuotaManager>& quota_manager, + const base::Time begin, + uint32 remove_mask, + uint32 quota_storage_remove_mask, + const GURL& remove_origin) { + std::set<GURL> origins; + if (!remove_origin.is_empty()) + origins.insert(remove_origin); + + IncrementTaskCountOnIO(); + base::Closure decrement_callback = base::Bind( + &QuotaManagedDataDeletionHelper::DecrementTaskCountOnIO, + base::Unretained(this)); + + if (quota_storage_remove_mask & kQuotaManagedPersistentStorage) { + IncrementTaskCountOnIO(); + if (origins.empty()) { // Remove for all origins. + // Ask the QuotaManager for all origins with temporary quota modified + // within the user-specified timeframe, and deal with the resulting set in + // ClearQuotaManagedOriginsOnIOThread(). + quota_manager->GetOriginsModifiedSince( + quota::kStorageTypePersistent, begin, + base::Bind(&ClearQuotaManagedOriginsOnIOThread, + quota_manager, remove_mask, decrement_callback)); + } else { + ClearQuotaManagedOriginsOnIOThread( + quota_manager, remove_mask, decrement_callback, + origins, quota::kStorageTypePersistent); + } + } - // We ignore the media request context because it shares the same cookie store - // as the main request context. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - base::Bind(&ClearAllDataOnIOThread, - storage_mask, - url_request_context_, - quota_manager_)); - - if (storage_mask & kLocalDomStorage) { - dom_storage_context_->GetLocalStorageUsage( - base::Bind(&OnLocalStorageUsageInfo, dom_storage_context_)); + // Do the same for temporary quota. + if (quota_storage_remove_mask & kQuotaManagedTemporaryStorage) { + IncrementTaskCountOnIO(); + if (origins.empty()) { // Remove for all origins. + quota_manager->GetOriginsModifiedSince( + quota::kStorageTypeTemporary, begin, + base::Bind(&ClearQuotaManagedOriginsOnIOThread, + quota_manager, remove_mask, decrement_callback)); + } else { + ClearQuotaManagedOriginsOnIOThread( + quota_manager, remove_mask, decrement_callback, + origins, quota::kStorageTypeTemporary); + } } - if (storage_mask & kSessionDomStorage) { - dom_storage_context_->GetSessionStorageUsage( - base::Bind(&OnSessionStorageUsageInfo, dom_storage_context_)); + // Do the same for syncable quota. + if (quota_storage_remove_mask & kQuotaManagedSyncableStorage) { + IncrementTaskCountOnIO(); + if (origins.empty()) { // Remove for all origins. + quota_manager->GetOriginsModifiedSince( + quota::kStorageTypeSyncable, begin, + base::Bind(&ClearQuotaManagedOriginsOnIOThread, + quota_manager, remove_mask, decrement_callback)); + } else { + ClearQuotaManagedOriginsOnIOThread( + quota_manager, remove_mask, decrement_callback, + origins, quota::kStorageTypeSyncable); + } } + + DecrementTaskCountOnIO(); } -void StoragePartitionImpl::AsyncClearDataBetween(uint32 storage_mask, - const base::Time& begin, const base::Time& end, - const base::Closure& callback) { +void StoragePartitionImpl::DataDeletionHelper::IncrementTaskCountOnUI() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK(storage_mask == kShaderStorage); + ++task_count; +} - if (storage_mask & kShaderStorage) { +void StoragePartitionImpl::DataDeletionHelper::DecrementTaskCountOnUI() { + if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&DataDeletionHelper::DecrementTaskCountOnUI, + base::Unretained(this))); + return; + } + DCHECK_GT(task_count, 0); + --task_count; + if (!task_count) { + callback.Run(); + delete this; + } +} + +void StoragePartitionImpl::DataDeletionHelper::ClearDataOnUIThread( + uint32 remove_mask, + uint32 quota_storage_remove_mask, + const GURL& remove_origin, + const base::FilePath& path, + net::URLRequestContextGetter* rq_context, + DOMStorageContextImpl* dom_storage_context, + quota::QuotaManager* quota_manager, + const base::Time begin, + const base::Time end) { + DCHECK_NE(remove_mask, 0u); + DCHECK(!callback.is_null()); + + IncrementTaskCountOnUI(); + base::Closure decrement_callback = base::Bind( + &DataDeletionHelper::DecrementTaskCountOnUI, base::Unretained(this)); + + if (remove_mask & REMOVE_DATA_MASK_COOKIES) { + // Handle the cookies. + IncrementTaskCountOnUI(); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind(&ClearCookiesOnIOThread, + make_scoped_refptr(rq_context), begin, end, + decrement_callback)); + } + + if (remove_mask & REMOVE_DATA_MASK_INDEXEDDB || + remove_mask & REMOVE_DATA_MASK_WEBSQL || + remove_mask & REMOVE_DATA_MASK_APPCACHE || + remove_mask & REMOVE_DATA_MASK_FILE_SYSTEMS) { + IncrementTaskCountOnUI(); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind(&ClearQuotaManagedDataOnIOThread, + make_scoped_refptr(quota_manager), begin, + remove_mask, quota_storage_remove_mask, remove_origin, + decrement_callback)); + } + + if (remove_mask & REMOVE_DATA_MASK_LOCAL_STORAGE) { + IncrementTaskCountOnUI(); + ClearLocalStorageOnUIThread( + make_scoped_refptr(dom_storage_context), + remove_origin, begin, end, decrement_callback); + + // ClearDataImpl cannot clear session storage data when a particular origin + // is specified. Therefore we ignore clearing session storage in this case. + // TODO(lazyboy): Fix. + if (remove_origin.is_empty()) { + IncrementTaskCountOnUI(); + ClearSessionStorageOnUIThread( + make_scoped_refptr(dom_storage_context), decrement_callback); + } + } + + if (remove_mask & REMOVE_DATA_MASK_SHADER_CACHE) { + IncrementTaskCountOnUI(); BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&ClearShaderCacheOnIOThread, GetPath(), begin, end, - callback)); + base::Bind(&ClearShaderCacheOnIOThread, + path, begin, end, decrement_callback)); } + + DecrementTaskCountOnUI(); +} + + +void StoragePartitionImpl::ClearDataForOrigin( + uint32 remove_mask, + uint32 quota_storage_remove_mask, + const GURL& storage_origin, + net::URLRequestContextGetter* request_context_getter) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + ClearDataImpl(remove_mask, quota_storage_remove_mask, storage_origin, + request_context_getter, base::Time(), base::Time::Max(), + base::Bind(&base::DoNothing)); +} + +void StoragePartitionImpl::ClearDataForUnboundedRange( + uint32 remove_mask, + uint32 quota_storage_remove_mask) { + ClearDataImpl(remove_mask, quota_storage_remove_mask, GURL(), + GetURLRequestContext(), base::Time(), base::Time::Max(), + base::Bind(&base::DoNothing)); +} + +void StoragePartitionImpl::ClearDataForRange(uint32 remove_mask, + uint32 quota_storage_remove_mask, + const base::Time& begin, + const base::Time& end, + const base::Closure& callback) { + ClearDataImpl(remove_mask, quota_storage_remove_mask, GURL(), + GetURLRequestContext(), begin, end, callback); } WebRTCIdentityStore* StoragePartitionImpl::GetWebRTCIdentityStore() { diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h index 9dcdfec..0410f4d 100644 --- a/content/browser/storage_partition_impl.h +++ b/content/browser/storage_partition_impl.h @@ -31,19 +31,26 @@ class StoragePartitionImpl : public StoragePartition { virtual webkit_database::DatabaseTracker* GetDatabaseTracker() OVERRIDE; virtual DOMStorageContextImpl* GetDOMStorageContext() OVERRIDE; virtual IndexedDBContextImpl* GetIndexedDBContext() OVERRIDE; - virtual void AsyncClearDataForOrigin( - uint32 storage_mask, + + virtual void ClearDataForOrigin( + uint32 remove_mask, + uint32 quota_storage_remove_mask, const GURL& storage_origin, net::URLRequestContextGetter* request_context_getter) OVERRIDE; - virtual void AsyncClearData(uint32 storage_mask) OVERRIDE; - virtual void AsyncClearDataBetween( - uint32 storage_mask, - const base::Time& begin, - const base::Time& end, - const base::Closure& callback) OVERRIDE; + virtual void ClearDataForUnboundedRange( + uint32 remove_mask, + uint32 quota_storage_remove_mask) OVERRIDE; + virtual void ClearDataForRange(uint32 remove_mask, + uint32 quota_storage_remove_mask, + const base::Time& begin, + const base::Time& end, + const base::Closure& callback) OVERRIDE; WebRTCIdentityStore* GetWebRTCIdentityStore(); + struct DataDeletionHelper; + struct QuotaManagedDataDeletionHelper; + private: friend class StoragePartitionImplMap; FRIEND_TEST_ALL_PREFIXES(StoragePartitionShaderClearTest, ClearShaderCache); @@ -58,6 +65,10 @@ class StoragePartitionImpl : public StoragePartition { bool in_memory, const base::FilePath& profile_path); + // Quota managed data uses a different bitmask for types than + // StoragePartition uses. This method generates that mask. + static int GenerateQuotaClientMask(uint32 remove_mask); + CONTENT_EXPORT StoragePartitionImpl( const base::FilePath& partition_path, quota::QuotaManager* quota_manager, @@ -68,6 +79,14 @@ class StoragePartitionImpl : public StoragePartition { IndexedDBContextImpl* indexed_db_context, scoped_ptr<WebRTCIdentityStore> webrtc_identity_store); + void ClearDataImpl(uint32 remove_mask, + uint32 quota_storage_remove_mask, + const GURL& remove_origin, + net::URLRequestContextGetter* rq_context, + const base::Time begin, + const base::Time end, + const base::Closure& callback); + // Used by StoragePartitionImplMap. // // TODO(ajwong): These should be taken in the constructor and in Create() but diff --git a/content/browser/storage_partition_impl_map.cc b/content/browser/storage_partition_impl_map.cc index 8b6556ee..da7e88f 100644 --- a/content/browser/storage_partition_impl_map.cc +++ b/content/browser/storage_partition_impl_map.cc @@ -496,7 +496,9 @@ void StoragePartitionImplMap::AsyncObliterate( ++it) { const StoragePartitionConfig& config = it->first; if (config.partition_domain == partition_domain) { - it->second->AsyncClearData(StoragePartition::kAllStorage); + it->second->ClearDataForUnboundedRange( + StoragePartition::REMOVE_DATA_MASK_ALL, + StoragePartition::kAllStorage); if (!config.in_memory) { paths_to_keep.push_back(it->second->GetPath()); } diff --git a/content/browser/storage_partition_impl_unittest.cc b/content/browser/storage_partition_impl_unittest.cc index 36af638..0492335 100644 --- a/content/browser/storage_partition_impl_unittest.cc +++ b/content/browser/storage_partition_impl_unittest.cc @@ -98,8 +98,10 @@ class StoragePartitionShaderClearTest : public testing::Test { void ClearData(content::StoragePartitionImpl* sp, const base::Closure& cb) { base::Time time; - sp->AsyncClearDataBetween(content::StoragePartition::kShaderStorage, - time, time, cb); + sp->ClearDataForRange( + StoragePartition::REMOVE_DATA_MASK_SHADER_CACHE, + StoragePartition::kAllStorage, + time, time, cb); } TEST_F(StoragePartitionShaderClearTest, ClearShaderCache) { diff --git a/content/public/browser/storage_partition.h b/content/public/browser/storage_partition.h index bd7f90c..a8e451c 100644 --- a/content/public/browser/storage_partition.h +++ b/content/public/browser/storage_partition.h @@ -56,56 +56,63 @@ class StoragePartition { virtual DOMStorageContext* GetDOMStorageContext() = 0; virtual IndexedDBContext* GetIndexedDBContext() = 0; - enum StorageMask { - kCookies = 1 << 0, + enum RemoveDataMask { + REMOVE_DATA_MASK_APPCACHE = 1 << 0, + REMOVE_DATA_MASK_COOKIES = 1 << 1, + REMOVE_DATA_MASK_FILE_SYSTEMS = 1 << 2, + REMOVE_DATA_MASK_INDEXEDDB = 1 << 3, + REMOVE_DATA_MASK_LOCAL_STORAGE = 1 << 4, + REMOVE_DATA_MASK_SHADER_CACHE = 1 << 5, + REMOVE_DATA_MASK_WEBSQL = 1 << 6, + + REMOVE_DATA_MASK_ALL = -1 + }; + // TODO(lazyboy): Value in the enum should start with the enum prefix + // (QUOTA_MANAGED_STORAGE_MASK_*). + enum QuotaManagedStorageMask { // Corresponds to quota::kStorageTypeTemporary. - kQuotaManagedTemporaryStorage = 1 << 1, + kQuotaManagedTemporaryStorage = 1 << 0, // Corresponds to quota::kStorageTypePersistent. - kQuotaManagedPersistentStorage = 1 << 2, - - // Local dom storage. - kLocalDomStorage = 1 << 3, - kSessionDomStorage = 1 << 4, - - // Local shader storage. - kShaderStorage = 1 << 5, + kQuotaManagedPersistentStorage = 1 << 1, // Corresponds to quota::kStorageTypeSyncable. - kQuotaManagedSyncableStorage = 1 << 6, + kQuotaManagedSyncableStorage = 1 << 2, - kAllStorage = -1, + kAllStorage = -1 }; // Starts an asynchronous task that does a best-effort clear the data - // corresonding to the given |storage_mask| inside this StoragePartition for - // the given |storage_origin|. Note kSessionDomStorage is not cleared and the - // mask is ignored. + // corresponding to the given |remove_mask| and |quota_storage_remove_mask| + // inside this StoragePartition for the given |storage_origin|. + // Note session dom storage is not cleared even if you specify + // REMOVE_DATA_MASK_LOCAL_STORAGE. // // TODO(ajwong): Right now, the embedder may have some // URLRequestContextGetter objects that the StoragePartition does not know // about. This will no longer be the case when we resolve // http://crbug.com/159193. Remove |request_context_getter| when that bug // is fixed. - virtual void AsyncClearDataForOrigin( - uint32 storage_mask, - const GURL& storage_origin, - net::URLRequestContextGetter* request_context_getter) = 0; + virtual void ClearDataForOrigin(uint32 remove_mask, + uint32 quota_storage_remove_mask, + const GURL& storage_origin, + net::URLRequestContextGetter* rq_context) = 0; - // Similar to AsyncClearDataForOrigin(), but deletes all data out of the + // Similar to ClearDataForOrigin(), but deletes all data out of the // StoragePartition rather than just the data related to this origin. - virtual void AsyncClearData(uint32 storage_mask) = 0; + virtual void ClearDataForUnboundedRange(uint32 remove_mask, + uint32 quota_storage_remove_mask) = 0; - // Similar to AsyncClearDataForOrigin(), but deletes all the data out of the + // Similar to ClearDataForOrigin(), but deletes all the data out of the // StoragePartion from between the given |begin| and |end| dates rather // then just the data related to this origin. - // - // Note: This currently only supports the shader cache. - virtual void AsyncClearDataBetween(uint32 storage_mask, - const base::Time& begin, - const base::Time& end, - const base::Closure& callback) = 0; + virtual void ClearDataForRange(uint32 remove_mask, + uint32 quota_storage_remove_mask, + const base::Time& begin, + const base::Time& end, + const base::Closure& callback) = 0; + protected: virtual ~StoragePartition() {} }; |