summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authormkwst@chromium.org <mkwst@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-01 16:23:40 +0000
committermkwst@chromium.org <mkwst@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-01 16:23:40 +0000
commit94704173af5f1f377246351d2db3bc5106692df5 (patch)
treedb35e55da44431240ef29d2e8940705f8019f645 /chrome
parenta0ae316fef92606969c083f696609516ea7b8e1e (diff)
downloadchromium_src-94704173af5f1f377246351d2db3bc5106692df5.zip
chromium_src-94704173af5f1f377246351d2db3bc5106692df5.tar.gz
chromium_src-94704173af5f1f377246351d2db3bc5106692df5.tar.bz2
Time-based removal of temporary file systems via BrowsingDataRemover
QuotaManager takes over much of the functionality that BrowsingDataRemover implemented for FileSystem and Appcache removal. It also handles WebSQL databases, but I've left the database deletion in, as IndexedDBs aren't yet handled correctly, so we need to take care of them explicitly. BUG=63700 TEST=unit_tests, test_shell_tests Review URL: http://codereview.chromium.org/7129018 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@94913 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/browsing_data_remover.cc270
-rw-r--r--chrome/browser/browsing_data_remover.h85
-rw-r--r--chrome/browser/browsing_data_remover_unittest.cc330
-rw-r--r--chrome/browser/profiles/profile_impl.cc6
-rw-r--r--chrome/chrome_tests.gypi2
-rw-r--r--chrome/test/testing_profile.cc7
-rw-r--r--chrome/test/testing_profile.h4
7 files changed, 351 insertions, 353 deletions
diff --git a/chrome/browser/browsing_data_remover.cc b/chrome/browser/browsing_data_remover.cc
index 70083fe..9512be6 100644
--- a/chrome/browser/browsing_data_remover.cc
+++ b/chrome/browser/browsing_data_remover.cc
@@ -9,6 +9,7 @@
#include "base/callback.h"
#include "base/file_util.h"
+#include "base/logging.h"
#include "base/platform_file.h"
#include "chrome/browser/autofill/personal_data_manager.h"
#include "chrome/browser/browser_process.h"
@@ -44,11 +45,8 @@
#include "net/http/http_cache.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
-#include "webkit/database/database_tracker.h"
-#include "webkit/database/database_util.h"
-#include "webkit/fileapi/file_system_context.h"
-#include "webkit/fileapi/file_system_operation_context.h"
-#include "webkit/fileapi/sandbox_mount_point_provider.h"
+#include "webkit/quota/quota_manager.h"
+#include "webkit/quota/quota_types.h"
// Done so that we can use PostTask on BrowsingDataRemovers and not have
// BrowsingDataRemover implement RefCounted.
@@ -60,29 +58,21 @@ BrowsingDataRemover::BrowsingDataRemover(Profile* profile,
base::Time delete_begin,
base::Time delete_end)
: profile_(profile),
+ quota_manager_(NULL),
special_storage_policy_(profile->GetExtensionSpecialStoragePolicy()),
delete_begin_(delete_begin),
delete_end_(delete_end),
- ALLOW_THIS_IN_INITIALIZER_LIST(database_cleared_callback_(
- this, &BrowsingDataRemover::OnClearedDatabases)),
ALLOW_THIS_IN_INITIALIZER_LIST(cache_callback_(
this, &BrowsingDataRemover::DoClearCache)),
- ALLOW_THIS_IN_INITIALIZER_LIST(appcache_got_info_callback_(
- this, &BrowsingDataRemover::OnGotAppCacheInfo)),
- ALLOW_THIS_IN_INITIALIZER_LIST(appcache_deleted_callback_(
- this, &BrowsingDataRemover::OnAppCacheDeleted)),
- appcaches_to_be_deleted_count_(0),
next_cache_state_(STATE_NONE),
cache_(NULL),
main_context_getter_(profile->GetRequestContext()),
media_context_getter_(profile->GetRequestContextForMedia()),
- waiting_for_clear_databases_(false),
waiting_for_clear_history_(false),
+ waiting_for_clear_quota_managed_data_(false),
waiting_for_clear_networking_history_(false),
waiting_for_clear_cache_(false),
- waiting_for_clear_appcache_(false),
- waiting_for_clear_gears_data_(false),
- waiting_for_clear_file_systems_(false) {
+ waiting_for_clear_lso_data_(false) {
DCHECK(profile);
}
@@ -90,30 +80,21 @@ BrowsingDataRemover::BrowsingDataRemover(Profile* profile,
TimePeriod time_period,
base::Time delete_end)
: profile_(profile),
+ quota_manager_(NULL),
special_storage_policy_(profile->GetExtensionSpecialStoragePolicy()),
delete_begin_(CalculateBeginDeleteTime(time_period)),
delete_end_(delete_end),
- ALLOW_THIS_IN_INITIALIZER_LIST(database_cleared_callback_(
- this, &BrowsingDataRemover::OnClearedDatabases)),
ALLOW_THIS_IN_INITIALIZER_LIST(cache_callback_(
this, &BrowsingDataRemover::DoClearCache)),
- ALLOW_THIS_IN_INITIALIZER_LIST(appcache_got_info_callback_(
- this, &BrowsingDataRemover::OnGotAppCacheInfo)),
- ALLOW_THIS_IN_INITIALIZER_LIST(appcache_deleted_callback_(
- this, &BrowsingDataRemover::OnAppCacheDeleted)),
- appcaches_to_be_deleted_count_(0),
next_cache_state_(STATE_NONE),
cache_(NULL),
main_context_getter_(profile->GetRequestContext()),
media_context_getter_(profile->GetRequestContextForMedia()),
- waiting_for_clear_databases_(false),
waiting_for_clear_history_(false),
+ waiting_for_clear_quota_managed_data_(false),
waiting_for_clear_networking_history_(false),
waiting_for_clear_cache_(false),
- waiting_for_clear_appcache_(false),
- waiting_for_clear_lso_data_(false),
- waiting_for_clear_gears_data_(false),
- waiting_for_clear_file_systems_(false) {
+ waiting_for_clear_lso_data_(false) {
DCHECK(profile);
}
@@ -215,41 +196,18 @@ void BrowsingDataRemover::Remove(int remove_mask) {
profile_->GetWebKitContext()->DeleteDataModifiedSince(delete_begin_);
}
- database_tracker_ = profile_->GetDatabaseTracker();
- if (database_tracker_.get()) {
- waiting_for_clear_databases_ = true;
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(
- this,
- &BrowsingDataRemover::ClearDatabasesOnFILEThread));
- }
-
- appcache_service_ = profile_->GetAppCacheService();
- if (appcache_service_.get()) {
- waiting_for_clear_appcache_ = true;
+ // We'll start by using the quota system to clear out AppCaches, WebSQL DBs,
+ // and File Systems.
+ quota_manager_ = profile_->GetQuotaManager();
+ if (quota_manager_) {
+ waiting_for_clear_quota_managed_data_ = true;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
NewRunnableMethod(
this,
- &BrowsingDataRemover::ClearAppCacheOnIOThread));
+ &BrowsingDataRemover::ClearQuotaManagedDataOnIOThread));
}
- waiting_for_clear_gears_data_ = true;
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(
- this,
- &BrowsingDataRemover::ClearGearsDataOnFILEThread,
- profile_->GetPath()));
-
- waiting_for_clear_file_systems_ = true;
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(
- this,
- &BrowsingDataRemover::ClearFileSystemsOnFILEThread));
-
if (profile_->GetTransportSecurityState()) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
@@ -490,142 +448,104 @@ void BrowsingDataRemover::DoClearCache(int rv) {
}
}
-void BrowsingDataRemover::OnClearedDatabases(int rv) {
- if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- bool result = BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- NewRunnableMethod(this, &BrowsingDataRemover::OnClearedDatabases, rv));
- DCHECK(result);
- return;
+void BrowsingDataRemover::ClearQuotaManagedDataOnIOThread() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK(waiting_for_clear_quota_managed_data_);
+
+ // Ask the QuotaManager for all origins with temporary quota modified within
+ // the user-specified timeframe, and deal with the resulting set in
+ // OnGotQuotaManagedOrigins().
+ quota_managed_origins_to_delete_count_ = 0;
+ quota_managed_storage_types_to_delete_count_ = 2;
+
+ if (delete_begin_ == base::Time()) {
+ // If we're deleting since the beginning of time, ask the QuotaManager for
+ // all origins with persistent quota modified within the user-specified
+ // timeframe, and deal with the resulting set in
+ // OnGotPersistentQuotaManagedOrigins.
+ profile_->GetQuotaManager()->GetOriginsModifiedSince(
+ quota::kStorageTypePersistent, delete_begin_, NewCallback(this,
+ &BrowsingDataRemover::OnGotPersistentQuotaManagedOrigins));
+ } else {
+ // Otherwise, we don't need to deal with persistent storage.
+ --quota_managed_storage_types_to_delete_count_;
}
- // Notify the UI thread that we are done.
- database_tracker_ = NULL;
- waiting_for_clear_databases_ = false;
-
- NotifyAndDeleteIfDone();
-}
-
-void BrowsingDataRemover::ClearDatabasesOnFILEThread() {
- // This function should be called on the FILE thread.
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- int rv = database_tracker_->DeleteDataModifiedSince(
- delete_begin_, &database_cleared_callback_);
- if (rv != net::ERR_IO_PENDING)
- OnClearedDatabases(rv);
-}
-void BrowsingDataRemover::OnClearedAppCache() {
- if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- bool result = BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- NewRunnableMethod(this, &BrowsingDataRemover::OnClearedAppCache));
- DCHECK(result);
- return;
- }
- waiting_for_clear_appcache_ = false;
- NotifyAndDeleteIfDone();
+ // Do the same for temporary quota, regardless, passing the resulting set into
+ // OnGotTemporaryQuotaManagedOrigins.
+ profile_->GetQuotaManager()->GetOriginsModifiedSince(
+ quota::kStorageTypeTemporary, delete_begin_, NewCallback(this,
+ &BrowsingDataRemover::OnGotTemporaryQuotaManagedOrigins));
}
-void BrowsingDataRemover::ClearAppCacheOnIOThread() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- DCHECK(waiting_for_clear_appcache_);
- appcache_info_ = new appcache::AppCacheInfoCollection;
- appcache_service_->GetAllAppCacheInfo(
- appcache_info_, &appcache_got_info_callback_);
- // continues in OnGotAppCacheInfo.
-}
-
-void BrowsingDataRemover::OnGotAppCacheInfo(int rv) {
- using appcache::AppCacheInfoVector;
- typedef std::map<GURL, AppCacheInfoVector> InfoByOrigin;
-
- for (InfoByOrigin::const_iterator origin =
- appcache_info_->infos_by_origin.begin();
- origin != appcache_info_->infos_by_origin.end(); ++origin) {
- if (special_storage_policy_->IsStorageProtected(origin->first))
+void BrowsingDataRemover::OnGotTemporaryQuotaManagedOrigins(
+ const std::set<GURL>& origins) {
+ DCHECK_GT(quota_managed_storage_types_to_delete_count_, 0);
+ // Walk through the origins passed in, delete temporary quota from each that
+ // isn't protected.
+ std::set<GURL>::const_iterator origin;
+ for (origin = origins.begin(); origin != origins.end(); ++origin) {
+ if (special_storage_policy_->IsStorageProtected(origin->GetOrigin()))
continue;
- for (AppCacheInfoVector::const_iterator info = origin->second.begin();
- info != origin->second.end(); ++info) {
- if (info->creation_time > delete_begin_) {
- ++appcaches_to_be_deleted_count_;
- appcache_service_->DeleteAppCacheGroup(
- info->manifest_url, &appcache_deleted_callback_);
- }
- }
+ ++quota_managed_origins_to_delete_count_;
+ quota_manager_->DeleteOriginData(origin->GetOrigin(),
+ quota::kStorageTypeTemporary, NewCallback(this,
+ &BrowsingDataRemover::OnQuotaManagedOriginDeletion));
}
- if (!appcaches_to_be_deleted_count_)
- OnClearedAppCache();
- // else continues in OnAppCacheDeleted
+ --quota_managed_storage_types_to_delete_count_;
+ if (quota_managed_storage_types_to_delete_count_ == 0 &&
+ quota_managed_origins_to_delete_count_ == 0)
+ CheckQuotaManagedDataDeletionStatus();
}
-void BrowsingDataRemover::OnAppCacheDeleted(int rv) {
- --appcaches_to_be_deleted_count_;
- if (!appcaches_to_be_deleted_count_)
- OnClearedAppCache();
-}
-
-void BrowsingDataRemover::ClearFileSystemsOnFILEThread() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- DCHECK(waiting_for_clear_file_systems_);
- scoped_refptr<fileapi::FileSystemContext>
- fs_context(profile_->GetFileSystemContext());
- scoped_ptr<fileapi::SandboxMountPointProvider::OriginEnumerator>
- origin_enumerator(fs_context->path_manager()->sandbox_provider()->
- CreateOriginEnumerator());
-
- GURL origin;
- while (!(origin = origin_enumerator->Next()).is_empty()) {
- if (special_storage_policy_->IsStorageProtected(origin))
+void BrowsingDataRemover::OnGotPersistentQuotaManagedOrigins(
+ const std::set<GURL>& origins) {
+ DCHECK_GT(quota_managed_storage_types_to_delete_count_, 0);
+ // Walk through the origins passed in, delete persistent quota from each that
+ // isn't protected.
+ std::set<GURL>::const_iterator origin;
+ for (origin = origins.begin(); origin != origins.end(); ++origin) {
+ if (special_storage_policy_->IsStorageProtected(origin->GetOrigin()))
continue;
- if (delete_begin_ == base::Time()) {
- // If the user chooses to delete browsing data "since the beginning of
- // time" remove both temporary and persistent file systems entirely.
- fs_context->DeleteDataForOriginAndTypeOnFileThread(origin,
- fileapi::kFileSystemTypeTemporary);
- fs_context->DeleteDataForOriginAndTypeOnFileThread(origin,
- fileapi::kFileSystemTypePersistent);
- }
- // TODO(mkwst): Else? Decide what to do for time-based deletion: crbug/63700
+ ++quota_managed_origins_to_delete_count_;
+ quota_manager_->DeleteOriginData(origin->GetOrigin(),
+ quota::kStorageTypePersistent, NewCallback(this,
+ &BrowsingDataRemover::OnQuotaManagedOriginDeletion));
}
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- NewRunnableMethod(this, &BrowsingDataRemover::OnClearedFileSystems));
-}
-
-void BrowsingDataRemover::OnClearedFileSystems() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- waiting_for_clear_file_systems_ = false;
- NotifyAndDeleteIfDone();
-}
-
-// static
-void BrowsingDataRemover::ClearGearsData(const FilePath& profile_dir) {
- FilePath plugin_data = profile_dir.AppendASCII("Plugin Data");
- if (file_util::DirectoryExists(plugin_data))
- file_util::Delete(plugin_data, true);
+ --quota_managed_storage_types_to_delete_count_;
+ if (quota_managed_storage_types_to_delete_count_ == 0 &&
+ quota_managed_origins_to_delete_count_ == 0)
+ CheckQuotaManagedDataDeletionStatus();
}
-void BrowsingDataRemover::OnClearedGearsData() {
- if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- bool result = BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- NewRunnableMethod(this, &BrowsingDataRemover::OnClearedGearsData));
- DCHECK(result);
- return;
+void BrowsingDataRemover::OnQuotaManagedOriginDeletion(
+ quota::QuotaStatusCode status) {
+ DCHECK_GT(quota_managed_origins_to_delete_count_, 0);
+ if (status != quota::kQuotaStatusOk) {
+ // TODO(mkwst): We should add the GURL to StatusCallback; this is a pretty
+ // worthless error message otherwise.
+ DLOG(ERROR) << "Couldn't remove origin. Status: " << status;
}
- waiting_for_clear_gears_data_ = false;
- NotifyAndDeleteIfDone();
+
+ --quota_managed_origins_to_delete_count_;
+ if (quota_managed_storage_types_to_delete_count_ == 0 &&
+ quota_managed_origins_to_delete_count_ == 0)
+ CheckQuotaManagedDataDeletionStatus();
}
-void BrowsingDataRemover::ClearGearsDataOnFILEThread(
- const FilePath& profile_dir) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- DCHECK(waiting_for_clear_gears_data_);
+void BrowsingDataRemover::CheckQuotaManagedDataDeletionStatus() {
+ DCHECK_EQ(quota_managed_origins_to_delete_count_, 0);
+ DCHECK_EQ(quota_managed_storage_types_to_delete_count_, 0);
+ DCHECK(waiting_for_clear_quota_managed_data_);
- ClearGearsData(profile_dir);
- OnClearedGearsData();
+ waiting_for_clear_quota_managed_data_ = false;
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ NewRunnableMethod(
+ this,
+ &BrowsingDataRemover::NotifyAndDeleteIfDone));
}
void BrowsingDataRemover::OnWaitableEventSignaled(
diff --git a/chrome/browser/browsing_data_remover.h b/chrome/browser/browsing_data_remover.h
index 9f94024..dc96cc0 100644
--- a/chrome/browser/browsing_data_remover.h
+++ b/chrome/browser/browsing_data_remover.h
@@ -16,6 +16,7 @@
#include "content/browser/cancelable_request.h"
#include "content/common/notification_observer.h"
#include "content/common/notification_registrar.h"
+#include "webkit/quota/quota_types.h"
class ExtensionSpecialStoragePolicy;
class IOThread;
@@ -34,6 +35,10 @@ namespace webkit_database {
class DatabaseTracker;
}
+namespace quota {
+class QuotaManager;
+}
+
// BrowsingDataRemover is responsible for removing data related to browsing:
// visits in url database, downloads, cookies ...
@@ -92,9 +97,6 @@ class BrowsingDataRemover : public NotificationObserver,
static bool is_removing() { return removing_; }
- // Removes the Gears plugin data.
- static void ClearGearsData(const FilePath& profile_dir);
-
private:
enum CacheState {
STATE_NONE,
@@ -143,36 +145,26 @@ class BrowsingDataRemover : public NotificationObserver,
// Performs the actual work to delete the cache.
void DoClearCache(int rv);
- // Callback when HTML5 databases have been deleted. Invokes
- // NotifyAndDeleteIfDone.
- void OnClearedDatabases(int rv);
-
- // Invoked on the FILE thread to delete HTML5 databases.
- void ClearDatabasesOnFILEThread();
+ // Invoked on the IO thread to delete all storage types managed by the quota
+ // system: AppCache, Databases, FileSystems.
+ void ClearQuotaManagedDataOnIOThread();
- // Callback when HTML5 file systems have been cleared. Invokes
- // NotifyAndDeleteIfDone.
- void OnClearedFileSystems();
-
- // Invoked on the FILE thread to delete HTML5 file systems.
- void ClearFileSystemsOnFILEThread();
-
- // Callback when the appcache has been cleared. Invokes
- // NotifyAndDeleteIfDone.
- void OnClearedAppCache();
+ // Callback to respond to QuotaManager::GetOriginsModifiedSince, which is the
+ // core of 'ClearQuotaManagedDataOnIOThread'.
+ void OnGotTemporaryQuotaManagedOrigins(const std::set<GURL>&);
- // Invoked on the IO thread to delete from the AppCache.
- void ClearAppCacheOnIOThread();
+ // Callback to respond to QuotaManager::GetOriginsModifiedSince, which is the
+ // core of `ClearQuotaManagedDataOnIOThread`
+ void OnGotPersistentQuotaManagedOrigins(const std::set<GURL>&);
- // Lower level helpers.
- void OnGotAppCacheInfo(int rv);
- void OnAppCacheDeleted(int rv);
+ // Callback responding to deletion of a single quota managed origin's
+ // persistent data
+ void OnQuotaManagedOriginDeletion(quota::QuotaStatusCode);
- // Callback when Gears data has been deleted. Invokes NotifyAndDeleteIfDone.
- void OnClearedGearsData();
-
- // Invoked on the FILE thread to delete old Gears data.
- void ClearGearsDataOnFILEThread(const FilePath& profile_dir);
+ // Called to check whether all temporary and persistent origin data that
+ // should be deleted has been deleted. If everything's good to go, invokes
+ // NotifyAndDeleteIfDone on the UI thread.
+ void CheckQuotaManagedDataDeletionStatus();
// Calculate the begin time for the deletion range specified by |time_period|.
base::Time CalculateBeginDeleteTime(TimePeriod time_period);
@@ -181,10 +173,9 @@ class BrowsingDataRemover : public NotificationObserver,
bool all_done() {
return registrar_.IsEmpty() && !waiting_for_clear_cache_ &&
!waiting_for_clear_history_ &&
+ !waiting_for_clear_quota_managed_data_ &&
!waiting_for_clear_networking_history_ &&
- !waiting_for_clear_databases_ && !waiting_for_clear_appcache_ &&
- !waiting_for_clear_lso_data_ && !waiting_for_clear_gears_data_ &&
- !waiting_for_clear_file_systems_;
+ !waiting_for_clear_lso_data_;
}
NotificationRegistrar registrar_;
@@ -192,6 +183,10 @@ class BrowsingDataRemover : public NotificationObserver,
// Profile we're to remove from.
Profile* profile_;
+ // The QuotaManager is owned by the profile; we can use a raw pointer here,
+ // and rely on the profile to destroy the object whenever it's reasonable.
+ quota::QuotaManager* quota_manager_;
+
// 'Protected' origins are not subject to data removal.
scoped_refptr<ExtensionSpecialStoragePolicy> special_storage_policy_;
@@ -204,24 +199,12 @@ class BrowsingDataRemover : public NotificationObserver,
// True if Remove has been invoked.
static bool removing_;
- // Reference to database tracker held while deleting databases.
- scoped_refptr<webkit_database::DatabaseTracker> database_tracker_;
-
- net::CompletionCallbackImpl<BrowsingDataRemover> database_cleared_callback_;
- net::CompletionCallbackImpl<BrowsingDataRemover> cache_callback_;
-
- // Used to clear the appcache.
- scoped_refptr<ChromeAppCacheService> appcache_service_;
- net::CompletionCallbackImpl<BrowsingDataRemover> appcache_got_info_callback_;
- net::CompletionCallbackImpl<BrowsingDataRemover> appcache_deleted_callback_;
- scoped_refptr<appcache::AppCacheInfoCollection> appcache_info_;
- int appcaches_to_be_deleted_count_;
-
// Used to delete data from the HTTP caches.
+ net::CompletionCallbackImpl<BrowsingDataRemover> cache_callback_;
CacheState next_cache_state_;
disk_cache::Backend* cache_;
- // Used to delete data from HTTP cache and appcache.
+ // Used to delete data from HTTP cache.
scoped_refptr<net::URLRequestContextGetter> main_context_getter_;
scoped_refptr<net::URLRequestContextGetter> media_context_getter_;
@@ -230,14 +213,16 @@ class BrowsingDataRemover : public NotificationObserver,
base::WaitableEventWatcher watcher_;
// True if we're waiting for various data to be deleted.
- bool waiting_for_clear_databases_;
bool waiting_for_clear_history_;
+ bool waiting_for_clear_quota_managed_data_;
bool waiting_for_clear_networking_history_;
bool waiting_for_clear_cache_;
- bool waiting_for_clear_appcache_;
bool waiting_for_clear_lso_data_;
- bool waiting_for_clear_gears_data_;
- bool waiting_for_clear_file_systems_;
+
+ // Tracking how many origins need to be deleted, and whether we're finished
+ // gathering origins.
+ int quota_managed_origins_to_delete_count_;
+ int quota_managed_storage_types_to_delete_count_;
ObserverList<Observer> observer_list_;
diff --git a/chrome/browser/browsing_data_remover_unittest.cc b/chrome/browser/browsing_data_remover_unittest.cc
index 2e4249d..367dc5f 100644
--- a/chrome/browser/browsing_data_remover_unittest.cc
+++ b/chrome/browser/browsing_data_remover_unittest.cc
@@ -11,14 +11,15 @@
#include "chrome/browser/extensions/mock_extension_special_storage_policy.h"
#include "chrome/browser/history/history.h"
#include "chrome/test/testing_profile.h"
-#include "content/browser/appcache/chrome_appcache_service.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "webkit/appcache/appcache_test_helper.h"
#include "webkit/fileapi/file_system_context.h"
-#include "webkit/fileapi/file_system_operation_context.h"
#include "webkit/fileapi/file_system_file_util.h"
+#include "webkit/fileapi/file_system_operation_context.h"
#include "webkit/fileapi/file_system_path_manager.h"
#include "webkit/fileapi/sandbox_mount_point_provider.h"
+#include "webkit/quota/mock_quota_manager.h"
+#include "webkit/quota/quota_manager.h"
+#include "webkit/quota/quota_types.h"
namespace {
@@ -30,9 +31,6 @@ const GURL kOrigin1(kTestkOrigin1);
const GURL kOrigin2(kTestkOrigin2);
const GURL kOrigin3(kTestkOrigin3);
-const GURL kProtectedManifest("http://www.protected.com/cache.manifest");
-const GURL kNormalManifest("http://www.normal.com/cache.manifest");
-
class BrowsingDataRemoverTester : public BrowsingDataRemover::Observer {
public:
BrowsingDataRemoverTester() {}
@@ -56,6 +54,8 @@ class BrowsingDataRemoverTester : public BrowsingDataRemover::Observer {
DISALLOW_COPY_AND_ASSIGN(BrowsingDataRemoverTester);
};
+// Testers -------------------------------------------------------------------
+
class RemoveHistoryTester : public BrowsingDataRemoverTester {
public:
explicit RemoveHistoryTester(TestingProfile* profile)
@@ -101,69 +101,55 @@ class RemoveHistoryTester : public BrowsingDataRemoverTester {
DISALLOW_COPY_AND_ASSIGN(RemoveHistoryTester);
};
-class RemoveFileSystemTester : public BrowsingDataRemoverTester {
+class RemoveQuotaManagedDataTester : public BrowsingDataRemoverTester {
public:
- explicit RemoveFileSystemTester() {}
-
- void FindFileSystemPathCallback(bool success,
- const FilePath& path,
- const std::string& name) {
- found_file_system_ = success;
- Notify();
+ RemoveQuotaManagedDataTester() {}
+ virtual ~RemoveQuotaManagedDataTester() {}
+
+ void PopulateTestQuotaManagedData(quota::MockQuotaManager* manager) {
+ // Set up kOrigin1 with a temporary quota, kOrigin2 with a persistent
+ // quota, and kOrigin3 with both. kOrigin1 is modified now, kOrigin2
+ // is modified at the beginning of time, and kOrigin3 is modified one day
+ // ago.
+ PopulateTestQuotaManagedPersistentData(manager);
+ PopulateTestQuotaManagedTemporaryData(manager);
}
- bool FileSystemContainsOriginAndType(const GURL& origin,
- fileapi::FileSystemType type) {
- sandbox_->ValidateFileSystemRootAndGetURL(
- origin, type, false, NewCallback(this,
- &RemoveFileSystemTester::FindFileSystemPathCallback));
- BlockUntilNotified();
- return found_file_system_;
- }
-
- virtual void PopulateTestFileSystemData(TestingProfile* profile) {
- // Set up kOrigin1 with a temporary file system, kOrigin2 with a persistent
- // file system, and kOrigin3 with both.
- sandbox_ = profile->GetFileSystemContext()->path_manager()->
- sandbox_provider();
-
- CreateDirectoryForOriginAndType(kOrigin1,
- fileapi::kFileSystemTypeTemporary);
- CreateDirectoryForOriginAndType(kOrigin2,
- fileapi::kFileSystemTypePersistent);
- CreateDirectoryForOriginAndType(kOrigin3,
- fileapi::kFileSystemTypeTemporary);
- CreateDirectoryForOriginAndType(kOrigin3,
- fileapi::kFileSystemTypePersistent);
-
- EXPECT_FALSE(FileSystemContainsOriginAndType(kOrigin1,
- fileapi::kFileSystemTypePersistent));
- EXPECT_TRUE(FileSystemContainsOriginAndType(kOrigin1,
- fileapi::kFileSystemTypeTemporary));
- EXPECT_TRUE(FileSystemContainsOriginAndType(kOrigin2,
- fileapi::kFileSystemTypePersistent));
- EXPECT_FALSE(FileSystemContainsOriginAndType(kOrigin2,
- fileapi::kFileSystemTypeTemporary));
- EXPECT_TRUE(FileSystemContainsOriginAndType(kOrigin3,
- fileapi::kFileSystemTypePersistent));
- EXPECT_TRUE(FileSystemContainsOriginAndType(kOrigin3,
- fileapi::kFileSystemTypeTemporary));
+ void PopulateTestQuotaManagedPersistentData(
+ quota::MockQuotaManager* manager) {
+ manager->AddOrigin(kOrigin2, quota::kStorageTypePersistent,
+ base::Time());
+ manager->AddOrigin(kOrigin3, quota::kStorageTypePersistent,
+ base::Time::Now() - base::TimeDelta::FromDays(1));
+
+ EXPECT_FALSE(manager->OriginHasData(kOrigin1,
+ quota::kStorageTypePersistent));
+ EXPECT_TRUE(manager->OriginHasData(kOrigin2,
+ quota::kStorageTypePersistent));
+ EXPECT_TRUE(manager->OriginHasData(kOrigin3,
+ quota::kStorageTypePersistent));
}
- void CreateDirectoryForOriginAndType(const GURL& origin,
- fileapi::FileSystemType type) {
- FilePath target = sandbox_->ValidateFileSystemRootAndGetPathOnFileThread(
- origin, type, FilePath(), true);
- EXPECT_TRUE(file_util::DirectoryExists(target));
+ void PopulateTestQuotaManagedTemporaryData(quota::MockQuotaManager* manager) {
+ manager->AddOrigin(kOrigin1, quota::kStorageTypeTemporary,
+ base::Time::Now());
+ manager->AddOrigin(kOrigin3, quota::kStorageTypeTemporary,
+ base::Time::Now() - base::TimeDelta::FromDays(1));
+
+ EXPECT_TRUE(manager->OriginHasData(kOrigin1,
+ quota::kStorageTypeTemporary));
+ EXPECT_FALSE(manager->OriginHasData(kOrigin2,
+ quota::kStorageTypeTemporary));
+ EXPECT_TRUE(manager->OriginHasData(kOrigin3,
+ quota::kStorageTypeTemporary));
}
private:
- fileapi::SandboxMountPointProvider* sandbox_;
- bool found_file_system_;
-
- DISALLOW_COPY_AND_ASSIGN(RemoveFileSystemTester);
+ DISALLOW_COPY_AND_ASSIGN(RemoveQuotaManagedDataTester);
};
+// Test Class ----------------------------------------------------------------
+
class BrowsingDataRemoverTest : public testing::Test {
public:
BrowsingDataRemoverTest()
@@ -205,6 +191,18 @@ class BrowsingDataRemoverTest : public testing::Test {
return profile_.get();
}
+ quota::MockQuotaManager* GetMockManager() {
+ if (profile_->GetQuotaManager() == NULL) {
+ profile_->SetQuotaManager(new quota::MockQuotaManager(
+ profile_->IsOffTheRecord(),
+ profile_->GetPath(),
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB),
+ profile_->GetExtensionSpecialStoragePolicy()));
+ }
+ return (quota::MockQuotaManager*) profile_->GetQuotaManager();
+ }
+
private:
// message_loop_, as well as all the threads associated with it must be
// defined before profile_ to prevent explosions. Oh how I love C++.
@@ -219,6 +217,8 @@ class BrowsingDataRemoverTest : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(BrowsingDataRemoverTest);
};
+// Tests ---------------------------------------------------------------------
+
TEST_F(BrowsingDataRemoverTest, RemoveHistoryForever) {
scoped_ptr<RemoveHistoryTester> tester(
new RemoveHistoryTester(GetProfile()));
@@ -250,76 +250,164 @@ TEST_F(BrowsingDataRemoverTest, RemoveHistoryForLastHour) {
EXPECT_TRUE(tester->HistoryContainsURL(kOrigin2));
}
-TEST_F(BrowsingDataRemoverTest, RemoveFileSystemsForever) {
- scoped_ptr<RemoveFileSystemTester> tester(new RemoveFileSystemTester());
+TEST_F(BrowsingDataRemoverTest, RemoveQuotaManagedDataForeverBoth) {
+ scoped_ptr<RemoveQuotaManagedDataTester> tester(
+ new RemoveQuotaManagedDataTester());
+
+ tester->PopulateTestQuotaManagedData(GetMockManager());
+ BlockUntilBrowsingDataRemoved(BrowsingDataRemover::EVERYTHING,
+ base::Time::Now(), BrowsingDataRemover::REMOVE_COOKIES, tester.get());
+
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1,
+ quota::kStorageTypeTemporary));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2,
+ quota::kStorageTypeTemporary));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin3,
+ quota::kStorageTypeTemporary));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1,
+ quota::kStorageTypePersistent));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2,
+ quota::kStorageTypePersistent));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin3,
+ quota::kStorageTypePersistent));
+}
- tester->PopulateTestFileSystemData(GetProfile());
+TEST_F(BrowsingDataRemoverTest, RemoveQuotaManagedDataForeverOnlyTemporary) {
+ scoped_ptr<RemoveQuotaManagedDataTester> tester(
+ new RemoveQuotaManagedDataTester());
+ tester->PopulateTestQuotaManagedTemporaryData(GetMockManager());
BlockUntilBrowsingDataRemoved(BrowsingDataRemover::EVERYTHING,
base::Time::Now(), BrowsingDataRemover::REMOVE_COOKIES, tester.get());
- EXPECT_FALSE(tester->FileSystemContainsOriginAndType(kOrigin1,
- fileapi::kFileSystemTypePersistent));
- EXPECT_FALSE(tester->FileSystemContainsOriginAndType(kOrigin1,
- fileapi::kFileSystemTypeTemporary));
- EXPECT_FALSE(tester->FileSystemContainsOriginAndType(kOrigin2,
- fileapi::kFileSystemTypePersistent));
- EXPECT_FALSE(tester->FileSystemContainsOriginAndType(kOrigin2,
- fileapi::kFileSystemTypeTemporary));
- EXPECT_FALSE(tester->FileSystemContainsOriginAndType(kOrigin3,
- fileapi::kFileSystemTypePersistent));
- EXPECT_FALSE(tester->FileSystemContainsOriginAndType(kOrigin3,
- fileapi::kFileSystemTypeTemporary));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1,
+ quota::kStorageTypeTemporary));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2,
+ quota::kStorageTypeTemporary));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin3,
+ quota::kStorageTypeTemporary));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1,
+ quota::kStorageTypePersistent));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2,
+ quota::kStorageTypePersistent));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin3,
+ quota::kStorageTypePersistent));
}
-TEST_F(BrowsingDataRemoverTest, RemoveAppCacheForever) {
- // Set up ChromeAppCacheService.
- scoped_refptr<ChromeAppCacheService> appcache_service =
- new ChromeAppCacheService(NULL);
- const content::ResourceContext* resource_context = NULL;
+TEST_F(BrowsingDataRemoverTest, RemoveQuotaManagedDataForeverOnlyPersistent) {
+ scoped_ptr<RemoveQuotaManagedDataTester> tester(
+ new RemoveQuotaManagedDataTester());
+
+ tester->PopulateTestQuotaManagedPersistentData(GetMockManager());
+ BlockUntilBrowsingDataRemoved(BrowsingDataRemover::EVERYTHING,
+ base::Time::Now(), BrowsingDataRemover::REMOVE_COOKIES, tester.get());
+
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1,
+ quota::kStorageTypeTemporary));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2,
+ quota::kStorageTypeTemporary));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin3,
+ quota::kStorageTypeTemporary));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1,
+ quota::kStorageTypePersistent));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2,
+ quota::kStorageTypePersistent));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin3,
+ quota::kStorageTypePersistent));
+}
+
+TEST_F(BrowsingDataRemoverTest, RemoveQuotaManagedDataForeverNeither) {
+ scoped_ptr<RemoveQuotaManagedDataTester> tester(
+ new RemoveQuotaManagedDataTester());
+
+ GetMockManager(); // Creates the QuotaManager instance.
+ BlockUntilBrowsingDataRemoved(BrowsingDataRemover::EVERYTHING,
+ base::Time::Now(), BrowsingDataRemover::REMOVE_COOKIES, tester.get());
+
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1,
+ quota::kStorageTypeTemporary));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2,
+ quota::kStorageTypeTemporary));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin3,
+ quota::kStorageTypeTemporary));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1,
+ quota::kStorageTypePersistent));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2,
+ quota::kStorageTypePersistent));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin3,
+ quota::kStorageTypePersistent));
+}
+
+TEST_F(BrowsingDataRemoverTest, RemoveQuotaManagedDataForLastHour) {
+ scoped_ptr<RemoveQuotaManagedDataTester> tester(
+ new RemoveQuotaManagedDataTester());
+ tester->PopulateTestQuotaManagedData(GetMockManager());
+
+ BlockUntilBrowsingDataRemoved(BrowsingDataRemover::LAST_HOUR,
+ base::Time::Now(), BrowsingDataRemover::REMOVE_COOKIES, tester.get());
+
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1,
+ quota::kStorageTypeTemporary));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2,
+ quota::kStorageTypeTemporary));
+ EXPECT_TRUE(GetMockManager()->OriginHasData(kOrigin3,
+ quota::kStorageTypeTemporary));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1,
+ quota::kStorageTypePersistent));
+ EXPECT_TRUE(GetMockManager()->OriginHasData(kOrigin2,
+ quota::kStorageTypePersistent));
+ EXPECT_TRUE(GetMockManager()->OriginHasData(kOrigin3,
+ quota::kStorageTypePersistent));
+}
+
+TEST_F(BrowsingDataRemoverTest, RemoveQuotaManagedDataForLastWeek) {
+ scoped_ptr<RemoveQuotaManagedDataTester> tester(
+ new RemoveQuotaManagedDataTester());
+ tester->PopulateTestQuotaManagedData(GetMockManager());
+
+ BlockUntilBrowsingDataRemoved(BrowsingDataRemover::LAST_WEEK,
+ base::Time::Now(), BrowsingDataRemover::REMOVE_COOKIES, tester.get());
+
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1,
+ quota::kStorageTypeTemporary));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2,
+ quota::kStorageTypeTemporary));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin3,
+ quota::kStorageTypeTemporary));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1,
+ quota::kStorageTypePersistent));
+ EXPECT_TRUE(GetMockManager()->OriginHasData(kOrigin2,
+ quota::kStorageTypePersistent));
+ EXPECT_TRUE(GetMockManager()->OriginHasData(kOrigin3,
+ quota::kStorageTypePersistent));
+}
+
+TEST_F(BrowsingDataRemoverTest, RemoveQuotaManagedUnprotectedOrigins) {
+ // Protect kOrigin1.
scoped_refptr<MockExtensionSpecialStoragePolicy> mock_policy =
- new MockExtensionSpecialStoragePolicy;
- mock_policy->AddProtected(kProtectedManifest.GetOrigin());
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- NewRunnableMethod(appcache_service.get(),
- &ChromeAppCacheService::InitializeOnIOThread,
- FilePath(),
- resource_context,
- mock_policy));
- MessageLoop::current()->RunAllPending();
- TestingProfile* profile = GetProfile();
- profile->SetAppCacheService(appcache_service);
- profile->SetExtensionSpecialStoragePolicy(mock_policy);
-
- // Add data into the AppCacheStorage.
- appcache::AppCacheTestHelper appcache_helper;
- appcache_helper.AddGroupAndCache(appcache_service, kNormalManifest);
- appcache_helper.AddGroupAndCache(appcache_service, kProtectedManifest);
-
- // Verify that adding the data succeeded.
- std::set<GURL> origins;
- appcache_helper.GetOriginsWithCaches(appcache_service, &origins);
- EXPECT_EQ(2UL, origins.size());
- EXPECT_TRUE(origins.find(kProtectedManifest.GetOrigin()) != origins.end());
- EXPECT_TRUE(origins.find(kNormalManifest.GetOrigin()) != origins.end());
-
- // Set up the object to be tested.
- scoped_ptr<BrowsingDataRemoverTester> tester(new BrowsingDataRemoverTester());
- BrowsingDataRemover* remover = new BrowsingDataRemover(
- profile, BrowsingDataRemover::EVERYTHING, base::Time::Now());
- remover->AddObserver(tester.get());
-
- // Remove the appcaches and wait for it to complete. BrowsingDataRemover
- // deletes itself when it completes.
- remover->Remove(BrowsingDataRemover::REMOVE_COOKIES);
- tester->BlockUntilNotified();
-
- // Results: appcaches for the normal origin got deleted, appcaches for the
- // protected origin didn't.
- appcache_helper.GetOriginsWithCaches(appcache_service, &origins);
- EXPECT_EQ(1UL, origins.size());
- EXPECT_TRUE(origins.find(kProtectedManifest.GetOrigin()) != origins.end());
+ new MockExtensionSpecialStoragePolicy;
+ mock_policy->AddProtected(kOrigin1.GetOrigin());
+ GetProfile()->SetExtensionSpecialStoragePolicy(mock_policy);
+
+ scoped_ptr<RemoveQuotaManagedDataTester> tester(
+ new RemoveQuotaManagedDataTester());
+ tester->PopulateTestQuotaManagedData(GetMockManager());
+
+ BlockUntilBrowsingDataRemoved(BrowsingDataRemover::EVERYTHING,
+ base::Time::Now(), BrowsingDataRemover::REMOVE_COOKIES, tester.get());
+
+ EXPECT_TRUE(GetMockManager()->OriginHasData(kOrigin1,
+ quota::kStorageTypeTemporary));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2,
+ quota::kStorageTypeTemporary));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin3,
+ quota::kStorageTypeTemporary));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1,
+ quota::kStorageTypePersistent));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2,
+ quota::kStorageTypePersistent));
+ EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin3,
+ quota::kStorageTypePersistent));
}
} // namespace
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index 44fc2cd..dbb77d5 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -678,12 +678,6 @@ ProfileImpl::~ProfileImpl() {
ProfileDependencyManager::GetInstance()->DestroyProfileServices(this);
- if (clear_local_state_on_exit_) {
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableFunction(&BrowsingDataRemover::ClearGearsData, path_));
- }
-
if (db_tracker_) {
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 2a47e6b..ba48e5c 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -220,6 +220,8 @@
'../ui/gfx/image/image_unittest_util.cc',
'../webkit/appcache/appcache_test_helper.cc',
'../webkit/appcache/appcache_test_helper.h',
+ '../webkit/quota/mock_quota_manager.cc',
+ '../webkit/quota/mock_quota_manager.h',
'../webkit/quota/mock_special_storage_policy.cc',
'../webkit/quota/mock_special_storage_policy.h',
],
diff --git a/chrome/test/testing_profile.cc b/chrome/test/testing_profile.cc
index 0fc134b..717f236 100644
--- a/chrome/test/testing_profile.cc
+++ b/chrome/test/testing_profile.cc
@@ -59,6 +59,7 @@
#include "webkit/database/database_tracker.h"
#include "webkit/fileapi/file_system_context.h"
#include "webkit/quota/quota_manager.h"
+#include "webkit/quota/mock_quota_manager.h"
using base::Time;
using testing::NiceMock;
@@ -543,8 +544,12 @@ fileapi::FileSystemContext* TestingProfile::GetFileSystemContext() {
return file_system_context_.get();
}
+void TestingProfile::SetQuotaManager(quota::QuotaManager* manager) {
+ quota_manager_ = manager;
+}
+
quota::QuotaManager* TestingProfile::GetQuotaManager() {
- return NULL;
+ return quota_manager_.get();
}
BrowserSignin* TestingProfile::GetBrowserSignin() {
diff --git a/chrome/test/testing_profile.h b/chrome/test/testing_profile.h
index 07977bc..47e6d5e 100644
--- a/chrome/test/testing_profile.h
+++ b/chrome/test/testing_profile.h
@@ -182,6 +182,7 @@ class TestingProfile : public Profile {
virtual DownloadManager* GetDownloadManager();
virtual PersonalDataManager* GetPersonalDataManager();
virtual fileapi::FileSystemContext* GetFileSystemContext();
+ virtual void SetQuotaManager(quota::QuotaManager* manager);
virtual quota::QuotaManager* GetQuotaManager();
virtual BrowserSignin* GetBrowserSignin();
virtual bool HasCreatedDownloadManager() const;
@@ -390,6 +391,9 @@ class TestingProfile : public Profile {
ProfileDependencyManager* profile_dependency_manager_;
scoped_refptr<ChromeAppCacheService> appcache_service_;
+
+ // The QuotaManager, only available if set explicitly via SetQuotaManager.
+ scoped_refptr<quota::QuotaManager> quota_manager_;
};
#endif // CHROME_TEST_TESTING_PROFILE_H_