summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormichaeln@google.com <michaeln@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-26 00:28:43 +0000
committermichaeln@google.com <michaeln@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-26 00:28:43 +0000
commit19eb8015c483fff874bf1eddb80bd26cf4167f33 (patch)
treebe896411dde17d24eb8dbcd67e7b4c5cad2ef1b6
parentf02074331bddc7d89b20e6b3a8fb934e6891207c (diff)
downloadchromium_src-19eb8015c483fff874bf1eddb80bd26cf4167f33.zip
chromium_src-19eb8015c483fff874bf1eddb80bd26cf4167f33.tar.gz
chromium_src-19eb8015c483fff874bf1eddb80bd26cf4167f33.tar.bz2
Add an accessor for an ExtensionSpecialStoragePolicy to the Profile class
and use it in the extension service, data remover, and storage subsystems. BUG=52357 TEST=extension_service_unittest.cc Review URL: http://codereview.chromium.org/6551028 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@76126 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/browsing_data_remover.cc67
-rw-r--r--chrome/browser/browsing_data_remover.h17
-rw-r--r--chrome/browser/extensions/extension_service.cc147
-rw-r--r--chrome/browser/extensions/extension_service.h22
-rw-r--r--chrome/browser/extensions/extension_service_unittest.cc54
-rw-r--r--chrome/browser/profiles/profile.cc38
-rw-r--r--chrome/browser/profiles/profile.h5
-rw-r--r--chrome/browser/profiles/profile_impl.cc24
-rw-r--r--chrome/browser/profiles/profile_impl.h3
-rw-r--r--chrome/test/testing_profile.cc14
-rw-r--r--chrome/test/testing_profile.h5
-rw-r--r--content/browser/appcache/chrome_appcache_service.cc16
-rw-r--r--content/browser/appcache/chrome_appcache_service.h7
-rw-r--r--content/browser/appcache/chrome_appcache_service_unittest.cc2
-rw-r--r--content/browser/file_system/browser_file_system_helper.cc4
-rw-r--r--content/browser/file_system/browser_file_system_helper.h7
-rw-r--r--content/browser/in_process_webkit/dom_storage_context.cc36
-rw-r--r--content/browser/in_process_webkit/dom_storage_context.h17
-rw-r--r--content/browser/in_process_webkit/webkit_context.cc14
-rw-r--r--content/browser/in_process_webkit/webkit_context.h4
-rw-r--r--content/browser/in_process_webkit/webkit_context_unittest.cc3
-rw-r--r--webkit/appcache/appcache_service.cc5
-rw-r--r--webkit/appcache/appcache_service.h10
-rw-r--r--webkit/appcache/appcache_storage.cc20
-rw-r--r--webkit/appcache/appcache_storage.h10
-rw-r--r--webkit/appcache/appcache_storage_impl.cc10
-rw-r--r--webkit/appcache/appcache_storage_impl_unittest.cc15
-rw-r--r--webkit/database/database_tracker.cc46
-rw-r--r--webkit/database/database_tracker.h19
-rw-r--r--webkit/database/database_tracker_unittest.cc38
-rw-r--r--webkit/database/database_util.cc7
-rw-r--r--webkit/database/database_util.h1
-rw-r--r--webkit/fileapi/file_system_context.cc13
-rw-r--r--webkit/fileapi/file_system_context.h6
-rw-r--r--webkit/fileapi/file_system_quota_manager.cc31
-rw-r--r--webkit/fileapi/file_system_quota_manager.h14
-rw-r--r--webkit/fileapi/file_system_quota_manager_unittest.cc154
-rw-r--r--webkit/tools/test_shell/simple_database_system.cc2
-rw-r--r--webkit/tools/test_shell/simple_file_system.cc1
-rw-r--r--webkit/tools/test_shell/test_shell.gypi1
40 files changed, 354 insertions, 555 deletions
diff --git a/chrome/browser/browsing_data_remover.cc b/chrome/browser/browsing_data_remover.cc
index 6361e30..f926126 100644
--- a/chrome/browser/browsing_data_remover.cc
+++ b/chrome/browser/browsing_data_remover.cc
@@ -12,6 +12,7 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/download/download_manager.h"
#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/extension_special_storage_policy.h"
#include "chrome/browser/history/history.h"
#include "chrome/browser/io_thread.h"
#include "chrome/browser/metrics/user_metrics.h"
@@ -49,6 +50,7 @@ BrowsingDataRemover::BrowsingDataRemover(Profile* profile,
base::Time delete_begin,
base::Time delete_end)
: profile_(profile),
+ special_storage_policy_(profile->GetExtensionSpecialStoragePolicy()),
delete_begin_(delete_begin),
delete_end_(delete_end),
ALLOW_THIS_IN_INITIALIZER_LIST(database_cleared_callback_(
@@ -76,6 +78,7 @@ BrowsingDataRemover::BrowsingDataRemover(Profile* profile,
TimePeriod time_period,
base::Time delete_end)
: profile_(profile),
+ special_storage_policy_(profile->GetExtensionSpecialStoragePolicy()),
delete_begin_(CalculateBeginDeleteTime(time_period)),
delete_end_(delete_end),
ALLOW_THIS_IN_INITIALIZER_LIST(database_cleared_callback_(
@@ -108,25 +111,6 @@ void BrowsingDataRemover::Remove(int remove_mask) {
DCHECK(!removing_);
removing_ = true;
- std::vector<GURL> origin_whitelist;
- ExtensionService* extensions_service = profile_->GetExtensionService();
- if (extensions_service && extensions_service->HasInstalledExtensions()) {
- std::map<GURL, int> whitelist_map =
- extensions_service->protected_storage_map();
- for (std::map<GURL, int>::const_iterator iter = whitelist_map.begin();
- iter != whitelist_map.end(); ++iter) {
- origin_whitelist.push_back(iter->first);
- }
- }
-
- std::vector<string16> webkit_db_whitelist;
- for (size_t i = 0; i < origin_whitelist.size(); ++i) {
- webkit_db_whitelist.push_back(
- webkit_database::DatabaseUtil::GetOriginIdentifier(
- origin_whitelist[i]));
- }
-
-
if (remove_mask & REMOVE_HISTORY) {
HistoryService* history_service =
profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
@@ -194,8 +178,9 @@ void BrowsingDataRemover::Remove(int remove_mask) {
// REMOVE_COOKIES is actually "cookies and other site data" so we make sure
// to remove other data such local databases, STS state, etc.
- profile_->GetWebKitContext()->DeleteDataModifiedSince(
- delete_begin_, chrome::kExtensionScheme, webkit_db_whitelist);
+ // We assume the end time is now.
+
+ profile_->GetWebKitContext()->DeleteDataModifiedSince(delete_begin_);
database_tracker_ = profile_->GetDatabaseTracker();
if (database_tracker_.get()) {
@@ -204,26 +189,24 @@ void BrowsingDataRemover::Remove(int remove_mask) {
BrowserThread::FILE, FROM_HERE,
NewRunnableMethod(
this,
- &BrowsingDataRemover::ClearDatabasesOnFILEThread,
- delete_begin_,
- webkit_db_whitelist));
+ &BrowsingDataRemover::ClearDatabasesOnFILEThread));
}
+ waiting_for_clear_appcache_ = true;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
NewRunnableMethod(
- profile_->GetTransportSecurityState(),
- &net::TransportSecurityState::DeleteSince,
- delete_begin_));
+ this,
+ &BrowsingDataRemover::ClearAppCacheOnIOThread));
+
+ // TODO(michaeln): delete temporary file system data too
- waiting_for_clear_appcache_ = true;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
NewRunnableMethod(
- this,
- &BrowsingDataRemover::ClearAppCacheOnIOThread,
- delete_begin_, // we assume end time == now
- origin_whitelist));
+ profile_->GetTransportSecurityState(),
+ &net::TransportSecurityState::DeleteSince,
+ delete_begin_));
}
if (remove_mask & REMOVE_PASSWORDS) {
@@ -464,13 +447,11 @@ void BrowsingDataRemover::OnClearedDatabases(int rv) {
NotifyAndDeleteIfDone();
}
-void BrowsingDataRemover::ClearDatabasesOnFILEThread(base::Time delete_begin,
- const std::vector<string16>& webkit_db_whitelist) {
+void BrowsingDataRemover::ClearDatabasesOnFILEThread() {
// This function should be called on the FILE thread.
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
-
int rv = database_tracker_->DeleteDataModifiedSince(
- delete_begin, webkit_db_whitelist, &database_cleared_callback_);
+ delete_begin_, &database_cleared_callback_);
if (rv != net::ERR_IO_PENDING)
OnClearedDatabases(rv);
}
@@ -483,17 +464,13 @@ void BrowsingDataRemover::OnClearedAppCache() {
DCHECK(result);
return;
}
- appcache_whitelist_.clear();
waiting_for_clear_appcache_ = false;
NotifyAndDeleteIfDone();
}
-void BrowsingDataRemover::ClearAppCacheOnIOThread(base::Time delete_begin,
- const std::vector<GURL>& origin_whitelist) {
+void BrowsingDataRemover::ClearAppCacheOnIOThread() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
DCHECK(waiting_for_clear_appcache_);
-
- appcache_whitelist_ = origin_whitelist;
appcache_info_ = new appcache::AppCacheInfoCollection;
GetAppCacheService()->GetAllAppCacheInfo(
appcache_info_, &appcache_got_info_callback_);
@@ -507,14 +484,8 @@ void BrowsingDataRemover::OnGotAppCacheInfo(int rv) {
for (InfoByOrigin::const_iterator origin =
appcache_info_->infos_by_origin.begin();
origin != appcache_info_->infos_by_origin.end(); ++origin) {
- bool found_in_whitelist = false;
- for (size_t i = 0; i < appcache_whitelist_.size(); ++i) {
- if (appcache_whitelist_[i] == origin->first)
- found_in_whitelist = true;
- }
- if (found_in_whitelist)
+ if (special_storage_policy_->IsStorageProtected(origin->first))
continue;
-
for (AppCacheInfoVector::const_iterator info = origin->second.begin();
info != origin->second.end(); ++info) {
if (info->creation_time > delete_begin_) {
diff --git a/chrome/browser/browsing_data_remover.h b/chrome/browser/browsing_data_remover.h
index f9667ca..56d19dd7 100644
--- a/chrome/browser/browsing_data_remover.h
+++ b/chrome/browser/browsing_data_remover.h
@@ -16,6 +16,7 @@
#include "content/browser/appcache/chrome_appcache_service.h"
#include "content/browser/cancelable_request.h"
+class ExtensionSpecialStoragePolicy;
class IOThread;
class PluginDataRemover;
class Profile;
@@ -138,19 +139,15 @@ class BrowsingDataRemover : public NotificationObserver,
// NotifyAndDeleteIfDone.
void OnClearedDatabases(int rv);
- // Invoked on the FILE thread to delete HTML5 databases. Ignores any within
- // the |webkit_db_whitelist|.
- void ClearDatabasesOnFILEThread(base::Time delete_begin,
- const std::vector<string16>& webkit_db_whitelist);
+ // Invoked on the FILE thread to delete HTML5 databases.
+ void ClearDatabasesOnFILEThread();
// Callback when the appcache has been cleared. Invokes
// NotifyAndDeleteIfDone.
void OnClearedAppCache();
- // Invoked on the IO thread to delete from the AppCache, ignoring data from
- // any origins within the |origin_whitelist|.
- void ClearAppCacheOnIOThread(base::Time delete_begin,
- const std::vector<GURL>& origin_whitelist);
+ // Invoked on the IO thread to delete from the AppCache.
+ void ClearAppCacheOnIOThread();
// Lower level helpers.
void OnGotAppCacheInfo(int rv);
@@ -174,6 +171,9 @@ class BrowsingDataRemover : public NotificationObserver,
// Profile we're to remove from.
Profile* profile_;
+ // 'Protected' origins are not subject to data removal.
+ scoped_refptr<ExtensionSpecialStoragePolicy> special_storage_policy_;
+
// Start time to delete from.
const base::Time delete_begin_;
@@ -193,7 +193,6 @@ class BrowsingDataRemover : public NotificationObserver,
net::CompletionCallbackImpl<BrowsingDataRemover> appcache_got_info_callback_;
net::CompletionCallbackImpl<BrowsingDataRemover> appcache_deleted_callback_;
scoped_refptr<appcache::AppCacheInfoCollection> appcache_info_;
- std::vector<GURL> appcache_whitelist_;
int appcaches_to_be_deleted_count_;
// Used to delete data from the HTTP caches.
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index 5a19f48..b3bb620 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -37,6 +37,7 @@
#include "chrome/browser/extensions/extension_management_api.h"
#include "chrome/browser/extensions/extension_process_manager.h"
#include "chrome/browser/extensions/extension_processes_api.h"
+#include "chrome/browser/extensions/extension_special_storage_policy.h"
#include "chrome/browser/extensions/extension_updater.h"
#include "chrome/browser/extensions/extension_web_ui.h"
#include "chrome/browser/extensions/extension_webnavigation_api.h"
@@ -106,35 +107,6 @@ ManifestReloadReason ShouldReloadExtensionManifest(const ExtensionInfo& info) {
return NOT_NEEDED;
}
-void GetExplicitOriginsInExtent(const Extension* extension,
- std::vector<GURL>* origins) {
- typedef std::vector<URLPattern> PatternList;
- std::set<GURL> set;
- const PatternList& patterns = extension->web_extent().patterns();
- for (PatternList::const_iterator pattern = patterns.begin();
- pattern != patterns.end(); ++pattern) {
- if (pattern->match_subdomains() || pattern->match_all_urls())
- continue;
- // Wildcard URL schemes won't parse into a valid GURL, so explicit schemes
- // must be used.
- PatternList explicit_patterns = pattern->ConvertToExplicitSchemes();
- for (PatternList::const_iterator explicit_p = explicit_patterns.begin();
- explicit_p != explicit_patterns.end(); ++explicit_p) {
- GURL origin = GURL(explicit_p->GetAsString()).GetOrigin();
- if (origin.is_valid()) {
- set.insert(origin);
- } else {
- NOTREACHED();
- }
- }
- }
-
- for (std::set<GURL>::const_iterator unique = set.begin();
- unique != set.end(); ++unique) {
- origins->push_back(*unique);
- }
-}
-
} // namespace
PendingExtensionInfo::PendingExtensionInfo(
@@ -1090,15 +1062,8 @@ void ExtensionService::NotifyExtensionLoaded(const Extension* extension) {
// extension.
if (profile_) {
profile_->RegisterExtensionWithRequestContexts(extension);
-
- // Check if this permission requires unlimited storage quota
- if (extension->HasApiPermission(Extension::kUnlimitedStoragePermission))
- GrantUnlimitedStorage(extension);
-
- // If the extension is an app, protect its local storage from
- // "Clear browsing data."
- if (extension->is_app())
- GrantProtectedStorage(extension);
+ profile_->GetExtensionSpecialStoragePolicy()->
+ GrantRightsForExtension(extension);
}
NotificationService::current()->Notify(
@@ -1117,106 +1082,8 @@ void ExtensionService::NotifyExtensionUnloaded(
if (profile_) {
profile_->UnregisterExtensionWithRequestContexts(extension);
-
- // Check if this permission required unlimited storage quota, reset its
- // in-memory quota.
- if (extension->HasApiPermission(Extension::kUnlimitedStoragePermission))
- RevokeUnlimitedStorage(extension);
-
- // If this is an app, then stop protecting its storage so it can be deleted.
- if (extension->is_app())
- RevokeProtectedStorage(extension);
- }
-}
-
-void ExtensionService::GrantProtectedStorage(const Extension* extension) {
- DCHECK(extension->is_app()) << "Only Apps are allowed protected storage.";
- std::vector<GURL> origins;
- GetExplicitOriginsInExtent(extension, &origins);
- for (size_t i = 0; i < origins.size(); ++i)
- ++protected_storage_map_[origins[i]];
-}
-
-void ExtensionService::RevokeProtectedStorage(const Extension* extension) {
- DCHECK(extension->is_app()) << "Attempting to revoke protected storage from "
- << " a non-app extension.";
- std::vector<GURL> origins;
- GetExplicitOriginsInExtent(extension, &origins);
- for (size_t i = 0; i < origins.size(); ++i) {
- const GURL& origin = origins[i];
- DCHECK(protected_storage_map_[origin] > 0);
- if (--protected_storage_map_[origin] <= 0)
- protected_storage_map_.erase(origin);
- }
-}
-
-void ExtensionService::GrantUnlimitedStorage(const Extension* extension) {
- DCHECK(extension->HasApiPermission(Extension::kUnlimitedStoragePermission));
- std::vector<GURL> origins;
- GetExplicitOriginsInExtent(extension, &origins);
- origins.push_back(extension->url());
-
- for (size_t i = 0; i < origins.size(); ++i) {
- const GURL& origin = origins[i];
- if (++unlimited_storage_map_[origin] == 1) {
- string16 origin_identifier =
- webkit_database::DatabaseUtil::GetOriginIdentifier(origin);
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(
- profile_->GetDatabaseTracker(),
- &webkit_database::DatabaseTracker::SetOriginQuotaInMemory,
- origin_identifier,
- kint64max));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- NewRunnableMethod(
- profile_->GetAppCacheService(),
- &ChromeAppCacheService::SetOriginQuotaInMemory,
- origin,
- kint64max));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- NewRunnableMethod(
- profile_->GetFileSystemContext(),
- &fileapi::FileSystemContext::SetOriginQuotaUnlimited,
- origin));
- }
- }
-}
-
-void ExtensionService::RevokeUnlimitedStorage(const Extension* extension) {
- DCHECK(extension->HasApiPermission(Extension::kUnlimitedStoragePermission));
- std::vector<GURL> origins;
- GetExplicitOriginsInExtent(extension, &origins);
- origins.push_back(extension->url());
-
- for (size_t i = 0; i < origins.size(); ++i) {
- const GURL& origin = origins[i];
- DCHECK(unlimited_storage_map_[origin] > 0);
- if (--unlimited_storage_map_[origin] == 0) {
- unlimited_storage_map_.erase(origin);
- string16 origin_identifier =
- webkit_database::DatabaseUtil::GetOriginIdentifier(origin);
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(
- profile_->GetDatabaseTracker(),
- &webkit_database::DatabaseTracker::ResetOriginQuotaInMemory,
- origin_identifier));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- NewRunnableMethod(
- profile_->GetAppCacheService(),
- &ChromeAppCacheService::ResetOriginQuotaInMemory,
- origin));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- NewRunnableMethod(
- profile_->GetFileSystemContext(),
- &fileapi::FileSystemContext::ResetOriginQuotaUnlimited,
- origin));
- }
+ profile_->GetExtensionSpecialStoragePolicy()->
+ RevokeRightsForExtension(extension);
}
}
@@ -1454,6 +1321,10 @@ void ExtensionService::UnloadExtension(
}
void ExtensionService::UnloadAllExtensions() {
+ if (profile_) {
+ profile_->GetExtensionSpecialStoragePolicy()->
+ RevokeRightsForAllExtensions();
+ }
extensions_.clear();
disabled_extensions_.clear();
terminated_extension_ids_.clear();
diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h
index 67a59be..402f644 100644
--- a/chrome/browser/extensions/extension_service.h
+++ b/chrome/browser/extensions/extension_service.h
@@ -408,10 +408,6 @@ class ExtensionService
return browser_event_router_.get();
}
- const std::map<GURL, int>& protected_storage_map() const {
- return protected_storage_map_;
- }
-
// Notify the frontend that there was an error loading an extension.
// This method is public because ExtensionServiceBackend can post to here.
void ReportExtensionLoadError(const FilePath& extension_path,
@@ -516,12 +512,6 @@ class ExtensionService
// Helper method. Loads extension from prefs.
void LoadInstalledExtension(const ExtensionInfo& info, bool write_to_prefs);
- // Helper methods to configure the storage services accordingly.
- void GrantProtectedStorage(const Extension* extension);
- void RevokeProtectedStorage(const Extension* extension);
- void GrantUnlimitedStorage(const Extension* extension);
- void RevokeUnlimitedStorage(const Extension* extension);
-
// The profile this ExtensionService is part of.
Profile* profile_;
@@ -603,18 +593,6 @@ class ExtensionService
typedef std::vector<ComponentExtensionInfo> RegisteredComponentExtensions;
RegisteredComponentExtensions component_extension_manifests_;
- // Collection of origins we've granted unlimited storage to. This is a
- // map from origin to the number of extensions requiring unlimited
- // storage within that origin.
- typedef std::map<GURL, int> UnlimitedStorageMap;
- UnlimitedStorageMap unlimited_storage_map_;
-
- // Collection of origins whose storage is protected by "Clear browsing data."
- // A map from origin to the number of Apps currently installed and therefore
- // intrinsically protected.
- typedef std::map<GURL, int> ProtectedStorageMap;
- ProtectedStorageMap protected_storage_map_;
-
// Manages the installation of default apps and the promotion of them in the
// app launcher.
DefaultApps default_apps_;
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc
index c5d35e6..b2b1623 100644
--- a/chrome/browser/extensions/extension_service_unittest.cc
+++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -26,6 +26,7 @@
#include "chrome/browser/extensions/extension_creator.h"
#include "chrome/browser/extensions/extension_error_reporter.h"
#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/extension_special_storage_policy.h"
#include "chrome/browser/extensions/external_extension_provider_interface.h"
#include "chrome/browser/extensions/external_extension_provider_impl.h"
#include "chrome/browser/extensions/external_pref_extension_loader.h"
@@ -341,11 +342,13 @@ class ExtensionTestingProfile : public TestingProfile {
appcache_service_ = new ChromeAppCacheService;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
- NewRunnableMethod(appcache_service_.get(),
- &ChromeAppCacheService::InitializeOnIOThread,
- GetPath(), IsOffTheRecord(),
- make_scoped_refptr(GetHostContentSettingsMap()),
- false));
+ NewRunnableMethod(
+ appcache_service_.get(),
+ &ChromeAppCacheService::InitializeOnIOThread,
+ GetPath(), IsOffTheRecord(),
+ make_scoped_refptr(GetHostContentSettingsMap()),
+ make_scoped_refptr(GetExtensionSpecialStoragePolicy()),
+ false));
}
return appcache_service_;
}
@@ -353,7 +356,7 @@ class ExtensionTestingProfile : public TestingProfile {
virtual fileapi::FileSystemContext* GetFileSystemContext() {
if (!file_system_context_)
file_system_context_ = CreateFileSystemContext(
- GetPath(), IsOffTheRecord());
+ GetPath(), IsOffTheRecord(), GetExtensionSpecialStoragePolicy());
return file_system_context_;
}
@@ -1674,13 +1677,11 @@ TEST_F(ExtensionServiceTest, UpdateApps) {
TEST_F(ExtensionServiceTest, InstallAppsWithUnlimtedStorage) {
InitializeEmptyExtensionService();
EXPECT_TRUE(service_->extensions()->empty());
- EXPECT_TRUE(service_->unlimited_storage_map_.empty());
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
int pref_count = 0;
- ChromeAppCacheService* appcache_service = profile_->GetAppCacheService();
// Install app1 with unlimited storage.
PackAndInstallExtension(extensions_path.AppendASCII("app1"), true);
@@ -1693,9 +1694,8 @@ TEST_F(ExtensionServiceTest, InstallAppsWithUnlimtedStorage) {
EXPECT_TRUE(extension->web_extent().ContainsURL(
extension->GetFullLaunchURL()));
const GURL origin1(extension->GetFullLaunchURL().GetOrigin());
- EXPECT_EQ(kint64max,
- appcache_service->storage()->GetOriginQuotaInMemory(origin1));
- EXPECT_FALSE(service_->unlimited_storage_map_.empty());
+ EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
+ IsStorageUnlimited(origin1));
// Install app2 from the same origin with unlimited storage.
PackAndInstallExtension(extensions_path.AppendASCII("app2"), true);
@@ -1709,32 +1709,30 @@ TEST_F(ExtensionServiceTest, InstallAppsWithUnlimtedStorage) {
extension->GetFullLaunchURL()));
const GURL origin2(extension->GetFullLaunchURL().GetOrigin());
EXPECT_EQ(origin1, origin2);
- EXPECT_EQ(kint64max,
- appcache_service->storage()->GetOriginQuotaInMemory(origin2));
- EXPECT_FALSE(service_->unlimited_storage_map_.empty());
+ EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
+ IsStorageUnlimited(origin2));
+
// Uninstall one of them, unlimited storage should still be granted
// to the origin.
service_->UninstallExtension(id1, false);
loop_.RunAllPending();
EXPECT_EQ(1u, service_->extensions()->size());
- EXPECT_EQ(kint64max,
- appcache_service->storage()->GetOriginQuotaInMemory(origin1));
- EXPECT_FALSE(service_->unlimited_storage_map_.empty());
+ EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
+ IsStorageUnlimited(origin1));
+
// Uninstall the other, unlimited storage should be revoked.
service_->UninstallExtension(id2, false);
loop_.RunAllPending();
EXPECT_EQ(0u, service_->extensions()->size());
- EXPECT_EQ(-1L,
- appcache_service->storage()->GetOriginQuotaInMemory(origin2));
- EXPECT_TRUE(service_->unlimited_storage_map_.empty());
+ EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
+ IsStorageUnlimited(origin2));
}
TEST_F(ExtensionServiceTest, InstallAppsAndCheckStorageProtection) {
InitializeEmptyExtensionService();
EXPECT_TRUE(service_->extensions()->empty());
- EXPECT_TRUE(service_->protected_storage_map_.empty());
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
@@ -1747,9 +1745,9 @@ TEST_F(ExtensionServiceTest, InstallAppsAndCheckStorageProtection) {
const Extension* extension = service_->extensions()->at(0);
EXPECT_TRUE(extension->is_app());
const std::string id1 = extension->id();
- EXPECT_FALSE(service_->protected_storage_map_.empty());
const GURL origin1(extension->GetFullLaunchURL().GetOrigin());
- ASSERT_EQ(1, service_->protected_storage_map_[origin1]);
+ EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
+ IsStorageProtected(origin1));
// App 4 has a different origin (maps.google.com).
PackAndInstallExtension(extensions_path.AppendASCII("app4"), true);
@@ -1757,21 +1755,23 @@ TEST_F(ExtensionServiceTest, InstallAppsAndCheckStorageProtection) {
ASSERT_EQ(2u, service_->extensions()->size());
extension = service_->extensions()->at(1);
const std::string id2 = extension->id();
- EXPECT_FALSE(service_->protected_storage_map_.empty());
const GURL origin2(extension->GetFullLaunchURL().GetOrigin());
ASSERT_NE(origin1, origin2);
- ASSERT_EQ(1, service_->protected_storage_map_[origin2]);
+ EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
+ IsStorageProtected(origin2));
service_->UninstallExtension(id1, false);
loop_.RunAllPending();
EXPECT_EQ(1u, service_->extensions()->size());
- EXPECT_FALSE(service_->protected_storage_map_.empty());
service_->UninstallExtension(id2, false);
loop_.RunAllPending();
EXPECT_TRUE(service_->extensions()->empty());
- EXPECT_TRUE(service_->protected_storage_map_.empty());
+ EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
+ IsStorageProtected(origin1));
+ EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
+ IsStorageProtected(origin2));
}
// Test that when an extension version is reinstalled, nothing happens.
diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc
index db1579b..3d202cd 100644
--- a/chrome/browser/profiles/profile.cc
+++ b/chrome/browser/profiles/profile.cc
@@ -22,6 +22,7 @@
#include "chrome/browser/extensions/extension_message_service.h"
#include "chrome/browser/extensions/extension_pref_store.h"
#include "chrome/browser/extensions/extension_process_manager.h"
+#include "chrome/browser/extensions/extension_special_storage_policy.h"
#include "chrome/browser/net/pref_proxy_config_service.h"
#include "chrome/browser/notifications/desktop_notification_service.h"
#include "chrome/browser/prefs/pref_service.h"
@@ -157,9 +158,7 @@ class OffTheRecordProfileImpl : public Profile,
: profile_(real_profile),
prefs_(real_profile->GetOffTheRecordPrefs()),
ALLOW_THIS_IN_INITIALIZER_LIST(io_data_(this)),
- start_time_(Time::Now()),
- db_tracker_(new webkit_database::DatabaseTracker(
- profile_->GetPath(), true)) {
+ start_time_(Time::Now()) {
extension_process_manager_.reset(ExtensionProcessManager::Create(this));
BrowserList::AddObserver(this);
@@ -183,11 +182,12 @@ class OffTheRecordProfileImpl : public Profile,
Source<Profile>(this),
NotificationService::NoDetails());
// Clean up all DB files/directories
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(
- db_tracker_.get(),
- &webkit_database::DatabaseTracker::DeleteIncognitoDBDirectory));
+ if (db_tracker_)
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ NewRunnableMethod(
+ db_tracker_.get(),
+ &webkit_database::DatabaseTracker::DeleteIncognitoDBDirectory));
BrowserList::RemoveObserver(this);
@@ -227,16 +227,22 @@ class OffTheRecordProfileImpl : public Profile,
appcache_service_ = new ChromeAppCacheService;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
- NewRunnableMethod(appcache_service_.get(),
- &ChromeAppCacheService::InitializeOnIOThread,
- GetPath(), IsOffTheRecord(),
- make_scoped_refptr(GetHostContentSettingsMap()),
- false));
+ NewRunnableMethod(
+ appcache_service_.get(),
+ &ChromeAppCacheService::InitializeOnIOThread,
+ GetPath(), IsOffTheRecord(),
+ make_scoped_refptr(GetHostContentSettingsMap()),
+ make_scoped_refptr(GetExtensionSpecialStoragePolicy()),
+ false));
}
return appcache_service_;
}
virtual webkit_database::DatabaseTracker* GetDatabaseTracker() {
+ if (!db_tracker_.get()) {
+ db_tracker_ = new webkit_database::DatabaseTracker(
+ GetPath(), IsOffTheRecord(), GetExtensionSpecialStoragePolicy());
+ }
return db_tracker_;
}
@@ -284,6 +290,10 @@ class OffTheRecordProfileImpl : public Profile,
return GetOriginalProfile()->GetExtensionIOEventRouter();
}
+ virtual ExtensionSpecialStoragePolicy* GetExtensionSpecialStoragePolicy() {
+ return GetOriginalProfile()->GetExtensionSpecialStoragePolicy();
+ }
+
virtual SSLHostState* GetSSLHostState() {
if (!ssl_host_state_.get())
ssl_host_state_.reset(new SSLHostState());
@@ -380,7 +390,7 @@ class OffTheRecordProfileImpl : public Profile,
virtual fileapi::FileSystemContext* GetFileSystemContext() {
if (!file_system_context_)
file_system_context_ = CreateFileSystemContext(
- GetPath(), IsOffTheRecord());
+ GetPath(), IsOffTheRecord(), GetExtensionSpecialStoragePolicy());
DCHECK(file_system_context_.get());
return file_system_context_.get();
}
diff --git a/chrome/browser/profiles/profile.h b/chrome/browser/profiles/profile.h
index 42252da..c45b072 100644
--- a/chrome/browser/profiles/profile.h
+++ b/chrome/browser/profiles/profile.h
@@ -68,6 +68,7 @@ class ExtensionMessageService;
class ExtensionPrefValueMap;
class ExtensionProcessManager;
class ExtensionService;
+class ExtensionSpecialStoragePolicy;
class FaviconService;
class FilePath;
class FindBarState;
@@ -229,6 +230,10 @@ class Profile {
// Accessor. The instance is created at startup.
virtual ExtensionIOEventRouter* GetExtensionIOEventRouter() = 0;
+ // Accessor. The instance is created upon first access.
+ virtual ExtensionSpecialStoragePolicy*
+ GetExtensionSpecialStoragePolicy() = 0;
+
// Retrieves a pointer to the SSLHostState associated with this profile.
// The SSLHostState is lazily created the first time that this method is
// called.
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index 4b51e82..f639147 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -36,6 +36,7 @@
#include "chrome/browser/extensions/extension_pref_store.h"
#include "chrome/browser/extensions/extension_process_manager.h"
#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/extension_special_storage_policy.h"
#include "chrome/browser/extensions/user_script_master.h"
#include "chrome/browser/favicon_service.h"
#include "chrome/browser/geolocation/geolocation_content_settings_map.h"
@@ -642,11 +643,13 @@ ChromeAppCacheService* ProfileImpl::GetAppCacheService() {
appcache_service_ = new ChromeAppCacheService;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
- NewRunnableMethod(appcache_service_.get(),
- &ChromeAppCacheService::InitializeOnIOThread,
- GetPath(), IsOffTheRecord(),
- make_scoped_refptr(GetHostContentSettingsMap()),
- clear_local_state_on_exit_));
+ NewRunnableMethod(
+ appcache_service_.get(),
+ &ChromeAppCacheService::InitializeOnIOThread,
+ GetPath(), IsOffTheRecord(),
+ make_scoped_refptr(GetHostContentSettingsMap()),
+ make_scoped_refptr(GetExtensionSpecialStoragePolicy()),
+ clear_local_state_on_exit_));
}
return appcache_service_;
}
@@ -654,7 +657,7 @@ ChromeAppCacheService* ProfileImpl::GetAppCacheService() {
webkit_database::DatabaseTracker* ProfileImpl::GetDatabaseTracker() {
if (!db_tracker_) {
db_tracker_ = new webkit_database::DatabaseTracker(
- GetPath(), IsOffTheRecord());
+ GetPath(), IsOffTheRecord(), GetExtensionSpecialStoragePolicy());
}
return db_tracker_;
}
@@ -709,6 +712,13 @@ ExtensionIOEventRouter* ProfileImpl::GetExtensionIOEventRouter() {
return extension_io_event_router_.get();
}
+ExtensionSpecialStoragePolicy*
+ ProfileImpl::GetExtensionSpecialStoragePolicy() {
+ if (!extension_special_storage_policy_.get())
+ extension_special_storage_policy_ = new ExtensionSpecialStoragePolicy();
+ return extension_special_storage_policy_.get();
+}
+
SSLHostState* ProfileImpl::GetSSLHostState() {
if (!ssl_host_state_.get())
ssl_host_state_.reset(new SSLHostState());
@@ -1065,7 +1075,7 @@ PersonalDataManager* ProfileImpl::GetPersonalDataManager() {
fileapi::FileSystemContext* ProfileImpl::GetFileSystemContext() {
if (!file_system_context_.get())
file_system_context_ = CreateFileSystemContext(
- GetPath(), IsOffTheRecord());
+ GetPath(), IsOffTheRecord(), GetExtensionSpecialStoragePolicy());
DCHECK(file_system_context_.get());
return file_system_context_.get();
}
diff --git a/chrome/browser/profiles/profile_impl.h b/chrome/browser/profiles/profile_impl.h
index 5eea88cb..ef35079 100644
--- a/chrome/browser/profiles/profile_impl.h
+++ b/chrome/browser/profiles/profile_impl.h
@@ -63,6 +63,7 @@ class ProfileImpl : public Profile,
virtual ExtensionMessageService* GetExtensionMessageService();
virtual ExtensionEventRouter* GetExtensionEventRouter();
virtual ExtensionIOEventRouter* GetExtensionIOEventRouter();
+ virtual ExtensionSpecialStoragePolicy* GetExtensionSpecialStoragePolicy();
virtual FaviconService* GetFaviconService(ServiceAccessType sat);
virtual HistoryService* GetHistoryService(ServiceAccessType sat);
virtual HistoryService* GetHistoryServiceWithoutCreating();
@@ -201,6 +202,8 @@ class ProfileImpl : public Profile,
scoped_refptr<ExtensionMessageService> extension_message_service_;
scoped_ptr<ExtensionEventRouter> extension_event_router_;
scoped_refptr<ExtensionIOEventRouter> extension_io_event_router_;
+ scoped_refptr<ExtensionSpecialStoragePolicy>
+ extension_special_storage_policy_;
scoped_ptr<SSLHostState> ssl_host_state_;
scoped_refptr<net::TransportSecurityState>
transport_security_state_;
diff --git a/chrome/test/testing_profile.cc b/chrome/test/testing_profile.cc
index a9baafd..892a29e 100644
--- a/chrome/test/testing_profile.cc
+++ b/chrome/test/testing_profile.cc
@@ -18,6 +18,7 @@
#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
#include "chrome/browser/extensions/extension_pref_value_map.h"
#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/extension_special_storage_policy.h"
#include "chrome/browser/favicon_service.h"
#include "chrome/browser/geolocation/geolocation_content_settings_map.h"
#include "chrome/browser/geolocation/geolocation_permission_context.h"
@@ -396,8 +397,10 @@ ChromeAppCacheService* TestingProfile::GetAppCacheService() {
}
webkit_database::DatabaseTracker* TestingProfile::GetDatabaseTracker() {
- if (!db_tracker_)
- db_tracker_ = new webkit_database::DatabaseTracker(GetPath(), false);
+ if (!db_tracker_) {
+ db_tracker_ = new webkit_database::DatabaseTracker(
+ GetPath(), false, GetExtensionSpecialStoragePolicy());
+ }
return db_tracker_;
}
@@ -433,6 +436,13 @@ ExtensionIOEventRouter* TestingProfile::GetExtensionIOEventRouter() {
return NULL;
}
+ExtensionSpecialStoragePolicy*
+TestingProfile::GetExtensionSpecialStoragePolicy() {
+ if (!extension_special_storage_policy_)
+ extension_special_storage_policy_ = new ExtensionSpecialStoragePolicy();
+ return extension_special_storage_policy_;
+}
+
SSLHostState* TestingProfile::GetSSLHostState() {
return NULL;
}
diff --git a/chrome/test/testing_profile.h b/chrome/test/testing_profile.h
index a8a610a..5517553 100644
--- a/chrome/test/testing_profile.h
+++ b/chrome/test/testing_profile.h
@@ -28,6 +28,7 @@ class DesktopNotificationService;
class ExtensionPrefs;
class ExtensionPrefStore;
class ExtensionPrefValueMap;
+class ExtensionSpecialStoragePolicy;
class FaviconService;
class FindBarState;
class GeolocationContentSettingsMap;
@@ -153,6 +154,7 @@ class TestingProfile : public Profile {
virtual ExtensionMessageService* GetExtensionMessageService();
virtual ExtensionEventRouter* GetExtensionEventRouter();
virtual ExtensionIOEventRouter* GetExtensionIOEventRouter();
+ virtual ExtensionSpecialStoragePolicy* GetExtensionSpecialStoragePolicy();
virtual SSLHostState* GetSSLHostState();
virtual net::TransportSecurityState* GetTransportSecurityState();
virtual FaviconService* GetFaviconService(ServiceAccessType access);
@@ -392,6 +394,9 @@ class TestingProfile : public Profile {
scoped_ptr<ExtensionPrefValueMap> extension_pref_value_map_;
+ scoped_refptr<ExtensionSpecialStoragePolicy>
+ extension_special_storage_policy_;
+
// The proxy prefs tracker.
scoped_refptr<PrefProxyConfigTracker> pref_proxy_config_tracker_;
diff --git a/content/browser/appcache/chrome_appcache_service.cc b/content/browser/appcache/chrome_appcache_service.cc
index 68c7ece..5f6107a 100644
--- a/content/browser/appcache/chrome_appcache_service.cc
+++ b/content/browser/appcache/chrome_appcache_service.cc
@@ -38,6 +38,7 @@ ChromeAppCacheService::ChromeAppCacheService()
void ChromeAppCacheService::InitializeOnIOThread(
const FilePath& profile_path, bool is_incognito,
scoped_refptr<HostContentSettingsMap> content_settings_map,
+ scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy,
bool clear_local_state_on_exit) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
@@ -57,6 +58,7 @@ void ChromeAppCacheService::InitializeOnIOThread(
Initialize(cache_path_,
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE));
set_appcache_policy(this);
+ set_special_storage_policy(special_storage_policy);
}
ChromeAppCacheService::~ChromeAppCacheService() {
@@ -69,20 +71,8 @@ ChromeAppCacheService::~ChromeAppCacheService() {
}
}
-void ChromeAppCacheService::SetOriginQuotaInMemory(
- const GURL& origin, int64 quota) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- if (storage())
- storage()->SetOriginQuotaInMemory(origin, quota);
-}
-
-void ChromeAppCacheService::ResetOriginQuotaInMemory(const GURL& origin) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- if (storage())
- storage()->ResetOriginQuotaInMemory(origin);
-}
-
void ChromeAppCacheService::SetClearLocalStateOnExit(bool clear_local_state) {
+ // TODO(michaeln): How is 'protected' status granted to apps in this case?
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
diff --git a/content/browser/appcache/chrome_appcache_service.h b/content/browser/appcache/chrome_appcache_service.h
index 8081122..ad77477 100644
--- a/content/browser/appcache/chrome_appcache_service.h
+++ b/content/browser/appcache/chrome_appcache_service.h
@@ -12,6 +12,7 @@
#include "content/browser/browser_thread.h"
#include "webkit/appcache/appcache_policy.h"
#include "webkit/appcache/appcache_service.h"
+#include "webkit/quota/special_storage_policy.h"
class ChromeURLRequestContext;
class FilePath;
@@ -36,13 +37,9 @@ class ChromeAppCacheService
void InitializeOnIOThread(
const FilePath& profile_path, bool is_incognito,
scoped_refptr<HostContentSettingsMap> content_settings_map,
+ scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy,
bool clear_local_state_on_exit);
- // Helpers used by the extension service to grant and revoke
- // unlimited storage to app extensions.
- void SetOriginQuotaInMemory(const GURL& origin, int64 quota);
- void ResetOriginQuotaInMemory(const GURL& origin);
-
void SetClearLocalStateOnExit(bool clear_local_state);
private:
diff --git a/content/browser/appcache/chrome_appcache_service_unittest.cc b/content/browser/appcache/chrome_appcache_service_unittest.cc
index 0c5c512..fb6b80e 100644
--- a/content/browser/appcache/chrome_appcache_service_unittest.cc
+++ b/content/browser/appcache/chrome_appcache_service_unittest.cc
@@ -49,6 +49,7 @@ TEST_F(ChromeAppCacheServiceTest, KeepOnDestruction) {
&ChromeAppCacheService::InitializeOnIOThread,
temp_dir_.path(), false,
scoped_refptr<HostContentSettingsMap>(NULL),
+ scoped_refptr<quota::SpecialStoragePolicy>(NULL),
false));
// Make the steps needed to initialize the storage of AppCache data.
message_loop_.RunAllPending();
@@ -79,6 +80,7 @@ TEST_F(ChromeAppCacheServiceTest, RemoveOnDestruction) {
&ChromeAppCacheService::InitializeOnIOThread,
temp_dir_.path(), false,
scoped_refptr<HostContentSettingsMap>(NULL),
+ scoped_refptr<quota::SpecialStoragePolicy>(NULL),
true));
// Make the steps needed to initialize the storage of AppCache data.
message_loop_.RunAllPending();
diff --git a/content/browser/file_system/browser_file_system_helper.cc b/content/browser/file_system/browser_file_system_helper.cc
index 81666f0..960d838 100644
--- a/content/browser/file_system/browser_file_system_helper.cc
+++ b/content/browser/file_system/browser_file_system_helper.cc
@@ -10,10 +10,12 @@
#include "content/browser/browser_thread.h"
scoped_refptr<fileapi::FileSystemContext> CreateFileSystemContext(
- const FilePath& profile_path, bool is_incognito) {
+ const FilePath& profile_path, bool is_incognito,
+ quota::SpecialStoragePolicy* special_storage_policy) {
return new fileapi::FileSystemContext(
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE),
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
+ special_storage_policy,
profile_path,
is_incognito,
CommandLine::ForCurrentProcess()->HasSwitch(
diff --git a/content/browser/file_system/browser_file_system_helper.h b/content/browser/file_system/browser_file_system_helper.h
index 55c6e3a..84eb26c 100644
--- a/content/browser/file_system/browser_file_system_helper.h
+++ b/content/browser/file_system/browser_file_system_helper.h
@@ -9,9 +9,14 @@
#include "base/scoped_ptr.h"
#include "webkit/fileapi/file_system_context.h"
+namespace quota {
+class SpecialStoragePolicy;
+}
+
// Helper method that returns FileSystemContext constructed for
// the browser process.
scoped_refptr<fileapi::FileSystemContext> CreateFileSystemContext(
- const FilePath& profile_path, bool is_incognito);
+ const FilePath& profile_path, bool is_incognito,
+ quota::SpecialStoragePolicy* special_storage_policy);
#endif // CONTENT_BROWSER_FILE_SYSTEM_BROWSER_FILE_SYSTEM_HELPER_H_
diff --git a/content/browser/in_process_webkit/dom_storage_context.cc b/content/browser/in_process_webkit/dom_storage_context.cc
index c39d75a..184cb24 100644
--- a/content/browser/in_process_webkit/dom_storage_context.cc
+++ b/content/browser/in_process_webkit/dom_storage_context.cc
@@ -9,6 +9,7 @@
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/string_util.h"
+#include "chrome/browser/extensions/extension_special_storage_policy.h"
#include "chrome/common/dom_storage_common.h"
#include "chrome/common/url_constants.h"
#include "content/browser/browser_thread.h"
@@ -17,14 +18,14 @@
#include "content/browser/in_process_webkit/webkit_context.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
+#include "webkit/quota/special_storage_policy.h"
#include "webkit/glue/webkit_glue.h"
using WebKit::WebSecurityOrigin;
namespace {
-void ClearLocalState(const FilePath& domstorage_path,
- const char* url_scheme_to_be_skipped) {
+void ClearLocalState(const FilePath& domstorage_path) {
file_util::FileEnumerator file_enumerator(
domstorage_path, false, file_util::FileEnumerator::FILES);
for (FilePath file_path = file_enumerator.Next(); !file_path.empty();
@@ -33,8 +34,9 @@ void ClearLocalState(const FilePath& domstorage_path,
WebSecurityOrigin web_security_origin =
WebSecurityOrigin::createFromDatabaseIdentifier(
webkit_glue::FilePathToWebString(file_path.BaseName()));
+ // TODO(michaeln): how is protected status provided to apps at this time?
if (!EqualsASCII(web_security_origin.protocol(),
- url_scheme_to_be_skipped)) {
+ chrome::kExtensionScheme)) {
file_util::Delete(file_path, false);
}
}
@@ -49,11 +51,14 @@ const FilePath::CharType DOMStorageContext::kLocalStorageDirectory[] =
const FilePath::CharType DOMStorageContext::kLocalStorageExtension[] =
FILE_PATH_LITERAL(".localstorage");
-DOMStorageContext::DOMStorageContext(WebKitContext* webkit_context)
+DOMStorageContext::DOMStorageContext(
+ WebKitContext* webkit_context,
+ quota::SpecialStoragePolicy* special_storage_policy)
: last_storage_area_id_(0),
last_session_storage_namespace_id_on_ui_thread_(kLocalStorageNamespaceId),
last_session_storage_namespace_id_on_io_thread_(kLocalStorageNamespaceId),
- clear_local_state_on_exit_(false) {
+ clear_local_state_on_exit_(false),
+ special_storage_policy_(special_storage_policy) {
data_path_ = webkit_context->data_path();
}
@@ -71,8 +76,7 @@ DOMStorageContext::~DOMStorageContext() {
// where no clean up is needed.
if (clear_local_state_on_exit_ &&
BrowserThread::CurrentlyOn(BrowserThread::WEBKIT)) {
- ClearLocalState(data_path_.Append(kLocalStorageDirectory),
- chrome::kExtensionScheme);
+ ClearLocalState(data_path_.Append(kLocalStorageDirectory));
}
}
@@ -176,10 +180,7 @@ void DOMStorageContext::PurgeMemory() {
local_storage->PurgeMemory();
}
-void DOMStorageContext::DeleteDataModifiedSince(
- const base::Time& cutoff,
- const char* url_scheme_to_be_skipped,
- const std::vector<string16>& protected_origins) {
+void DOMStorageContext::DeleteDataModifiedSince(const base::Time& cutoff) {
// Make sure that we don't delete a database that's currently being accessed
// by unloading all of the databases temporarily.
PurgeMemory();
@@ -189,16 +190,9 @@ void DOMStorageContext::DeleteDataModifiedSince(
file_util::FileEnumerator::FILES);
for (FilePath path = file_enumerator.Next(); !path.value().empty();
path = file_enumerator.Next()) {
- WebSecurityOrigin web_security_origin =
- WebSecurityOrigin::createFromDatabaseIdentifier(
- webkit_glue::FilePathToWebString(path.BaseName()));
- if (EqualsASCII(web_security_origin.protocol(), url_scheme_to_be_skipped))
- continue;
-
- std::vector<string16>::const_iterator find_iter =
- std::find(protected_origins.begin(), protected_origins.end(),
- web_security_origin.databaseIdentifier());
- if (find_iter != protected_origins.end())
+ GURL origin(WebSecurityOrigin::createFromDatabaseIdentifier(
+ webkit_glue::FilePathToWebString(path.BaseName())).toString());
+ if (special_storage_policy_->IsStorageProtected(origin))
continue;
file_util::FileEnumerator::FindInfo find_info;
diff --git a/content/browser/in_process_webkit/dom_storage_context.h b/content/browser/in_process_webkit/dom_storage_context.h
index 6810453..c865d8a 100644
--- a/content/browser/in_process_webkit/dom_storage_context.h
+++ b/content/browser/in_process_webkit/dom_storage_context.h
@@ -10,6 +10,7 @@
#include <set>
#include "base/file_path.h"
+#include "base/ref_counted.h"
#include "base/string16.h"
#include "base/time.h"
@@ -18,6 +19,10 @@ class DOMStorageMessageFilter;
class DOMStorageNamespace;
class WebKitContext;
+namespace quota {
+class SpecialStoragePolicy;
+}
+
// This is owned by WebKitContext and is all the dom storage information that's
// shared by all the DOMStorageMessageFilters that share the same profile. The
// specifics of responsibilities are fairly well documented here and in
@@ -27,7 +32,8 @@ class WebKitContext;
// NOTE: Virtual methods facilitate mocking functions for testing.
class DOMStorageContext {
public:
- explicit DOMStorageContext(WebKitContext* webkit_context);
+ DOMStorageContext(WebKitContext* webkit_context,
+ quota::SpecialStoragePolicy* special_storage_policy);
virtual ~DOMStorageContext();
// Invalid storage id. No storage session will ever report this value.
@@ -70,10 +76,9 @@ class DOMStorageContext {
virtual void PurgeMemory();
// Delete any local storage files that have been touched since the cutoff
- // date that's supplied.
- void DeleteDataModifiedSince(const base::Time& cutoff,
- const char* url_scheme_to_be_skipped,
- const std::vector<string16>& protected_origins);
+ // date that's supplied. Protected origins, per the SpecialStoragePolicy,
+ // are not deleted by this method.
+ void DeleteDataModifiedSince(const base::Time& cutoff);
// Deletes a single local storage file.
void DeleteLocalStorageFile(const FilePath& file_path);
@@ -151,6 +156,8 @@ class DOMStorageContext {
typedef std::map<int64, DOMStorageNamespace*> StorageNamespaceMap;
StorageNamespaceMap storage_namespace_map_;
+ scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy_;
+
DISALLOW_IMPLICIT_CONSTRUCTORS(DOMStorageContext);
};
diff --git a/content/browser/in_process_webkit/webkit_context.cc b/content/browser/in_process_webkit/webkit_context.cc
index b19fdbf..41cd58e 100644
--- a/content/browser/in_process_webkit/webkit_context.cc
+++ b/content/browser/in_process_webkit/webkit_context.cc
@@ -5,6 +5,7 @@
#include "content/browser/in_process_webkit/webkit_context.h"
#include "base/command_line.h"
+#include "chrome/browser/extensions/extension_special_storage_policy.h"
#include "chrome/browser/profiles/profile.h"
#include "content/browser/browser_thread.h"
@@ -13,7 +14,8 @@ WebKitContext::WebKitContext(Profile* profile, bool clear_local_state_on_exit)
is_incognito_(profile->IsOffTheRecord()),
clear_local_state_on_exit_(clear_local_state_on_exit),
ALLOW_THIS_IN_INITIALIZER_LIST(
- dom_storage_context_(new DOMStorageContext(this))),
+ dom_storage_context_(new DOMStorageContext(
+ this, profile->GetExtensionSpecialStoragePolicy()))),
ALLOW_THIS_IN_INITIALIZER_LIST(
indexed_db_context_(new IndexedDBContext(this))) {
}
@@ -52,20 +54,16 @@ void WebKitContext::PurgeMemory() {
dom_storage_context_->PurgeMemory();
}
-void WebKitContext::DeleteDataModifiedSince(
- const base::Time& cutoff,
- const char* url_scheme_to_be_skipped,
- const std::vector<string16>& protected_origins) {
+void WebKitContext::DeleteDataModifiedSince(const base::Time& cutoff) {
if (!BrowserThread::CurrentlyOn(BrowserThread::WEBKIT)) {
BrowserThread::PostTask(
BrowserThread::WEBKIT, FROM_HERE,
NewRunnableMethod(this, &WebKitContext::DeleteDataModifiedSince,
- cutoff, url_scheme_to_be_skipped, protected_origins));
+ cutoff));
return;
}
- dom_storage_context_->DeleteDataModifiedSince(
- cutoff, url_scheme_to_be_skipped, protected_origins);
+ dom_storage_context_->DeleteDataModifiedSince(cutoff);
}
diff --git a/content/browser/in_process_webkit/webkit_context.h b/content/browser/in_process_webkit/webkit_context.h
index 5f647ef..c912c62 100644
--- a/content/browser/in_process_webkit/webkit_context.h
+++ b/content/browser/in_process_webkit/webkit_context.h
@@ -57,9 +57,7 @@ class WebKitContext
// Tell all children (where applicable) to delete any objects that were
// last modified on or after the following time.
- void DeleteDataModifiedSince(const base::Time& cutoff,
- const char* url_scheme_to_be_skipped,
- const std::vector<string16>& protected_origins);
+ void DeleteDataModifiedSince(const base::Time& cutoff);
// Delete the session storage namespace associated with this id. Can be
// called from any thread.
diff --git a/content/browser/in_process_webkit/webkit_context_unittest.cc b/content/browser/in_process_webkit/webkit_context_unittest.cc
index 811a3d0..9998142 100644
--- a/content/browser/in_process_webkit/webkit_context_unittest.cc
+++ b/content/browser/in_process_webkit/webkit_context_unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "chrome/browser/extensions/extension_special_storage_policy.h"
#include "chrome/test/testing_profile.h"
#include "content/browser/browser_thread.h"
#include "content/browser/in_process_webkit/dom_storage_context.h"
@@ -11,7 +12,7 @@
class MockDOMStorageContext : public DOMStorageContext {
public:
explicit MockDOMStorageContext(WebKitContext* webkit_context)
- : DOMStorageContext(webkit_context),
+ : DOMStorageContext(webkit_context, new ExtensionSpecialStoragePolicy),
purge_count_(0) {
}
diff --git a/webkit/appcache/appcache_service.cc b/webkit/appcache/appcache_service.cc
index 1eb4673..e748434 100644
--- a/webkit/appcache/appcache_service.cc
+++ b/webkit/appcache/appcache_service.cc
@@ -10,6 +10,7 @@
#include "webkit/appcache/appcache_backend_impl.h"
#include "webkit/appcache/appcache_entry.h"
#include "webkit/appcache/appcache_storage_impl.h"
+#include "webkit/quota/special_storage_policy.h"
namespace appcache {
@@ -216,6 +217,10 @@ void AppCacheService::DeleteAppCacheGroup(const GURL& manifest_url,
helper->Start();
}
+void AppCacheService::set_special_storage_policy(
+ quota::SpecialStoragePolicy* policy) {
+ special_storage_policy_ = policy;
+}
void AppCacheService::RegisterBackend(
AppCacheBackendImpl* backend_impl) {
DCHECK(backends_.find(backend_impl->process_id()) == backends_.end());
diff --git a/webkit/appcache/appcache_service.h b/webkit/appcache/appcache_service.h
index 6a0c931..b36951f 100644
--- a/webkit/appcache/appcache_service.h
+++ b/webkit/appcache/appcache_service.h
@@ -27,6 +27,10 @@ namespace base {
class MessageLoopProxy;
}
+namespace quota {
+class SpecialStoragePolicy;
+}
+
namespace appcache {
class AppCacheBackendImpl;
@@ -95,6 +99,11 @@ class AppCacheService {
appcache_policy_ = policy;
}
+ quota::SpecialStoragePolicy* special_storage_policy() const {
+ return special_storage_policy_.get();
+ }
+ void set_special_storage_policy(quota::SpecialStoragePolicy* policy);
+
// Each child process in chrome uses a distinct backend instance.
// See chrome/browser/AppCacheDispatcherHost.
void RegisterBackend(AppCacheBackendImpl* backend_impl);
@@ -117,6 +126,7 @@ class AppCacheService {
AppCachePolicy* appcache_policy_;
scoped_ptr<AppCacheStorage> storage_;
+ scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy_;
PendingAsyncHelpers pending_helpers_;
BackendMap backends_; // One 'backend' per child process.
// Context for use during cache updates.
diff --git a/webkit/appcache/appcache_storage.cc b/webkit/appcache/appcache_storage.cc
index 01c18f1..a30088f 100644
--- a/webkit/appcache/appcache_storage.cc
+++ b/webkit/appcache/appcache_storage.cc
@@ -87,25 +87,5 @@ void AppCacheStorage::LoadResponseInfo(
info_load->StartIfNeeded();
}
-void AppCacheStorage::SetOriginQuotaInMemory(const GURL& origin, int64 quota) {
- DCHECK(quota >= 0);
- DCHECK(origin == origin.GetOrigin());
- if (IsSchemeSupported(origin))
- in_memory_quotas_[origin] = quota;
-}
-
-void AppCacheStorage::ResetOriginQuotaInMemory(const GURL& origin) {
- DCHECK(origin == origin.GetOrigin());
- in_memory_quotas_.erase(origin);
-}
-
-int64 AppCacheStorage::GetOriginQuotaInMemory(const GURL& origin) {
- DCHECK(origin == origin.GetOrigin());
- QuotaMap::const_iterator found = in_memory_quotas_.find(origin);
- if (found == in_memory_quotas_.end())
- return -1;
- return found->second;
-}
-
} // namespace appcache
diff --git a/webkit/appcache/appcache_storage.h b/webkit/appcache/appcache_storage.h
index 1d64ef9..1767127 100644
--- a/webkit/appcache/appcache_storage.h
+++ b/webkit/appcache/appcache_storage.h
@@ -167,11 +167,6 @@ class AppCacheStorage {
virtual void PurgeMemory() = 0;
- // Maintain a collection of quota overrides in memory.
- void SetOriginQuotaInMemory(const GURL& origin, int64 quota);
- void ResetOriginQuotaInMemory(const GURL& origin);
- int64 GetOriginQuotaInMemory(const GURL& origin);
-
// Generates unique storage ids for different object types.
int64 NewCacheId() {
return ++last_cache_id_;
@@ -283,11 +278,6 @@ class AppCacheStorage {
return ++last_response_id_;
}
- // Store quotas for extensions in memory, in order to prevent writing a row
- // to quota_table_ every time an extention is loaded.
- typedef std::map<GURL, int64> QuotaMap;
- QuotaMap in_memory_quotas_;
-
// The last storage id used for different object types.
int64 last_cache_id_;
int64 last_group_id_;
diff --git a/webkit/appcache/appcache_storage_impl.cc b/webkit/appcache/appcache_storage_impl.cc
index 8d21105..0f78b77 100644
--- a/webkit/appcache/appcache_storage_impl.cc
+++ b/webkit/appcache/appcache_storage_impl.cc
@@ -22,6 +22,7 @@
#include "webkit/appcache/appcache_response.h"
#include "webkit/appcache/appcache_service.h"
#include "webkit/appcache/appcache_thread.h"
+#include "webkit/quota/special_storage_policy.h"
namespace {
// Helper with no return value for use with NewRunnableFunction.
@@ -410,8 +411,7 @@ AppCacheStorageImpl::StoreGroupAndCacheTask::StoreGroupAndCacheTask(
AppCacheStorageImpl* storage, AppCacheGroup* group, AppCache* newest_cache)
: StoreOrLoadTask(storage), group_(group), cache_(newest_cache),
success_(false), would_exceed_quota_(false),
- quota_override_(
- storage->GetOriginQuotaInMemory(group->manifest_url().GetOrigin())) {
+ quota_override_(-1) {
group_record_.group_id = group->group_id();
group_record_.manifest_url = group->manifest_url();
group_record_.origin = group_record_.manifest_url.GetOrigin();
@@ -419,6 +419,12 @@ AppCacheStorageImpl::StoreGroupAndCacheTask::StoreGroupAndCacheTask(
group,
&cache_record_, &entry_records_, &fallback_namespace_records_,
&online_whitelist_records_);
+
+ if (storage->service()->special_storage_policy() &&
+ storage->service()->special_storage_policy()->IsStorageUnlimited(
+ group_record_.origin)) {
+ quota_override_ = kint64max;
+ }
}
void AppCacheStorageImpl::StoreGroupAndCacheTask::Run() {
diff --git a/webkit/appcache/appcache_storage_impl_unittest.cc b/webkit/appcache/appcache_storage_impl_unittest.cc
index 2f25b65..1d874bc 100644
--- a/webkit/appcache/appcache_storage_impl_unittest.cc
+++ b/webkit/appcache/appcache_storage_impl_unittest.cc
@@ -547,19 +547,14 @@ class AppCacheStorageImplTest : public testing::Test {
PushNextTask(NewRunnableMethod(
this, &AppCacheStorageImplTest::Verify_FailStoreGroup));
- // Set a low quota to force a failure.
- const GURL kOrigin(kManifestUrl.GetOrigin());
- EXPECT_EQ(-1L, storage()->GetOriginQuotaInMemory(kOrigin));
- storage()->SetOriginQuotaInMemory(kManifestUrl.GetOrigin(), 0);
- EXPECT_EQ(0L, storage()->GetOriginQuotaInMemory(kOrigin));
-
// Setup some preconditions. Create a group and newest cache that
- // appear to be "unstored".
+ // appear to be "unstored" and big enough to exceed the 5M limit.
+ const int64 kTooBig = 10 * 1024 * 1024; // 10M
group_ = new AppCacheGroup(
service(), kManifestUrl, storage()->NewGroupId());
cache_ = new AppCache(service(), storage()->NewCacheId());
cache_->AddEntry(kManifestUrl,
- AppCacheEntry(AppCacheEntry::MANIFEST, 1, 1024));
+ AppCacheEntry(AppCacheEntry::MANIFEST, 1, kTooBig));
// Hold a ref to the cache simulate the UpdateJob holding that ref,
// and hold a ref to the group to simulate the CacheHost holding that ref.
@@ -578,10 +573,6 @@ class AppCacheStorageImplTest : public testing::Test {
EXPECT_FALSE(database()->FindGroup(group_->group_id(), &group_record));
EXPECT_FALSE(database()->FindCache(cache_->cache_id(), &cache_record));
- const GURL kOrigin(kManifestUrl.GetOrigin());
- storage()->ResetOriginQuotaInMemory(kOrigin);
- EXPECT_EQ(-1L, storage()->GetOriginQuotaInMemory(kOrigin));
-
TestFinished();
}
diff --git a/webkit/database/database_tracker.cc b/webkit/database/database_tracker.cc
index 46e9dc1..20f5971 100644
--- a/webkit/database/database_tracker.cc
+++ b/webkit/database/database_tracker.cc
@@ -17,8 +17,10 @@
#include "base/string_number_conversions.h"
#include "base/utf_string_conversions.h"
#include "net/base/net_errors.h"
+#include "webkit/database/database_util.h"
#include "webkit/database/databases_table.h"
#include "webkit/database/quota_table.h"
+#include "webkit/quota/special_storage_policy.h"
namespace {
@@ -78,8 +80,10 @@ string16 OriginInfo::GetDatabaseDescription(
OriginInfo::OriginInfo(const string16& origin, int64 total_size, int64 quota)
: origin_(origin), total_size_(total_size), quota_(quota) {}
-DatabaseTracker::DatabaseTracker(const FilePath& profile_path,
- bool is_incognito)
+DatabaseTracker::DatabaseTracker(
+ const FilePath& profile_path,
+ bool is_incognito,
+ quota::SpecialStoragePolicy* special_storage_policy)
: is_initialized_(false),
is_incognito_(is_incognito),
shutting_down_(false),
@@ -91,6 +95,7 @@ DatabaseTracker::DatabaseTracker(const FilePath& profile_path,
databases_table_(NULL),
meta_table_(NULL),
default_quota_(5 * 1024 * 1024),
+ special_storage_policy_(special_storage_policy),
incognito_origin_directories_generator_(0) {
}
@@ -289,16 +294,6 @@ void DatabaseTracker::SetOriginQuota(const string16& origin_identifier,
}
}
-void DatabaseTracker::SetOriginQuotaInMemory(const string16& origin_identifier,
- int64 new_quota) {
- DCHECK(new_quota >= 0);
- in_memory_quotas_[origin_identifier] = new_quota;
-}
-
-void DatabaseTracker::ResetOriginQuotaInMemory(
- const string16& origin_identifier) {
- in_memory_quotas_.erase(origin_identifier);
-}
bool DatabaseTracker::DeleteClosedDatabase(const string16& origin_identifier,
const string16& database_name) {
@@ -464,8 +459,12 @@ DatabaseTracker::CachedOriginInfo* DatabaseTracker::GetCachedOriginInfo(
origin_info.SetDatabaseDescription(it->database_name, it->description);
}
- if (in_memory_quotas_.find(origin_identifier) != in_memory_quotas_.end()) {
- origin_info.SetQuota(in_memory_quotas_[origin_identifier]);
+ if (special_storage_policy_.get() &&
+ special_storage_policy_->IsStorageUnlimited(
+ DatabaseUtil::GetOriginFromIdentifier(origin_identifier))) {
+ // TODO(michaeln): handle the case where it changes status sometime after
+ // the cached origin_info has been established
+ origin_info.SetQuota(kint64max);
} else {
int64 origin_quota = quota_table_->GetOriginQuota(origin_identifier);
if (origin_quota > 0)
@@ -554,7 +553,6 @@ int DatabaseTracker::DeleteDatabase(const string16& origin_identifier,
int DatabaseTracker::DeleteDataModifiedSince(
const base::Time& cutoff,
- const std::vector<string16>& protected_origins,
net::CompletionCallback* callback) {
if (!LazyInit())
return net::ERR_FAILED;
@@ -563,19 +561,17 @@ int DatabaseTracker::DeleteDataModifiedSince(
deletion_callbacks_.find(callback) == deletion_callbacks_.end());
DatabaseSet to_be_deleted;
- std::vector<string16> origins;
- if (!databases_table_->GetAllOrigins(&origins))
+ std::vector<string16> origins_identifiers;
+ if (!databases_table_->GetAllOrigins(&origins_identifiers))
return net::ERR_FAILED;
int rv = net::OK;
- for (std::vector<string16>::const_iterator ori = origins.begin();
- ori != origins.end(); ++ori) {
- if (StartsWith(*ori, ASCIIToUTF16(kExtensionOriginIdentifierPrefix), true))
- continue;
-
- std::vector<string16>::const_iterator find_iter =
- std::find(protected_origins.begin(), protected_origins.end(), *ori);
- if (find_iter != protected_origins.end())
+ for (std::vector<string16>::const_iterator ori = origins_identifiers.begin();
+ ori != origins_identifiers.end(); ++ori) {
+ if (special_storage_policy_.get() &&
+ special_storage_policy_->IsStorageProtected(
+ DatabaseUtil::GetOriginFromIdentifier(*ori))) {
continue;
+ }
std::vector<DatabaseDetails> details;
if (!databases_table_->GetAllDatabaseDetailsForOrigin(*ori, &details))
diff --git a/webkit/database/database_tracker.h b/webkit/database/database_tracker.h
index 08a66b2..140753e 100644
--- a/webkit/database/database_tracker.h
+++ b/webkit/database/database_tracker.h
@@ -25,6 +25,10 @@ class Connection;
class MetaTable;
}
+namespace quota {
+class SpecialStoragePolicy;
+}
+
namespace webkit_database {
extern const FilePath::CharType kDatabaseDirectoryName[];
@@ -83,7 +87,8 @@ class DatabaseTracker
virtual ~Observer() {}
};
- DatabaseTracker(const FilePath& profile_path, bool is_incognito);
+ DatabaseTracker(const FilePath& profile_path, bool is_incognito,
+ quota::SpecialStoragePolicy* special_storage_policy);
void DatabaseOpened(const string16& origin_identifier,
const string16& database_name,
@@ -108,9 +113,6 @@ class DatabaseTracker
bool GetAllOriginsInfo(std::vector<OriginInfo>* origins_info);
void SetOriginQuota(const string16& origin_identifier, int64 new_quota);
- void SetOriginQuotaInMemory(const string16& origin_identifier,
- int64 new_quota);
- void ResetOriginQuotaInMemory(const string16& origin_identifier);
int64 GetDefaultQuota() { return default_quota_; }
// Sets the default quota for all origins. Should be used in tests only.
@@ -130,9 +132,9 @@ class DatabaseTracker
// supplied, omitting any that match IDs within |protected_origins|.
// Returns net::OK on success, net::FAILED if not all databases could be
// deleted, and net::ERR_IO_PENDING and |callback| is invoked upon completion,
- // if non-NULL.
+ // if non-NULL. Protected origins, according the the SpecialStoragePolicy,
+ // are not deleted by this method.
int DeleteDataModifiedSince(const base::Time& cutoff,
- const std::vector<string16>& protected_origins,
net::CompletionCallback* callback);
// Delete all databases that belong to the given origin. Returns net::OK on
@@ -238,9 +240,8 @@ class DatabaseTracker
// Default quota for all origins; changed only by tests
int64 default_quota_;
- // Store quotas for extensions in memory, in order to prevent writing a row
- // to quota_table_ every time an extention is loaded.
- std::map<string16, int64> in_memory_quotas_;
+ // Apps and Extensions can have special rights.
+ scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy_;
// When in incognito mode, store a DELETE_ON_CLOSE handle to each
// main DB and journal file that was accessed. When the incognito profile
diff --git a/webkit/database/database_tracker_unittest.cc b/webkit/database/database_tracker_unittest.cc
index 641c207..a8d2928 100644
--- a/webkit/database/database_tracker_unittest.cc
+++ b/webkit/database/database_tracker_unittest.cc
@@ -12,9 +12,25 @@
#include "net/base/test_completion_callback.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webkit/database/database_tracker.h"
+#include "webkit/database/database_util.h"
+#include "webkit/quota/special_storage_policy.h"
namespace {
+const char kOrigin1Url[] = "http://origin1";
+const char kOrigin2Url[] = "http://protected_origin2";
+
+class TestSpecialStoragePolicy : public quota::SpecialStoragePolicy {
+ public:
+ virtual bool IsStorageProtected(const GURL& origin) {
+ return origin == GURL(kOrigin2Url);
+ }
+
+ virtual bool IsStorageUnlimited(const GURL& origin) {
+ return false;
+ }
+};
+
class TestObserver : public webkit_database::DatabaseTracker::Observer {
public:
TestObserver() : new_notification_received_(false) {}
@@ -85,13 +101,16 @@ class DatabaseTracker_TestHelper_Test {
ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
scoped_refptr<DatabaseTracker> tracker(
- new DatabaseTracker(temp_dir.path(), incognito_mode));
+ new DatabaseTracker(temp_dir.path(), incognito_mode,
+ new TestSpecialStoragePolicy));
// Create and open three databases.
int64 database_size = 0;
int64 space_available = 0;
- const string16 kOrigin1 = ASCIIToUTF16("origin1");
- const string16 kOrigin2 = ASCIIToUTF16("origin2");
+ const string16 kOrigin1 =
+ DatabaseUtil::GetOriginIdentifier(GURL(kOrigin1Url));
+ const string16 kOrigin2 =
+ DatabaseUtil::GetOriginIdentifier(GURL(kOrigin2Url));
const string16 kDB1 = ASCIIToUTF16("db1");
const string16 kDB2 = ASCIIToUTF16("db2");
const string16 kDB3 = ASCIIToUTF16("db3");
@@ -160,10 +179,8 @@ class DatabaseTracker_TestHelper_Test {
// Delete databases modified since yesterday. db2 is whitelisted.
base::Time yesterday = base::Time::Now();
yesterday -= base::TimeDelta::FromDays(1);
- std::vector<string16> protected_origins;
- protected_origins.push_back(kOrigin2);
result = tracker->DeleteDataModifiedSince(
- yesterday, protected_origins, &callback);
+ yesterday, &callback);
EXPECT_EQ(net::ERR_IO_PENDING, result);
ASSERT_FALSE(callback.have_result());
EXPECT_TRUE(observer.DidReceiveNewNotification());
@@ -187,7 +204,8 @@ class DatabaseTracker_TestHelper_Test {
ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
scoped_refptr<DatabaseTracker> tracker(
- new DatabaseTracker(temp_dir.path(), incognito_mode));
+ new DatabaseTracker(temp_dir.path(), incognito_mode,
+ new TestSpecialStoragePolicy));
// Add two observers.
TestObserver observer1;
@@ -198,8 +216,10 @@ class DatabaseTracker_TestHelper_Test {
// Open three new databases.
int64 database_size = 0;
int64 space_available = 0;
- const string16 kOrigin1 = ASCIIToUTF16("origin1");
- const string16 kOrigin2 = ASCIIToUTF16("origin2");
+ const string16 kOrigin1 =
+ DatabaseUtil::GetOriginIdentifier(GURL(kOrigin1Url));
+ const string16 kOrigin2 =
+ DatabaseUtil::GetOriginIdentifier(GURL(kOrigin2Url));
const string16 kDB1 = ASCIIToUTF16("db1");
const string16 kDB2 = ASCIIToUTF16("db2");
const string16 kDB3 = ASCIIToUTF16("db3");
diff --git a/webkit/database/database_util.cc b/webkit/database/database_util.cc
index 8002d81..2886095 100644
--- a/webkit/database/database_util.cc
+++ b/webkit/database/database_util.cc
@@ -71,4 +71,11 @@ string16 DatabaseUtil::GetOriginIdentifier(const GURL& url) {
return WebKit::WebSecurityOrigin::createFromString(spec).databaseIdentifier();
}
+GURL DatabaseUtil::GetOriginFromIdentifier(const string16& origin_identifier) {
+ GURL origin(WebKit::WebSecurityOrigin::createFromDatabaseIdentifier(
+ origin_identifier).toString());
+ DCHECK(origin == origin.GetOrigin());
+ return origin;
+}
+
} // namespace webkit_database
diff --git a/webkit/database/database_util.h b/webkit/database/database_util.h
index cecea79..20410dc 100644
--- a/webkit/database/database_util.h
+++ b/webkit/database/database_util.h
@@ -25,6 +25,7 @@ class DatabaseUtil {
static FilePath GetFullFilePathForVfsFile(DatabaseTracker* db_tracker,
const string16& vfs_file_name);
static string16 GetOriginIdentifier(const GURL& url);
+ static GURL GetOriginFromIdentifier(const string16& origin_identifier);
};
} // namespace webkit_database
diff --git a/webkit/fileapi/file_system_context.cc b/webkit/fileapi/file_system_context.cc
index 5007fff..6cb97e9 100644
--- a/webkit/fileapi/file_system_context.cc
+++ b/webkit/fileapi/file_system_context.cc
@@ -15,6 +15,7 @@ namespace fileapi {
FileSystemContext::FileSystemContext(
scoped_refptr<base::MessageLoopProxy> file_message_loop,
scoped_refptr<base::MessageLoopProxy> io_message_loop,
+ scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy,
const FilePath& profile_path,
bool is_incognito,
bool allow_file_access,
@@ -24,7 +25,7 @@ FileSystemContext::FileSystemContext(
path_manager_(new FileSystemPathManager(
file_message_loop, profile_path, is_incognito, allow_file_access)),
quota_manager_(new FileSystemQuotaManager(
- allow_file_access, unlimited_quota)),
+ allow_file_access, unlimited_quota, special_storage_policy)),
usage_tracker_(new FileSystemUsageTracker(
file_message_loop, profile_path, is_incognito)) {
}
@@ -45,16 +46,6 @@ void FileSystemContext::DeleteDataForOriginOnFileThread(
file_util::Delete(path_for_origin, true /* recursive */);
}
-void FileSystemContext::SetOriginQuotaUnlimited(const GURL& url) {
- DCHECK(io_message_loop_->BelongsToCurrentThread());
- quota_manager()->SetOriginQuotaUnlimited(url);
-}
-
-void FileSystemContext::ResetOriginQuotaUnlimited(const GURL& url) {
- DCHECK(io_message_loop_->BelongsToCurrentThread());
- quota_manager()->ResetOriginQuotaUnlimited(url);
-}
-
void FileSystemContext::DeleteOnCorrectThread() const {
if (!io_message_loop_->BelongsToCurrentThread()) {
io_message_loop_->DeleteSoon(FROM_HERE, this);
diff --git a/webkit/fileapi/file_system_context.h b/webkit/fileapi/file_system_context.h
index 5c94c5f..d9552946 100644
--- a/webkit/fileapi/file_system_context.h
+++ b/webkit/fileapi/file_system_context.h
@@ -7,6 +7,7 @@
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
+#include "webkit/quota/special_storage_policy.h"
class FilePath;
class GURL;
@@ -32,6 +33,7 @@ class FileSystemContext
FileSystemContext(
scoped_refptr<base::MessageLoopProxy> file_message_loop,
scoped_refptr<base::MessageLoopProxy> io_message_loop,
+ scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy,
const FilePath& profile_path,
bool is_incognito,
bool allow_file_access_from_files,
@@ -40,10 +42,6 @@ class FileSystemContext
void DeleteDataForOriginOnFileThread(const GURL& origin_url);
- // Quota related methods.
- void SetOriginQuotaUnlimited(const GURL& url);
- void ResetOriginQuotaUnlimited(const GURL& url);
-
FileSystemPathManager* path_manager() { return path_manager_.get(); }
FileSystemQuotaManager* quota_manager() { return quota_manager_.get(); }
FileSystemUsageTracker* usage_tracker() { return usage_tracker_.get(); }
diff --git a/webkit/fileapi/file_system_quota_manager.cc b/webkit/fileapi/file_system_quota_manager.cc
index 13a33f6..69ff706 100644
--- a/webkit/fileapi/file_system_quota_manager.cc
+++ b/webkit/fileapi/file_system_quota_manager.cc
@@ -8,6 +8,7 @@
#include "base/file_util_proxy.h"
#include "base/ref_counted.h"
#include "base/scoped_callback_factory.h"
+#include "webkit/quota/special_storage_policy.h"
namespace fileapi {
@@ -15,9 +16,11 @@ const int64 FileSystemQuotaManager::kUnknownSize = -1;
FileSystemQuotaManager::FileSystemQuotaManager(
bool allow_file_access_from_files,
- bool unlimited_quota)
+ bool unlimited_quota,
+ quota::SpecialStoragePolicy* special_storage_policy)
: allow_file_access_from_files_(allow_file_access_from_files),
- unlimited_quota_(unlimited_quota) {
+ unlimited_quota_(unlimited_quota),
+ special_storage_policy_(special_storage_policy) {
}
FileSystemQuotaManager::~FileSystemQuotaManager() {}
@@ -26,26 +29,10 @@ bool FileSystemQuotaManager::CheckOriginQuota(const GURL& origin, int64) {
// If allow-file-access-from-files flag is explicitly given and the scheme
// is file, or if unlimited quota for this process was explicitly requested,
// return true.
- if (unlimited_quota_ ||
- (origin.SchemeIsFile() && allow_file_access_from_files_))
- return true;
- return CheckIfOriginGrantedUnlimitedQuota(origin);
-}
-
-void FileSystemQuotaManager::SetOriginQuotaUnlimited(const GURL& origin) {
- DCHECK(origin == origin.GetOrigin());
- unlimited_quota_origins_.insert(origin);
-}
-
-void FileSystemQuotaManager::ResetOriginQuotaUnlimited(const GURL& origin) {
- DCHECK(origin == origin.GetOrigin());
- unlimited_quota_origins_.erase(origin);
-}
-
-bool FileSystemQuotaManager::CheckIfOriginGrantedUnlimitedQuota(
- const GURL& origin) {
- std::set<GURL>::const_iterator found = unlimited_quota_origins_.find(origin);
- return (found != unlimited_quota_origins_.end());
+ return unlimited_quota_ ||
+ (allow_file_access_from_files_ && origin.SchemeIsFile()) ||
+ (special_storage_policy_.get() &&
+ special_storage_policy_->IsStorageUnlimited(origin));
}
} // namespace fileapi
diff --git a/webkit/fileapi/file_system_quota_manager.h b/webkit/fileapi/file_system_quota_manager.h
index f1c94e1..b7d4d04 100644
--- a/webkit/fileapi/file_system_quota_manager.h
+++ b/webkit/fileapi/file_system_quota_manager.h
@@ -8,8 +8,13 @@
#include <set>
#include "base/basictypes.h"
+#include "base/ref_counted.h"
#include "googleurl/src/gurl.h"
+namespace quota {
+class SpecialStoragePolicy;
+}
+
namespace fileapi {
// A quota manager for FileSystem. For now it has little implementation
@@ -23,7 +28,8 @@ class FileSystemQuotaManager {
// If |unlimited_quota| is true, unlimited access is granted for every
// origin. This flag must be used only for testing.
FileSystemQuotaManager(bool allow_file_access_from_files,
- bool unlimited_quota);
+ bool unlimited_quota,
+ quota::SpecialStoragePolicy* special_storage_policy);
~FileSystemQuotaManager();
// Checks if the origin can grow its usage by |growth| bytes.
@@ -32,17 +38,13 @@ class FileSystemQuotaManager {
// that are not in the in-memory unlimited_quota_origins map.
bool CheckOriginQuota(const GURL& origin, int64 growth);
- // Maintains origins in memory that are allowed to have unlimited quota.
- void SetOriginQuotaUnlimited(const GURL& origin);
- void ResetOriginQuotaUnlimited(const GURL& origin);
- bool CheckIfOriginGrantedUnlimitedQuota(const GURL& origin);
-
private:
// For some extensions/apps we allow unlimited quota.
std::set<GURL> unlimited_quota_origins_;
const bool allow_file_access_from_files_;
const bool unlimited_quota_;
+ scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy_;
DISALLOW_COPY_AND_ASSIGN(FileSystemQuotaManager);
};
diff --git a/webkit/fileapi/file_system_quota_manager_unittest.cc b/webkit/fileapi/file_system_quota_manager_unittest.cc
index 3bc7ac3..b22a33f9 100644
--- a/webkit/fileapi/file_system_quota_manager_unittest.cc
+++ b/webkit/fileapi/file_system_quota_manager_unittest.cc
@@ -9,24 +9,10 @@
#include "base/scoped_ptr.h"
#include "base/string_number_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "webkit/quota/special_storage_policy.h"
using namespace fileapi;
-class FileSystemQuotaManagerTest : public testing::Test {
- public:
- FileSystemQuotaManagerTest() { }
-
- void SetUp() {
- quota_.reset(new FileSystemQuotaManager(false, false));
- }
-
- FileSystemQuotaManager* quota() const { return quota_.get(); }
-
- protected:
- scoped_ptr<FileSystemQuotaManager> quota_;
- DISALLOW_COPY_AND_ASSIGN(FileSystemQuotaManagerTest);
-};
-
namespace {
static const char* const kTestOrigins[] = {
@@ -36,111 +22,81 @@ static const char* const kTestOrigins[] = {
"file:///",
};
+class TestSpecialStoragePolicy : public quota::SpecialStoragePolicy {
+ public:
+ virtual bool IsStorageProtected(const GURL& origin) {
+ return false;
+ }
+
+ virtual bool IsStorageUnlimited(const GURL& origin) {
+ return origin == GURL(kTestOrigins[1]);
+ }
+};
+
} // anonymous namespace
-TEST_F(FileSystemQuotaManagerTest, CheckOriginQuotaNotAllowed) {
+TEST(FileSystemQuotaManagerTest, CheckNotAllowed) {
+ FileSystemQuotaManager quota(false, false, NULL);
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestOrigins); ++i) {
SCOPED_TRACE(testing::Message() << "CheckOriginQuotaNotAllowed #"
<< i << " " << kTestOrigins[i]);
// Should fail no matter how much size is requested.
- EXPECT_FALSE(quota()->CheckOriginQuota(GURL(kTestOrigins[i]), -1));
- EXPECT_FALSE(quota()->CheckOriginQuota(GURL(kTestOrigins[i]), 0));
- EXPECT_FALSE(quota()->CheckOriginQuota(GURL(kTestOrigins[i]), 100));
+ GURL origin(kTestOrigins[i]);
+ EXPECT_FALSE(quota.CheckOriginQuota(origin, -1));
+ EXPECT_FALSE(quota.CheckOriginQuota(origin, 0));
+ EXPECT_FALSE(quota.CheckOriginQuota(origin, 100));
}
}
-TEST_F(FileSystemQuotaManagerTest, CheckOriginQuotaUnlimited) {
- // Tests if SetOriginQuotaUnlimited and ResetOriginQuotaUnlimited
- // are working as expected.
+TEST(FileSystemQuotaManagerTest, CheckUnlimitedFlag) {
+ FileSystemQuotaManager quota(false, true, NULL);
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestOrigins); ++i) {
- SCOPED_TRACE(testing::Message() << "CheckOriginQuotaUnlimited #"
- << i << " " << kTestOrigins[i]);
- GURL url(kTestOrigins[i]);
- EXPECT_FALSE(quota()->CheckIfOriginGrantedUnlimitedQuota(url));
- EXPECT_FALSE(quota()->CheckOriginQuota(url, 0));
-
- quota()->SetOriginQuotaUnlimited(url);
- EXPECT_TRUE(quota()->CheckIfOriginGrantedUnlimitedQuota(url));
- EXPECT_TRUE(quota()->CheckOriginQuota(url, -1));
- EXPECT_TRUE(quota()->CheckOriginQuota(url, 0));
- EXPECT_TRUE(quota()->CheckOriginQuota(url, 100));
-
- quota()->ResetOriginQuotaUnlimited(url);
- EXPECT_FALSE(quota()->CheckIfOriginGrantedUnlimitedQuota(url));
- EXPECT_FALSE(quota()->CheckOriginQuota(url, -1));
- EXPECT_FALSE(quota()->CheckOriginQuota(url, 0));
- EXPECT_FALSE(quota()->CheckOriginQuota(url, 100));
- }
-}
-
-TEST_F(FileSystemQuotaManagerTest, CheckOriginQuotaWithMixedSet) {
- // Tests setting unlimited quota for some urls doesn't affect
- // other urls.
- GURL test_url1("http://foo.bar.com/");
- GURL test_url2("http://example.com/");
- quota()->SetOriginQuotaUnlimited(test_url1);
- quota()->SetOriginQuotaUnlimited(test_url2);
-
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestOrigins); ++i) {
- SCOPED_TRACE(testing::Message() << "CheckOriginQuotaMixedSet #"
+ SCOPED_TRACE(testing::Message() << "CheckOriginQuotaNotAllowed #"
<< i << " " << kTestOrigins[i]);
- GURL url(kTestOrigins[i]);
- EXPECT_FALSE(quota()->CheckOriginQuota(url, 0));
- EXPECT_FALSE(quota()->CheckIfOriginGrantedUnlimitedQuota(url));
+ // Should succeed no matter how much size is requested.
+ GURL origin(kTestOrigins[i]);
+ EXPECT_TRUE(quota.CheckOriginQuota(origin, -1));
+ EXPECT_TRUE(quota.CheckOriginQuota(origin, 0));
+ EXPECT_TRUE(quota.CheckOriginQuota(origin, 100));
}
}
-TEST_F(FileSystemQuotaManagerTest, CheckOriginQuotaMixedWithDifferentScheme) {
- // Tests setting unlimited quota for urls doesn't affect
- // pages in the same hosts but with different scheme.
+TEST(FileSystemQuotaManagerTest, CheckAllowFileFlag) {
+ FileSystemQuotaManager quota(true, false, NULL);
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestOrigins); ++i) {
- GURL url(kTestOrigins[i]);
- if (url.SchemeIsFile())
- continue;
- ASSERT_TRUE(url == url.GetOrigin());
- std::string new_scheme = "https";
- if (url.SchemeIsSecure())
- new_scheme = "http";
- else
- ASSERT_TRUE(url.SchemeIs("http"));
- std::string new_url_string = new_scheme + "://" + url.host();
- if (url.has_port())
- new_url_string += ":" + url.port();
- quota()->SetOriginQuotaUnlimited(GURL(new_url_string));
- }
-
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestOrigins); ++i) {
- SCOPED_TRACE(testing::Message()
- << "CheckOriginQuotaMixedWithDifferentScheme #"
+ SCOPED_TRACE(testing::Message() << "CheckOriginQuotaNotAllowed #"
<< i << " " << kTestOrigins[i]);
- GURL url(kTestOrigins[i]);
- EXPECT_FALSE(quota()->CheckOriginQuota(url, 0));
- EXPECT_FALSE(quota()->CheckIfOriginGrantedUnlimitedQuota(url));
+ // Should succeed only for file:// urls
+ GURL origin(kTestOrigins[i]);
+ if (origin.SchemeIsFile()) {
+ EXPECT_TRUE(quota.CheckOriginQuota(origin, -1));
+ EXPECT_TRUE(quota.CheckOriginQuota(origin, 0));
+ EXPECT_TRUE(quota.CheckOriginQuota(origin, 100));
+ } else {
+ EXPECT_FALSE(quota.CheckOriginQuota(origin, -1));
+ EXPECT_FALSE(quota.CheckOriginQuota(origin, 0));
+ EXPECT_FALSE(quota.CheckOriginQuota(origin, 100));
+ }
}
}
-TEST_F(FileSystemQuotaManagerTest, CheckOriginQuotaMixedWithDifferentPort) {
- // Tests setting unlimited quota for urls doesn't affect
- // pages in the same scheme/hosts but with different port number.
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestOrigins); ++i) {
- GURL url(kTestOrigins[i]);
- if (url.SchemeIsFile())
- continue;
- ASSERT_TRUE(url == url.GetOrigin());
- int port = 81;
- if (url.has_port())
- port = url.IntPort() + 1;
- GURL new_url(url.scheme() + "://" + url.host() + ":" +
- base::IntToString(port));
- quota()->SetOriginQuotaUnlimited(new_url);
- }
+TEST(FileSystemQuotaManagerTest, CheckSpecialPolicy) {
+ scoped_refptr<TestSpecialStoragePolicy> policy(new TestSpecialStoragePolicy);
+ FileSystemQuotaManager quota(false, false, policy);
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestOrigins); ++i) {
- SCOPED_TRACE(testing::Message()
- << "CheckOriginQuotaMixedWithDifferentPort #"
+ SCOPED_TRACE(testing::Message() << "CheckOriginQuotaNotAllowed #"
<< i << " " << kTestOrigins[i]);
- GURL url(kTestOrigins[i]);
- EXPECT_FALSE(quota()->CheckOriginQuota(url, 0));
- EXPECT_FALSE(quota()->CheckIfOriginGrantedUnlimitedQuota(url));
+ // Should succeed only for unlimited origins according to the policy.
+ GURL origin(kTestOrigins[i]);
+ if (policy->IsStorageUnlimited(origin)) {
+ EXPECT_TRUE(quota.CheckOriginQuota(origin, -1));
+ EXPECT_TRUE(quota.CheckOriginQuota(origin, 0));
+ EXPECT_TRUE(quota.CheckOriginQuota(origin, 100));
+ } else {
+ EXPECT_FALSE(quota.CheckOriginQuota(origin, -1));
+ EXPECT_FALSE(quota.CheckOriginQuota(origin, 0));
+ EXPECT_FALSE(quota.CheckOriginQuota(origin, 100));
+ }
}
}
diff --git a/webkit/tools/test_shell/simple_database_system.cc b/webkit/tools/test_shell/simple_database_system.cc
index dc80f69..d9f0cbc 100644
--- a/webkit/tools/test_shell/simple_database_system.cc
+++ b/webkit/tools/test_shell/simple_database_system.cc
@@ -29,7 +29,7 @@ SimpleDatabaseSystem* SimpleDatabaseSystem::GetInstance() {
SimpleDatabaseSystem::SimpleDatabaseSystem()
: waiting_for_dbs_to_close_(false) {
CHECK(temp_dir_.CreateUniqueTempDir());
- db_tracker_ = new DatabaseTracker(temp_dir_.path(), false);
+ db_tracker_ = new DatabaseTracker(temp_dir_.path(), false, NULL);
db_tracker_->AddObserver(this);
DCHECK(!instance_);
instance_ = this;
diff --git a/webkit/tools/test_shell/simple_file_system.cc b/webkit/tools/test_shell/simple_file_system.cc
index ea33007..6016255 100644
--- a/webkit/tools/test_shell/simple_file_system.cc
+++ b/webkit/tools/test_shell/simple_file_system.cc
@@ -121,6 +121,7 @@ SimpleFileSystem::SimpleFileSystem() {
file_system_context_ = new FileSystemContext(
base::MessageLoopProxy::CreateForCurrentThread(),
base::MessageLoopProxy::CreateForCurrentThread(),
+ NULL /* special storage policy */,
file_system_dir_.path(),
false /* incognito */,
true /* allow_file_access */,
diff --git a/webkit/tools/test_shell/test_shell.gypi b/webkit/tools/test_shell/test_shell.gypi
index 67b34b5..565f18d 100644
--- a/webkit/tools/test_shell/test_shell.gypi
+++ b/webkit/tools/test_shell/test_shell.gypi
@@ -44,6 +44,7 @@
'<(DEPTH)/webkit/support/webkit_support.gyp:database',
'<(DEPTH)/webkit/support/webkit_support.gyp:fileapi',
'<(DEPTH)/webkit/support/webkit_support.gyp:glue',
+ '<(DEPTH)/webkit/support/webkit_support.gyp:quota',
'<(DEPTH)/webkit/support/webkit_support.gyp:webkit_gpu',
'<(DEPTH)/webkit/support/webkit_support.gyp:webkit_resources',
'<(DEPTH)/webkit/support/webkit_support.gyp:webkit_support_common',