summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/chrome_content_browser_client.cc59
-rw-r--r--chrome/browser/chrome_content_browser_client.h1
-rw-r--r--chrome/browser/extensions/data_deleter.cc12
-rw-r--r--content/browser/browser_context.cc29
-rw-r--r--content/browser/storage_partition_impl.cc120
-rw-r--r--content/browser/storage_partition_impl.h1
-rw-r--r--content/browser/storage_partition_impl_map.cc163
-rw-r--r--content/browser/storage_partition_impl_map.h7
-rw-r--r--content/public/browser/browser_context.h3
-rw-r--r--content/public/browser/content_browser_client.cc1
-rw-r--r--content/public/browser/content_browser_client.h18
-rw-r--r--content/public/browser/storage_partition.h4
12 files changed, 337 insertions, 81 deletions
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 450a7ab..cd5048a 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -501,9 +501,16 @@ bool ChromeContentBrowserClient::IsValidStoragePartitionId(
void ChromeContentBrowserClient::GetStoragePartitionConfigForSite(
content::BrowserContext* browser_context,
const GURL& site,
+ bool can_be_default,
std::string* partition_domain,
std::string* partition_name,
bool* in_memory) {
+ // Default to the browser-wide storage partition and override based on |site|
+ // below.
+ partition_domain->clear();
+ partition_name->clear();
+ *in_memory = false;
+
// For the webview tag, we create special guest processes, which host the
// tag content separately from the main application that embeds the tag.
// A webview tag can specify both the partition name and whether the storage
@@ -523,30 +530,44 @@ void ChromeContentBrowserClient::GetStoragePartitionConfigForSite(
// URL was created, so it needs to be decoded.
*partition_name = net::UnescapeURLComponent(site.query(),
net::UnescapeRule::NORMAL);
- return;
- }
+ } else if (site.SchemeIs(extensions::kExtensionScheme)) {
+ // If |can_be_default| is false, the caller is stating that the |site|
+ // should be parsed as if it had isolated storage. In particular it is
+ // important to NOT check ExtensionService for the is_storage_isolated()
+ // attribute because this code path is run during Extension uninstall
+ // to do cleanup after the Extension has already been unloaded from the
+ // ExtensionService.
+ bool is_isolated = !can_be_default;
+ if (can_be_default) {
+ const Extension* extension = NULL;
+ Profile* profile = Profile::FromBrowserContext(browser_context);
+ ExtensionService* extension_service =
+ extensions::ExtensionSystem::Get(profile)->extension_service();
+ if (extension_service) {
+ extension = extension_service->extensions()->
+ GetExtensionOrAppByURL(ExtensionURLInfo(site));
+ if (extension && extension->is_storage_isolated()) {
+ is_isolated = true;
+ }
+ }
+ }
- const Extension* extension = NULL;
- Profile* profile = Profile::FromBrowserContext(browser_context);
- ExtensionService* extension_service =
- extensions::ExtensionSystem::Get(profile)->extension_service();
- if (extension_service) {
- extension = extension_service->extensions()->
- GetExtensionOrAppByURL(ExtensionURLInfo(site));
- if (extension && extension->is_storage_isolated()) {
- // Extensions which have storage isolation enabled (e.g., apps), use
- // the extension id as the |partition_domain|.
- *partition_domain = extension->id();
- partition_name->clear();
+ if (is_isolated) {
+ CHECK(site.has_host());
+ // For extensions with isolated storage, the the host of the |site| is
+ // the |partition_domain|. The |in_memory| and |partition_name| are only
+ // used in guest schemes so they are cleared here.
+ *partition_domain = site.host();
*in_memory = false;
- return;
+ partition_name->clear();
}
}
- // All other cases use the default, browser-wide, storage partition.
- partition_domain->clear();
- partition_name->clear();
- *in_memory = false;
+ // Assert that if |can_be_default| is false, the code above must have found a
+ // non-default partition. If this fails, the caller has a serious logic
+ // error about which StoragePartition they expect to be in and it is not
+ // safe to continue.
+ CHECK(can_be_default || !partition_domain->empty());
}
content::WebContentsViewDelegate*
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index 78b741c..0b9e438 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -52,6 +52,7 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient {
virtual void GetStoragePartitionConfigForSite(
content::BrowserContext* browser_context,
const GURL& site,
+ bool can_be_default,
std::string* partition_domain,
std::string* partition_name,
bool* in_memory) OVERRIDE;
diff --git a/chrome/browser/extensions/data_deleter.cc b/chrome/browser/extensions/data_deleter.cc
index b4eac2b..fe84639 100644
--- a/chrome/browser/extensions/data_deleter.cc
+++ b/chrome/browser/extensions/data_deleter.cc
@@ -24,16 +24,16 @@ void DataDeleter::StartDeleting(Profile* profile,
const std::string& extension_id,
const GURL& storage_origin,
bool is_storage_isolated) {
- // TODO(ajwong): If |is_storage_isolated|, we should just blowaway the
- // whole directory that the associated StoragePartition is located at. To do
- // this, we need to ensure that all contexts referencing that directory have
- // closed their file handles, otherwise Windows will complain.
- //
- // http://www.crbug.com/85127
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(profile);
const GURL& site = Extension::GetBaseURLFromExtensionId(extension_id);
+
+ if (is_storage_isolated) {
+ BrowserContext::AsyncObliterateStoragePartition(profile, site);
+ return;
+ }
+
content::StoragePartition* partition =
BrowserContext::GetStoragePartitionForSite(profile, site);
diff --git a/content/browser/browser_context.cc b/content/browser/browser_context.cc
index d8bc87e..79355bc 100644
--- a/content/browser/browser_context.cc
+++ b/content/browser/browser_context.cc
@@ -37,11 +37,8 @@ namespace {
const char* kDownloadManagerKeyName = "download_manager";
const char* kStorageParitionMapKeyName = "content_storage_partition_map";
-StoragePartition* GetStoragePartitionFromConfig(
- BrowserContext* browser_context,
- const std::string& partition_domain,
- const std::string& partition_name,
- bool in_memory) {
+StoragePartitionImplMap* GetStoragePartitionMap(
+ BrowserContext* browser_context) {
StoragePartitionImplMap* partition_map =
static_cast<StoragePartitionImplMap*>(
browser_context->GetUserData(kStorageParitionMapKeyName));
@@ -49,6 +46,16 @@ StoragePartition* GetStoragePartitionFromConfig(
partition_map = new StoragePartitionImplMap(browser_context);
browser_context->SetUserData(kStorageParitionMapKeyName, partition_map);
}
+ return partition_map;
+}
+
+StoragePartition* GetStoragePartitionFromConfig(
+ BrowserContext* browser_context,
+ const std::string& partition_domain,
+ const std::string& partition_name,
+ bool in_memory) {
+ StoragePartitionImplMap* partition_map =
+ GetStoragePartitionMap(browser_context);
if (browser_context->IsOffTheRecord())
in_memory = true;
@@ -84,6 +91,13 @@ void PurgeMemoryOnIOThread(appcache::AppCacheService* appcache_service) {
} // namespace
+// static
+void BrowserContext::AsyncObliterateStoragePartition(
+ BrowserContext* browser_context,
+ const GURL& site) {
+ GetStoragePartitionMap(browser_context)->AsyncObliterate(site);
+}
+
DownloadManager* BrowserContext::GetDownloadManager(
BrowserContext* context) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -116,7 +130,7 @@ StoragePartition* BrowserContext::GetStoragePartition(
// this conditional and require that |site_instance| is non-NULL.
if (site_instance) {
GetContentClient()->browser()->GetStoragePartitionConfigForSite(
- browser_context, site_instance->GetSiteURL(),
+ browser_context, site_instance->GetSiteURL(), true,
&partition_domain, &partition_name, &in_memory);
}
@@ -132,7 +146,8 @@ StoragePartition* BrowserContext::GetStoragePartitionForSite(
bool in_memory;
GetContentClient()->browser()->GetStoragePartitionConfigForSite(
- browser_context, site, &partition_domain, &partition_name, &in_memory);
+ browser_context, site, true, &partition_domain, &partition_name,
+ &in_memory);
return GetStoragePartitionFromConfig(
browser_context, partition_domain, partition_name, in_memory);
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index da17ff1..a3eafab 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -8,6 +8,7 @@
#include "content/browser/fileapi/browser_file_system_helper.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/dom_storage_context.h"
#include "content/public/browser/indexed_db_context.h"
#include "net/base/completion_callback.h"
#include "net/base/net_errors.h"
@@ -15,17 +16,38 @@
#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_context.h"
#include "webkit/database/database_tracker.h"
-#include "webkit/database/database_util.h"
+#include "webkit/dom_storage/dom_storage_types.h"
#include "webkit/quota/quota_manager.h"
namespace content {
namespace {
-void ClearDataOnIOThread(
+void DoNothingStatusCallback(quota::QuotaStatusCode status) {
+ // Do nothing.
+}
+
+void ClearQuotaManagedOriginsOnIOThread(
+ const scoped_refptr<quota::QuotaManager>& quota_manager,
+ const std::set<GURL>& origins,
+ quota::StorageType type) {
+ // The QuotaManager manages all storage other than cookies, LocalStorage,
+ // and SessionStorage. This loop wipes out most HTML5 storage for the given
+ // origins.
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ std::set<GURL>::const_iterator origin;
+ for (std::set<GURL>::const_iterator origin = origins.begin();
+ origin != origins.end(); ++origin) {
+ quota_manager->DeleteOriginData(*origin, type,
+ quota::QuotaClient::kAllClientsMask,
+ base::Bind(&DoNothingStatusCallback));
+ }
+}
+
+void ClearOriginOnIOThread(
const GURL& storage_origin,
const scoped_refptr<net::URLRequestContextGetter>& request_context,
- const scoped_refptr<ChromeAppCacheService>& appcache_service) {
+ const scoped_refptr<quota::QuotaManager>& quota_manager) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
// Handle the cookies.
@@ -36,26 +58,54 @@ void ClearDataOnIOThread(
cookie_monster->DeleteAllForHostAsync(
storage_origin, net::CookieMonster::DeleteCallback());
- // Clear out appcache.
- appcache_service->DeleteAppCachesForOrigin(storage_origin,
- net::CompletionCallback());
+ // Handle all HTML5 storage other than DOMStorageContext.
+ std::set<GURL> origins;
+ origins.insert(storage_origin);
+ ClearQuotaManagedOriginsOnIOThread(quota_manager, origins,
+ quota::kStorageTypePersistent);
+ ClearQuotaManagedOriginsOnIOThread(quota_manager, origins,
+ quota::kStorageTypeTemporary);
}
-void ClearDataOnFileThread(
- const GURL& storage_origin,
- string16 origin_id,
- const scoped_refptr<webkit_database::DatabaseTracker> &database_tracker,
- const scoped_refptr<fileapi::FileSystemContext>& file_system_context) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+void ClearAllDataOnIOThread(
+ const scoped_refptr<net::URLRequestContextGetter>& request_context,
+ const scoped_refptr<quota::QuotaManager>& quota_manager) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- // Clear out the HTML5 filesystem.
- file_system_context->DeleteDataForOriginOnFileThread(storage_origin);
+ // Handle the cookies.
+ net::CookieMonster* cookie_monster =
+ request_context->GetURLRequestContext()->cookie_store()->
+ GetCookieMonster();
+ if (cookie_monster)
+ cookie_monster->DeleteAllAsync(net::CookieMonster::DeleteCallback());
+
+ // Handle all HTML5 storage other than DOMStorageContext.
+ quota_manager->GetOriginsModifiedSince(
+ quota::kStorageTypePersistent, base::Time(),
+ base::Bind(&ClearQuotaManagedOriginsOnIOThread, quota_manager));
+ quota_manager->GetOriginsModifiedSince(
+ quota::kStorageTypeTemporary, base::Time(),
+ base::Bind(&ClearQuotaManagedOriginsOnIOThread, quota_manager));
+}
- // Clear out the database tracker. We just let this run until completion
- // without notification.
- int rv = database_tracker->DeleteDataForOrigin(
- origin_id, net::CompletionCallback());
- DCHECK(rv == net::OK || rv == net::ERR_IO_PENDING);
+void OnLocalStorageUsageInfo(
+ const scoped_refptr<DOMStorageContextImpl>& dom_storage_context,
+ const std::vector<dom_storage::LocalStorageUsageInfo>& infos) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ for (size_t i = 0; i < infos.size(); ++i) {
+ dom_storage_context->DeleteLocalStorage(infos[i].origin);
+ }
+}
+
+void OnSessionStorageUsageInfo(
+ const scoped_refptr<DOMStorageContextImpl>& dom_storage_context,
+ const std::vector<dom_storage::SessionStorageUsageInfo>& infos) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ for (size_t i = 0; i < infos.size(); ++i) {
+ dom_storage_context->DeleteSessionStorage(infos[i]);
+ }
}
} // namespace
@@ -192,28 +242,28 @@ void StoragePartitionImpl::AsyncClearDataForOrigin(
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
- base::Bind(&ClearDataOnIOThread,
+ base::Bind(&ClearOriginOnIOThread,
storage_origin,
make_scoped_refptr(request_context_getter),
- appcache_service_));
-
- string16 origin_id =
- webkit_database::DatabaseUtil::GetOriginIdentifier(storage_origin);
- BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
- base::Bind(&ClearDataOnFileThread,
- storage_origin,
- origin_id,
- database_tracker_,
- filesystem_context_));
+ quota_manager_));
GetDOMStorageContext()->DeleteLocalStorage(storage_origin);
+}
+void StoragePartitionImpl::AsyncClearAllData() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ // We ignore the media request context because it shares the same cookie store
+ // as the main request context.
BrowserThread::PostTask(
- BrowserThread::WEBKIT_DEPRECATED, FROM_HERE,
- base::Bind(
- &IndexedDBContext::DeleteForOrigin,
- indexed_db_context_,
- storage_origin));
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&ClearAllDataOnIOThread, url_request_context_,
+ quota_manager_));
+
+ dom_storage_context_->GetLocalStorageUsage(
+ base::Bind(&OnLocalStorageUsageInfo, dom_storage_context_));
+ dom_storage_context_->GetSessionStorageUsage(
+ base::Bind(&OnSessionStorageUsageInfo, dom_storage_context_));
}
void StoragePartitionImpl::SetURLRequestContext(
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h
index fe0c292..46daacd 100644
--- a/content/browser/storage_partition_impl.h
+++ b/content/browser/storage_partition_impl.h
@@ -32,6 +32,7 @@ class StoragePartitionImpl : public StoragePartition {
virtual void AsyncClearDataForOrigin(
const GURL& storage_origin,
net::URLRequestContextGetter* request_context_getter) OVERRIDE;
+ virtual void AsyncClearAllData() OVERRIDE;
private:
friend class StoragePartitionImplMap;
diff --git a/content/browser/storage_partition_impl_map.cc b/content/browser/storage_partition_impl_map.cc
index eb7ae78..01c0593 100644
--- a/content/browser/storage_partition_impl_map.cc
+++ b/content/browser/storage_partition_impl_map.cc
@@ -7,9 +7,11 @@
#include "base/bind.h"
#include "base/callback.h"
#include "base/file_path.h"
+#include "base/file_util.h"
#include "base/stl_util.h"
#include "base/string_util.h"
#include "base/string_number_conversions.h"
+#include "base/threading/worker_pool.h"
#include "content/browser/appcache/chrome_appcache_service.h"
#include "content/browser/fileapi/browser_file_system_helper.h"
#include "content/browser/fileapi/chrome_blob_storage_context.h"
@@ -22,6 +24,7 @@
#include "content/browser/tcmalloc_internals_request_job.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/url_constants.h"
@@ -238,6 +241,99 @@ const FilePath::CharType kDefaultPartitionDirname[] =
// partition domain.
const int kPartitionNameHashBytes = 6;
+// Needed for selecting all files in ObliterateOneDirectory() below.
+#if defined(OS_POSIX)
+const int kAllFileTypes = file_util::FileEnumerator::FILES |
+ file_util::FileEnumerator::DIRECTORIES |
+ file_util::FileEnumerator::SHOW_SYM_LINKS;
+#else
+const int kAllFileTypes = file_util::FileEnumerator::FILES |
+ file_util::FileEnumerator::DIRECTORIES;
+#endif
+
+FilePath GetStoragePartitionDomainPath(
+ const std::string& partition_domain) {
+ CHECK(IsStringUTF8(partition_domain));
+
+ return FilePath(kStoragePartitionDirname).Append(kExtensionsDirname)
+ .Append(FilePath::FromUTF8Unsafe(partition_domain));
+}
+
+// Helper function for doing a depth-first deletion of the data on disk.
+// Examines paths directly in |current_dir| (no recursion) and tries to
+// delete from disk anything that is in, or isn't a parent of something in
+// |paths_to_keep|. Paths that need further expansion are added to
+// |paths_to_consider|.
+void ObliterateOneDirectory(const FilePath& current_dir,
+ const std::vector<FilePath>& paths_to_keep,
+ std::vector<FilePath>* paths_to_consider) {
+ file_util::FileEnumerator enumerator(current_dir, false, kAllFileTypes);
+ for (FilePath to_delete = enumerator.Next(); !to_delete.empty();
+ to_delete = enumerator.Next()) {
+ // Enum tracking which of the 3 possible actions to take for |to_delete|.
+ enum { kSkip, kEnqueue, kDelete } action = kDelete;
+
+ for (std::vector<FilePath>::const_iterator to_keep = paths_to_keep.begin();
+ to_keep != paths_to_keep.end();
+ ++to_keep) {
+ if (to_delete == *to_keep) {
+ action = kSkip;
+ break;
+ } else if (to_delete.IsParent(*to_keep)) {
+ // |to_delete| contains a path to keep. Add to stack for further
+ // processing.
+ action = kEnqueue;
+ break;
+ }
+ }
+
+ switch (action) {
+ case kDelete:
+ file_util::Delete(to_delete, true);
+ break;
+
+ case kEnqueue:
+ paths_to_consider->push_back(to_delete);
+ break;
+
+ case kSkip:
+ break;
+ }
+ }
+}
+
+// Synchronously attempts to delete |root|, preserving only entries in
+// |paths_to_keep|. If there are no entries in |paths_to_keep| on disk, then it
+// completely removes |root|. All paths must be absolute paths.
+void BlockingObliteratePath(const FilePath& root,
+ const std::vector<FilePath>& paths_to_keep) {
+ // Reduce |paths_to_keep| set to those under the root and actually on disk.
+ std::vector<FilePath> valid_paths_to_keep;
+ for (std::vector<FilePath>::const_iterator it = paths_to_keep.begin();
+ it != paths_to_keep.end();
+ ++it) {
+ if (root.IsParent(*it) && file_util::PathExists(*it))
+ valid_paths_to_keep.push_back(*it);
+ }
+
+ // If none of the |paths_to_keep| are valid anymore then we just whack the
+ // root and be done with it.
+ if (valid_paths_to_keep.empty()) {
+ file_util::Delete(root, true);
+ return;
+ }
+
+ // Otherwise, start at the root and delete everything that is not in
+ // |valid_paths_to_keep|.
+ std::vector<FilePath> paths_to_consider;
+ paths_to_consider.push_back(root);
+ while(!paths_to_consider.empty()) {
+ FilePath path = paths_to_consider.back();
+ paths_to_consider.pop_back();
+ ObliterateOneDirectory(path, valid_paths_to_keep, &paths_to_consider);
+ }
+}
+
} // namespace
// static
@@ -247,11 +343,12 @@ FilePath StoragePartitionImplMap::GetStoragePartitionPath(
if (partition_domain.empty())
return FilePath();
- CHECK(IsStringUTF8(partition_domain));
-
- FilePath path = FilePath(kStoragePartitionDirname).Append(kExtensionsDirname)
- .Append(FilePath::FromUTF8Unsafe(partition_domain));
+ FilePath path = GetStoragePartitionDomainPath(partition_domain);
+ // TODO(ajwong): Mangle in-memory into this somehow, either by putting
+ // it into the partition_name, or by manually adding another path component
+ // here. Otherwise, it's possible to have an in-memory StoragePartition and
+ // a persistent one that return the same FilePath for GetPath().
if (!partition_name.empty()) {
// For analysis of why we can ignore collisions, see the comment above
// kPartitionNameHashBytes.
@@ -264,7 +361,6 @@ FilePath StoragePartitionImplMap::GetStoragePartitionPath(
return path.Append(kDefaultPartitionDirname);
}
-
StoragePartitionImplMap::StoragePartitionImplMap(
BrowserContext* browser_context)
: browser_context_(browser_context),
@@ -317,11 +413,61 @@ StoragePartitionImpl* StoragePartitionImplMap::Get(
browser_context_->GetMediaRequestContextForStoragePartition(
partition->GetPath(), in_memory));
- PostCreateInitialization(partition);
+ PostCreateInitialization(partition, in_memory);
return partition;
}
+void StoragePartitionImplMap::AsyncObliterate(const GURL& site) {
+ // This method should avoid creating any StoragePartition (which would
+ // create more open file handles) so that it can delete as much of the
+ // data off disk as possible.
+ std::string partition_domain;
+ std::string partition_name;
+ bool in_memory = false;
+ GetContentClient()->browser()->GetStoragePartitionConfigForSite(
+ browser_context_, site, false, &partition_domain,
+ &partition_name, &in_memory);
+
+ // The default partition is the whole profile. We can't obliterate that and
+ // should never even try.
+ CHECK(!partition_domain.empty()) << site;
+
+ // Find the active partitions for the domain. Because these partitions are
+ // active, it is not possible to just delete the directories that contain
+ // the backing data structures without causing the browser to crash. Instead,
+ // of deleteing the directory, we tell each storage context later to
+ // remove any data they have saved. This will leave the directory structure
+ // intact but it will only contain empty databases.
+ std::vector<StoragePartitionImpl*> active_partitions;
+ std::vector<FilePath> paths_to_keep;
+ for (PartitionMap::const_iterator it = partitions_.begin();
+ it != partitions_.end();
+ ++it) {
+ const StoragePartitionConfig& config = it->first;
+ if (config.partition_domain == partition_domain) {
+ it->second->AsyncClearAllData();
+ if (!config.in_memory) {
+ paths_to_keep.push_back(it->second->GetPath());
+ }
+ }
+ }
+
+ // Start a best-effort delete of the on-disk storage excluding paths that are
+ // known to still be in use. This is to delete any previously created
+ // StoragePartition state that just happens to not have been used during this
+ // run of the browser.
+ FilePath domain_root = browser_context_->GetPath().Append(
+ GetStoragePartitionDomainPath(partition_domain));
+ base::WorkerPool::PostTask(
+ FROM_HERE,
+ base::Bind(&BlockingObliteratePath, domain_root, paths_to_keep),
+ true);
+
+ // TODO(ajwong): Schedule a final AsyncObliterate of the whole directory on
+ // the next browser start. http://crbug.com/85127.
+}
+
void StoragePartitionImplMap::ForEach(
const BrowserContext::StoragePartitionCallback& callback) {
for (PartitionMap::const_iterator it = partitions_.begin();
@@ -332,14 +478,15 @@ void StoragePartitionImplMap::ForEach(
}
void StoragePartitionImplMap::PostCreateInitialization(
- StoragePartitionImpl* partition) {
+ StoragePartitionImpl* partition,
+ bool in_memory) {
// Check first to avoid memory leak in unittests.
if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&ChromeAppCacheService::InitializeOnIOThread,
partition->GetAppCacheService(),
- browser_context_->IsOffTheRecord() ? FilePath() :
+ in_memory ? FilePath() :
partition->GetPath().Append(kAppCacheDirname),
browser_context_->GetResourceContext(),
make_scoped_refptr(partition->GetURLRequestContext()),
diff --git a/content/browser/storage_partition_impl_map.h b/content/browser/storage_partition_impl_map.h
index 9da35c3..5c25e02 100644
--- a/content/browser/storage_partition_impl_map.h
+++ b/content/browser/storage_partition_impl_map.h
@@ -32,6 +32,10 @@ class StoragePartitionImplMap : public base::SupportsUserData::Data {
const std::string& partition_name,
bool in_memory);
+ // Starts an asynchronous best-effort attempt to delete all on-disk storage
+ // related to |site|, avoiding any directories that are known to be in use.
+ void AsyncObliterate(const GURL& site);
+
void ForEach(const BrowserContext::StoragePartitionCallback& callback);
private:
@@ -93,7 +97,8 @@ class StoragePartitionImplMap : public base::SupportsUserData::Data {
// TODO(ajwong): Is there a way to make it so that Get()'s implementation
// doesn't need to be aware of this ordering? Revisit when refactoring
// ResourceContext and AppCache to respect storage partitions.
- void PostCreateInitialization(StoragePartitionImpl* partition);
+ void PostCreateInitialization(StoragePartitionImpl* partition,
+ bool in_memory);
BrowserContext* browser_context_; // Not Owned.
PartitionMap partitions_;
diff --git a/content/public/browser/browser_context.h b/content/public/browser/browser_context.h
index addc4d7..ff4446f 100644
--- a/content/public/browser/browser_context.h
+++ b/content/public/browser/browser_context.h
@@ -50,6 +50,9 @@ class CONTENT_EXPORT BrowserContext : public base::SupportsUserData {
static void ForEachStoragePartition(
BrowserContext* browser_context,
const StoragePartitionCallback& callback);
+ static void AsyncObliterateStoragePartition(
+ BrowserContext* browser_context,
+ const GURL& site);
// DON'T USE THIS. GetDefaultStoragePartition() is going away.
// Use GetStoragePartition() instead. Ask ajwong@ if you have problems.
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index 65374cf..05ddc93 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -177,6 +177,7 @@ bool ContentBrowserClient::IsValidStoragePartitionId(
void ContentBrowserClient::GetStoragePartitionConfigForSite(
BrowserContext* browser_context,
const GURL& site,
+ bool can_be_default,
std::string* partition_domain,
std::string* partition_name,
bool* in_memory) {
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 228e4ee..7368ebb 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -278,14 +278,22 @@ class CONTENT_EXPORT ContentBrowserClient {
// Allows the embedder to provide a storage parititon configuration for a
// site. A storage partition configuration includes a domain of the embedder's
// choice, an optional name within that domain, and whether the partition is
- // in-memory only. The |partition_domain| is [a-z]* UTF-8 string, specifying
- // the domain in which partitions live (similar to namespace). Within a
- // domain, partitions can be uniquely identified by the combination of
- // |partition_name| and |in_memory| values. When a partition is not to be
- // persisted, the |in_memory| value must be set to true.
+ // in-memory only.
+ //
+ // If |can_be_default| is false, the caller is telling the embedder that the
+ // |site| is known to not be in the default partition. This is useful in
+ // some shutdown situations where the bookkeeping logic that maps sites to
+ // their partition configuration are no longer valid.
+ //
+ // The |partition_domain| is [a-z]* UTF-8 string, specifying the domain in
+ // which partitions live (similar to namespace). Within a domain, partitions
+ // can be uniquely identified by the combination of |partition_name| and
+ // |in_memory| values. When a partition is not to be persisted, the
+ // |in_memory| value must be set to true.
virtual void GetStoragePartitionConfigForSite(
content::BrowserContext* browser_context,
const GURL& site,
+ bool can_be_default,
std::string* partition_domain,
std::string* partition_name,
bool* in_memory);
diff --git a/content/public/browser/storage_partition.h b/content/public/browser/storage_partition.h
index a06a311..2a905d9 100644
--- a/content/public/browser/storage_partition.h
+++ b/content/public/browser/storage_partition.h
@@ -68,6 +68,10 @@ class StoragePartition {
const GURL& storage_origin,
net::URLRequestContextGetter* request_context_getter) = 0;
+ // Similar to AsyncClearDataForOrigin(), but deletes all data out of the
+ // StoragePartition rather than just the data related to this origin.
+ virtual void AsyncClearAllData() = 0;
+
protected:
virtual ~StoragePartition() {}
};