summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarja@chromium.org <marja@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-08 11:31:40 +0000
committermarja@chromium.org <marja@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-08 11:31:40 +0000
commitf5d75f7d779dbc8bdc234f24a0c5e0bad1df40b2 (patch)
treea4781091fde7f14a5167e317811c084a628d25a3
parentdb15183c76bbfd38dc0dc22e61b85c8d18f96e18 (diff)
downloadchromium_src-f5d75f7d779dbc8bdc234f24a0c5e0bad1df40b2.zip
chromium_src-f5d75f7d779dbc8bdc234f24a0c5e0bad1df40b2.tar.gz
chromium_src-f5d75f7d779dbc8bdc234f24a0c5e0bad1df40b2.tar.bz2
DatabaseTracker: Clearing session-only databases on exit.
BUG=47049 TEST=DatabaseTrackerTest.DatabaseTrackerClearSessionOnlyDatabasesOnExit Review URL: http://codereview.chromium.org/7800040 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@100135 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/extensions/extension_special_storage_policy.cc17
-rw-r--r--chrome/browser/extensions/extension_special_storage_policy.h1
-rw-r--r--chrome/browser/extensions/extension_special_storage_policy_unittest.cc43
-rw-r--r--chrome/browser/extensions/mock_extension_special_storage_policy.cc4
-rw-r--r--chrome/browser/extensions/mock_extension_special_storage_policy.h1
-rw-r--r--webkit/database/database_tracker.cc26
-rw-r--r--webkit/database/database_tracker.h8
-rw-r--r--webkit/database/database_tracker_unittest.cc85
-rw-r--r--webkit/quota/mock_special_storage_policy.cc4
-rw-r--r--webkit/quota/mock_special_storage_policy.h1
-rw-r--r--webkit/quota/special_storage_policy.h3
11 files changed, 184 insertions, 9 deletions
diff --git a/chrome/browser/extensions/extension_special_storage_policy.cc b/chrome/browser/extensions/extension_special_storage_policy.cc
index 95a2486..de58fb9 100644
--- a/chrome/browser/extensions/extension_special_storage_policy.cc
+++ b/chrome/browser/extensions/extension_special_storage_policy.cc
@@ -7,6 +7,7 @@
#include "base/logging.h"
#include "chrome/browser/content_settings/host_content_settings_map.h"
#include "chrome/common/content_settings.h"
+#include "chrome/common/content_settings_types.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/url_constants.h"
#include "content/browser/browser_thread.h"
@@ -37,6 +38,22 @@ bool ExtensionSpecialStoragePolicy::IsStorageSessionOnly(const GURL& origin) {
return (content_setting == CONTENT_SETTING_SESSION_ONLY);
}
+bool ExtensionSpecialStoragePolicy::HasSessionOnlyOrigins() {
+ if (host_content_settings_map_ == NULL)
+ return false;
+ if (host_content_settings_map_->GetDefaultContentSetting(
+ CONTENT_SETTINGS_TYPE_COOKIES) == CONTENT_SETTING_SESSION_ONLY)
+ return true;
+ HostContentSettingsMap::SettingsForOneType entries;
+ host_content_settings_map_->GetSettingsForOneType(
+ CONTENT_SETTINGS_TYPE_COOKIES, "", &entries);
+ for (size_t i = 0; i < entries.size(); ++i) {
+ if (entries[i].c == CONTENT_SETTING_SESSION_ONLY)
+ return true;
+ }
+ return false;
+}
+
bool ExtensionSpecialStoragePolicy::IsFileHandler(
const std::string& extension_id) {
base::AutoLock locker(lock_);
diff --git a/chrome/browser/extensions/extension_special_storage_policy.h b/chrome/browser/extensions/extension_special_storage_policy.h
index 8ce9d30..bce392c 100644
--- a/chrome/browser/extensions/extension_special_storage_policy.h
+++ b/chrome/browser/extensions/extension_special_storage_policy.h
@@ -30,6 +30,7 @@ class ExtensionSpecialStoragePolicy : public quota::SpecialStoragePolicy {
virtual bool IsStorageUnlimited(const GURL& origin);
virtual bool IsStorageSessionOnly(const GURL& origin);
virtual bool IsFileHandler(const std::string& extension_id);
+ virtual bool HasSessionOnlyOrigins();
// Methods used by the ExtensionService to populate this class.
void GrantRightsForExtension(const Extension* extension);
diff --git a/chrome/browser/extensions/extension_special_storage_policy_unittest.cc b/chrome/browser/extensions/extension_special_storage_policy_unittest.cc
index bd7f274..938b3f9 100644
--- a/chrome/browser/extensions/extension_special_storage_policy_unittest.cc
+++ b/chrome/browser/extensions/extension_special_storage_policy_unittest.cc
@@ -3,9 +3,13 @@
// found in the LICENSE file.
#include "base/values.h"
+#include "chrome/browser/content_settings/host_content_settings_map.h"
#include "chrome/browser/extensions/extension_special_storage_policy.h"
+#include "chrome/common/content_settings.h"
+#include "chrome/common/content_settings_types.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_constants.h"
+#include "chrome/test/base/testing_profile.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace keys = extension_manifest_keys;
@@ -210,3 +214,42 @@ TEST_F(ExtensionSpecialStoragePolicyTest, OverlappingApps) {
EXPECT_FALSE(policy->IsStorageProtected(GURL("http://foo.wildcards/")));
EXPECT_FALSE(policy->IsStorageProtected(GURL("https://bar.wildcards/")));
}
+
+TEST_F(ExtensionSpecialStoragePolicyTest, HasSessionOnlyOrigins) {
+ MessageLoop message_loop;
+ BrowserThread ui_thread(BrowserThread::UI, &message_loop);
+
+ TestingProfile profile;
+ HostContentSettingsMap* host_content_settings_map =
+ profile.GetHostContentSettingsMap();
+ scoped_refptr<ExtensionSpecialStoragePolicy> policy(
+ new ExtensionSpecialStoragePolicy(host_content_settings_map));
+
+ EXPECT_FALSE(policy->HasSessionOnlyOrigins());
+
+ // The default setting can be session-only.
+ host_content_settings_map->SetDefaultContentSetting(
+ CONTENT_SETTINGS_TYPE_COOKIES, CONTENT_SETTING_SESSION_ONLY);
+ EXPECT_TRUE(policy->HasSessionOnlyOrigins());
+
+ host_content_settings_map->SetDefaultContentSetting(
+ CONTENT_SETTINGS_TYPE_COOKIES, CONTENT_SETTING_ALLOW);
+ EXPECT_FALSE(policy->HasSessionOnlyOrigins());
+
+ // Or the session-onlyness can affect individual origins.
+ ContentSettingsPattern pattern =
+ ContentSettingsPattern::FromString("pattern.com");
+
+ host_content_settings_map->SetContentSetting(
+ pattern, ContentSettingsPattern::Wildcard(),
+ CONTENT_SETTINGS_TYPE_COOKIES, "", CONTENT_SETTING_SESSION_ONLY);
+
+ EXPECT_TRUE(policy->HasSessionOnlyOrigins());
+
+ // Clearing an origin-spesific rule.
+ host_content_settings_map->SetContentSetting(
+ pattern, ContentSettingsPattern::Wildcard(),
+ CONTENT_SETTINGS_TYPE_COOKIES, "", CONTENT_SETTING_DEFAULT);
+
+ EXPECT_FALSE(policy->HasSessionOnlyOrigins());
+}
diff --git a/chrome/browser/extensions/mock_extension_special_storage_policy.cc b/chrome/browser/extensions/mock_extension_special_storage_policy.cc
index 7cf86cd..fd9bb3e 100644
--- a/chrome/browser/extensions/mock_extension_special_storage_policy.cc
+++ b/chrome/browser/extensions/mock_extension_special_storage_policy.cc
@@ -26,3 +26,7 @@ bool MockExtensionSpecialStoragePolicy::IsFileHandler(
const std::string& extension_id) {
return file_handlers_.find(extension_id) != file_handlers_.end();
}
+
+bool MockExtensionSpecialStoragePolicy::HasSessionOnlyOrigins() {
+ return !session_only_.empty();
+}
diff --git a/chrome/browser/extensions/mock_extension_special_storage_policy.h b/chrome/browser/extensions/mock_extension_special_storage_policy.h
index b4ce548..90fffbe 100644
--- a/chrome/browser/extensions/mock_extension_special_storage_policy.h
+++ b/chrome/browser/extensions/mock_extension_special_storage_policy.h
@@ -24,6 +24,7 @@ class MockExtensionSpecialStoragePolicy : public ExtensionSpecialStoragePolicy {
virtual bool IsStorageUnlimited(const GURL& origin);
virtual bool IsStorageSessionOnly(const GURL& origin);
virtual bool IsFileHandler(const std::string& extension_id);
+ virtual bool HasSessionOnlyOrigins();
void AddProtected(const GURL& origin) {
protected_.insert(origin);
diff --git a/webkit/database/database_tracker.cc b/webkit/database/database_tracker.cc
index 71daf48..12c6f5c 100644
--- a/webkit/database/database_tracker.cc
+++ b/webkit/database/database_tracker.cc
@@ -797,17 +797,33 @@ void DatabaseTracker::DeleteIncognitoDBDirectory() {
file_util::Delete(incognito_db_dir, true);
}
-void DatabaseTracker::ClearLocalState() {
+void DatabaseTracker::ClearLocalState(bool clear_all_databases) {
shutting_down_ = true;
+ bool has_session_only_databases =
+ special_storage_policy_.get() &&
+ special_storage_policy_->HasSessionOnlyOrigins();
+
+ // Clearning only session-only databases, and there are none.
+ if (!clear_all_databases && !has_session_only_databases)
+ return;
+
+ if (!LazyInit())
+ return;
+
std::vector<string16> origin_identifiers;
GetAllOriginIdentifiers(&origin_identifiers);
for (std::vector<string16>::iterator origin = origin_identifiers.begin();
origin != origin_identifiers.end(); ++origin) {
+ GURL origin_url =
+ webkit_database::DatabaseUtil::GetOriginFromIdentifier(*origin);
+ if (!clear_all_databases &&
+ !special_storage_policy_->IsStorageSessionOnly(origin_url)) {
+ continue;
+ }
if (special_storage_policy_.get() &&
- special_storage_policy_->IsStorageProtected(
- webkit_database::DatabaseUtil::GetOriginFromIdentifier(*origin))) {
+ special_storage_policy_->IsStorageProtected(origin_url)) {
continue;
}
webkit_database::OriginInfo origin_info;
@@ -840,8 +856,8 @@ void DatabaseTracker::Shutdown() {
}
if (is_incognito_)
DeleteIncognitoDBDirectory();
- else if (clear_local_state_on_exit_ && LazyInit())
- ClearLocalState();
+ else
+ ClearLocalState(clear_local_state_on_exit_);
}
void DatabaseTracker::SetClearLocalStateOnExit(bool clear_local_state_on_exit) {
diff --git a/webkit/database/database_tracker.h b/webkit/database/database_tracker.h
index a6e793e..1acfc92 100644
--- a/webkit/database/database_tracker.h
+++ b/webkit/database/database_tracker.h
@@ -198,10 +198,10 @@ class DatabaseTracker
// Deletes the directory that stores all DBs in incognito mode, if it exists.
void DeleteIncognitoDBDirectory();
- // Deletes databases not protected by the special storage policy if
- // |clear_local_state_on_exit_| is true and blocks databases from being
- // created/opened.
- void ClearLocalState();
+ // If clear_all_databases is true, deletes all databases not protected by
+ // special storage policy. Otherwise deletes session-only databases. Blocks
+ // databases from being created/opened.
+ void ClearLocalState(bool clear_all_databases);
bool DeleteClosedDatabase(const string16& origin_identifier,
const string16& database_name);
diff --git a/webkit/database/database_tracker_unittest.cc b/webkit/database/database_tracker_unittest.cc
index e99f075..6fa492c 100644
--- a/webkit/database/database_tracker_unittest.cc
+++ b/webkit/database/database_tracker_unittest.cc
@@ -608,6 +608,85 @@ class DatabaseTracker_TestHelper_Test {
EXPECT_FALSE(file_util::PathExists(origin1_db_dir));
}
+ static void DatabaseTrackerClearSessionOnlyDatabasesOnExit() {
+ int64 database_size = 0;
+ 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 kDescription = ASCIIToUTF16("database_description");
+
+ // Initialize the tracker database.
+ ScopedTempDir temp_dir;
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+ FilePath origin1_db_dir;
+ FilePath origin2_db_dir;
+ {
+ scoped_refptr<quota::MockSpecialStoragePolicy> special_storage_policy =
+ new quota::MockSpecialStoragePolicy;
+ special_storage_policy->AddSessionOnly(GURL(kOrigin2Url));
+ scoped_refptr<DatabaseTracker> tracker(
+ new DatabaseTracker(
+ temp_dir.path(), false, false /*clear_local_state_on_exit*/,
+ special_storage_policy, NULL,
+ base::MessageLoopProxy::current()));
+
+ // Open two new databases.
+ tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0,
+ &database_size);
+ EXPECT_EQ(0, database_size);
+ tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0,
+ &database_size);
+ EXPECT_EQ(0, database_size);
+
+ // Write some data to each file.
+ FilePath db_file;
+ db_file = tracker->GetFullDBFilePath(kOrigin1, kDB1);
+ EXPECT_TRUE(file_util::CreateDirectory(db_file.DirName()));
+ EXPECT_TRUE(EnsureFileOfSize(db_file, 1));
+
+ db_file = tracker->GetFullDBFilePath(kOrigin2, kDB2);
+ EXPECT_TRUE(file_util::CreateDirectory(db_file.DirName()));
+ EXPECT_TRUE(EnsureFileOfSize(db_file, 2));
+
+ // Store the origin database directories as long as they still exist.
+ origin1_db_dir = tracker->GetFullDBFilePath(kOrigin1, kDB1).DirName();
+ origin2_db_dir = tracker->GetFullDBFilePath(kOrigin2, kDB2).DirName();
+
+ tracker->DatabaseModified(kOrigin1, kDB1);
+ tracker->DatabaseModified(kOrigin2, kDB2);
+
+ // Close all databases.
+ tracker->DatabaseClosed(kOrigin1, kDB1);
+ tracker->DatabaseClosed(kOrigin2, kDB2);
+
+ tracker->Shutdown();
+ }
+
+ // At this point, the database tracker should be gone. Create a new one.
+ scoped_refptr<DatabaseTracker> tracker(
+ new DatabaseTracker(temp_dir.path(), false, false,
+ NULL, NULL, NULL));
+
+ // Get all data for all origins.
+ std::vector<OriginInfo> origins_info;
+ EXPECT_TRUE(tracker->GetAllOriginsInfo(&origins_info));
+ // kOrigin1 was not session-only, so it survived. kOrigin2 was session-only
+ // and it got deleted.
+ EXPECT_EQ(size_t(1), origins_info.size());
+ EXPECT_EQ(kOrigin1, origins_info[0].GetOrigin());
+ EXPECT_TRUE(
+ file_util::PathExists(tracker->GetFullDBFilePath(kOrigin1, kDB1)));
+ EXPECT_EQ(FilePath(), tracker->GetFullDBFilePath(kOrigin2, kDB2));
+
+ // The origin directory of kOrigin1 remains, but the origin directory of
+ // kOrigin2 is deleted.
+ EXPECT_TRUE(file_util::PathExists(origin1_db_dir));
+ EXPECT_FALSE(file_util::PathExists(origin2_db_dir));
+ }
+
static void EmptyDatabaseNameIsValid() {
const GURL kOrigin(kOrigin1Url);
const string16 kOriginId = DatabaseUtil::GetOriginIdentifier(kOrigin);
@@ -681,6 +760,12 @@ TEST(DatabaseTrackerTest, DatabaseTrackerClearLocalStateOnExit) {
DatabaseTracker_TestHelper_Test::DatabaseTrackerClearLocalStateOnExit();
}
+TEST(DatabaseTrackerTest, DatabaseTrackerClearSessionOnlyDatabasesOnExit) {
+ // Only works for regular mode.
+ DatabaseTracker_TestHelper_Test::
+ DatabaseTrackerClearSessionOnlyDatabasesOnExit();
+}
+
TEST(DatabaseTrackerTest, EmptyDatabaseNameIsValid) {
DatabaseTracker_TestHelper_Test::EmptyDatabaseNameIsValid();
}
diff --git a/webkit/quota/mock_special_storage_policy.cc b/webkit/quota/mock_special_storage_policy.cc
index 5787be9..c7fdb8f 100644
--- a/webkit/quota/mock_special_storage_policy.cc
+++ b/webkit/quota/mock_special_storage_policy.cc
@@ -29,4 +29,8 @@ bool MockSpecialStoragePolicy::IsFileHandler(const std::string& extension_id) {
return file_handlers_.find(extension_id) != file_handlers_.end();
}
+bool MockSpecialStoragePolicy::HasSessionOnlyOrigins() {
+ return !session_only_.empty();
+}
+
} // namespace quota
diff --git a/webkit/quota/mock_special_storage_policy.h b/webkit/quota/mock_special_storage_policy.h
index 7e54a6e..6f0ec13 100644
--- a/webkit/quota/mock_special_storage_policy.h
+++ b/webkit/quota/mock_special_storage_policy.h
@@ -21,6 +21,7 @@ class MockSpecialStoragePolicy : public quota::SpecialStoragePolicy {
virtual bool IsStorageUnlimited(const GURL& origin);
virtual bool IsStorageSessionOnly(const GURL& origin);
virtual bool IsFileHandler(const std::string& extension_id);
+ virtual bool HasSessionOnlyOrigins();
void AddProtected(const GURL& origin) {
protected_.insert(origin);
diff --git a/webkit/quota/special_storage_policy.h b/webkit/quota/special_storage_policy.h
index ed8989c..f7d80f7 100644
--- a/webkit/quota/special_storage_policy.h
+++ b/webkit/quota/special_storage_policy.h
@@ -46,6 +46,9 @@ class SpecialStoragePolicy
// when the session ends.
virtual bool IsStorageSessionOnly(const GURL& origin) = 0;
+ // Returns true if some origins are only allowed session-only storage.
+ virtual bool HasSessionOnlyOrigins() = 0;
+
// Adds/removes an observer, the policy does not take
// ownership of the observer. Should only be called on the IO thread.
void AddObserver(Observer* observer);