summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/browsing_data_remover.cc60
-rw-r--r--chrome/browser/browsing_data_remover.h25
-rw-r--r--chrome/browser/nacl_host/nacl_browser.cc91
-rw-r--r--chrome/browser/nacl_host/nacl_browser.h2
4 files changed, 148 insertions, 30 deletions
diff --git a/chrome/browser/browsing_data_remover.cc b/chrome/browser/browsing_data_remover.cc
index ee88523..1185202 100644
--- a/chrome/browser/browsing_data_remover.cc
+++ b/chrome/browser/browsing_data_remover.cc
@@ -23,6 +23,7 @@
#include "chrome/browser/extensions/extension_special_storage_policy.h"
#include "chrome/browser/history/history.h"
#include "chrome/browser/io_thread.h"
+#include "chrome/browser/nacl_host/nacl_browser.h"
#include "chrome/browser/net/chrome_url_request_context.h"
#include "chrome/browser/net/predictor.h"
#include "chrome/browser/password_manager/password_store.h"
@@ -112,6 +113,7 @@ BrowsingDataRemover::BrowsingDataRemover(Profile* profile,
media_context_getter_(profile->GetRequestContextForMedia()),
deauthorize_content_licenses_request_id_(0),
waiting_for_clear_cache_(false),
+ waiting_for_clear_nacl_cache_(false),
waiting_for_clear_cookies_count_(0),
waiting_for_clear_history_(false),
waiting_for_clear_local_storage_(false),
@@ -141,6 +143,7 @@ BrowsingDataRemover::BrowsingDataRemover(Profile* profile,
media_context_getter_(profile->GetRequestContextForMedia()),
deauthorize_content_licenses_request_id_(0),
waiting_for_clear_cache_(false),
+ waiting_for_clear_nacl_cache_(false),
waiting_for_clear_cookies_count_(0),
waiting_for_clear_history_(false),
waiting_for_clear_local_storage_(false),
@@ -156,7 +159,7 @@ BrowsingDataRemover::BrowsingDataRemover(Profile* profile,
}
BrowsingDataRemover::~BrowsingDataRemover() {
- DCHECK(all_done());
+ DCHECK(AllDone());
}
// Static.
@@ -411,6 +414,15 @@ void BrowsingDataRemover::RemoveImpl(int remove_mask,
base::Bind(&BrowsingDataRemover::ClearCacheOnIOThread,
base::Unretained(this)));
+#if !defined(DISABLE_NACL)
+ waiting_for_clear_nacl_cache_ = true;
+
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&BrowsingDataRemover::ClearNaClCacheOnIOThread,
+ base::Unretained(this)));
+#endif
+
// The PrerenderManager may have a page actively being prerendered, which
// is essentially a preemptively cached page.
prerender::PrerenderManager* prerender_manager =
@@ -486,6 +498,20 @@ base::Time BrowsingDataRemover::CalculateBeginDeleteTime(
return delete_begin_time - diff;
}
+bool BrowsingDataRemover::AllDone() {
+ return registrar_.IsEmpty() &&
+ !waiting_for_clear_cache_ &&
+ !waiting_for_clear_nacl_cache_ &&
+ !waiting_for_clear_cookies_count_&&
+ !waiting_for_clear_history_ &&
+ !waiting_for_clear_local_storage_ &&
+ !waiting_for_clear_networking_history_ &&
+ !waiting_for_clear_server_bound_certs_ &&
+ !waiting_for_clear_plugin_data_ &&
+ !waiting_for_clear_quota_managed_data_ &&
+ !waiting_for_clear_content_licenses_;
+}
+
void BrowsingDataRemover::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
@@ -503,7 +529,7 @@ void BrowsingDataRemover::Observe(int type,
void BrowsingDataRemover::NotifyAndDeleteIfDone() {
// TODO(brettw) bug 1139736: see TODO in Observe() above.
- if (!all_done())
+ if (!AllDone())
return;
set_removing(false);
@@ -630,6 +656,36 @@ void BrowsingDataRemover::DoClearCache(int rv) {
}
}
+#if !defined(DISABLE_NACL)
+void BrowsingDataRemover::ClearedNaClCache() {
+ // This function should be called on the UI thread.
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ waiting_for_clear_nacl_cache_ = false;
+
+ NotifyAndDeleteIfDone();
+}
+
+void BrowsingDataRemover::ClearedNaClCacheOnIOThread() {
+ // This function should be called on the IO thread.
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ // Notify the UI thread that we are done.
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&BrowsingDataRemover::ClearedNaClCache,
+ base::Unretained(this)));
+}
+
+void BrowsingDataRemover::ClearNaClCacheOnIOThread() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ NaClBrowser::GetInstance()->ClearValidationCache(
+ base::Bind(&BrowsingDataRemover::ClearedNaClCacheOnIOThread,
+ base::Unretained(this)));
+}
+#endif
+
void BrowsingDataRemover::ClearLocalStorageOnUIThread() {
DCHECK(waiting_for_clear_local_storage_);
diff --git a/chrome/browser/browsing_data_remover.h b/chrome/browser/browsing_data_remover.h
index 85b5280..d89541c 100644
--- a/chrome/browser/browsing_data_remover.h
+++ b/chrome/browser/browsing_data_remover.h
@@ -220,6 +220,18 @@ class BrowsingDataRemover : public content::NotificationObserver,
// Performs the actual work to delete the cache.
void DoClearCache(int rv);
+#if !defined(DISABLE_NACL)
+ // Callback for when the NaCl cache has been deleted. Invokes
+ // NotifyAndDeleteIfDone.
+ void ClearedNaClCache();
+
+ // Invokes the ClearedNaClCache on the UI thread.
+ void ClearedNaClCacheOnIOThread();
+
+ // Invoked on the IO thread to delete the NaCl cache.
+ void ClearNaClCacheOnIOThread();
+#endif
+
// Invoked on the UI thread to delete local storage.
void ClearLocalStorageOnUIThread();
@@ -270,17 +282,7 @@ class BrowsingDataRemover : public content::NotificationObserver,
base::Time CalculateBeginDeleteTime(TimePeriod time_period);
// Returns true if we're all done.
- bool all_done() {
- return registrar_.IsEmpty() && !waiting_for_clear_cache_ &&
- !waiting_for_clear_cookies_count_&&
- !waiting_for_clear_history_ &&
- !waiting_for_clear_local_storage_ &&
- !waiting_for_clear_networking_history_ &&
- !waiting_for_clear_server_bound_certs_ &&
- !waiting_for_clear_plugin_data_ &&
- !waiting_for_clear_quota_managed_data_ &&
- !waiting_for_clear_content_licenses_;
- }
+ bool AllDone();
// Setter for removing_; DCHECKs that we can only start removing if we're not
// already removing, and vice-versa.
@@ -328,6 +330,7 @@ class BrowsingDataRemover : public content::NotificationObserver,
// True if we're waiting for various data to be deleted.
// These may only be accessed from UI thread in order to avoid races!
bool waiting_for_clear_cache_;
+ bool waiting_for_clear_nacl_cache_;
// Non-zero if waiting for cookies to be cleared.
int waiting_for_clear_cookies_count_;
bool waiting_for_clear_history_;
diff --git a/chrome/browser/nacl_host/nacl_browser.cc b/chrome/browser/nacl_host/nacl_browser.cc
index 637c83c..7e62a0a 100644
--- a/chrome/browser/nacl_host/nacl_browser.cc
+++ b/chrome/browser/nacl_host/nacl_browser.cc
@@ -85,6 +85,12 @@ void WriteCache(const FilePath& filename, const Pickle* pickle) {
pickle->size());
}
+void RemoveCache(const FilePath& filename, const base::Closure& callback) {
+ file_util::Delete(filename, false);
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+ callback);
+}
+
void LogCacheQuery(ValidationCacheStatus status) {
UMA_HISTOGRAM_ENUMERATION("NaCl.ValidationCache.Query", status, CACHE_MAX);
}
@@ -109,6 +115,7 @@ NaClBrowser::NaClBrowser()
validation_cache_state_(NaClResourceUninitialized),
ok_(true) {
InitIrtFilePath();
+ InitValidationCacheFilePath();
}
NaClBrowser::~NaClBrowser() {
@@ -198,27 +205,30 @@ void NaClBrowser::OnIrtOpened(base::PlatformFileError error_code,
CheckWaiting();
}
+void NaClBrowser::InitValidationCacheFilePath() {
+ // Determine where the validation cache resides in the file system. It
+ // exists in Chrome's cache directory and is not tied to any specific
+ // profile.
+ // Start by finding the user data directory.
+ FilePath user_data_dir;
+ if (!PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) {
+ RunWithoutValidationCache();
+ return;
+ }
+ // The cache directory may or may not be the user data directory.
+ FilePath cache_file_path;
+ chrome::GetUserCacheDirectory(user_data_dir, &cache_file_path);
+ // Append the base file name to the cache directory.
+
+ validation_cache_file_path_ =
+ cache_file_path.Append(kValidationCacheFileName);
+}
+
void NaClBrowser::EnsureValidationCacheAvailable() {
if (IsOk() && validation_cache_state_ == NaClResourceUninitialized) {
if (ValidationCacheIsEnabled()) {
validation_cache_state_ = NaClResourceRequested;
- // Determine where the validation cache resides in the file system. It
- // exists in Chrome's cache directory and is not tied to any specific
- // profile.
- // Start by finding the user data directory.
- FilePath user_data_dir;
- if (!PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) {
- RunWithoutValidationCache();
- return;
- }
- // The cache directory may or may not be the user data directory.
- FilePath cache_file_path;
- chrome::GetUserCacheDirectory(user_data_dir, &cache_file_path);
- // Append the base file name to the cache directory.
- validation_cache_file_path_ =
- cache_file_path.Append(kValidationCacheFileName);
-
// Structure for carrying data between the callbacks.
std::string* data = new std::string();
// We can get away not giving this a sequence ID because this is the first
@@ -239,6 +249,11 @@ void NaClBrowser::EnsureValidationCacheAvailable() {
}
void NaClBrowser::OnValidationCacheLoaded(const std::string *data) {
+ // Did the cache get cleared before the load completed? If so, ignore the
+ // incoming data.
+ if (validation_cache_state_ == NaClResourceReady)
+ return;
+
if (data->size() == 0) {
// No file found.
validation_cache_.Reset();
@@ -315,6 +330,44 @@ void NaClBrowser::SetKnownToValidate(const std::string& signature,
}
}
+void NaClBrowser::ClearValidationCache(const base::Closure& callback) {
+ // Note: this method may be called before EnsureValidationCacheAvailable has
+ // been invoked. In other words, this method may be called before any NaCl
+ // processes have been created. This method must succeed and invoke the
+ // callback in such a case. If it does not invoke the callback, Chrome's UI
+ // will hang in that case.
+ validation_cache_.Reset();
+ off_the_record_validation_cache_.Reset();
+
+ if (validation_cache_file_path_.empty()) {
+ // Can't figure out what file to remove, but don't drop the callback.
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+ callback);
+ } else {
+ // Delegate the removal of the cache from the filesystem to another thread
+ // to avoid blocking the IO thread.
+ // This task is dispatched immediately, not delayed and coalesced, because
+ // the user interface for cache clearing is likely waiting for the callback.
+ // In addition, we need to make sure the cache is actually cleared before
+ // invoking the callback to meet the implicit guarantees of the UI.
+ content::BrowserThread::PostBlockingPoolSequencedTask(
+ kValidationCacheSequenceName,
+ FROM_HERE,
+ base::Bind(RemoveCache, validation_cache_file_path_, callback));
+ }
+
+ // Make sure any delayed tasks to persist the cache to the filesystem are
+ // squelched.
+ validation_cache_is_modified_ = false;
+
+ // If the cache is cleared before it is loaded from the filesystem, act as if
+ // we just loaded an empty cache.
+ if (validation_cache_state_ != NaClResourceReady) {
+ validation_cache_state_ = NaClResourceReady;
+ CheckWaiting();
+ }
+}
+
void NaClBrowser::MarkValidationCacheAsModified() {
if (!validation_cache_is_modified_) {
// Wait before persisting to disk. This can coalesce multiple cache
@@ -329,7 +382,11 @@ void NaClBrowser::MarkValidationCacheAsModified() {
}
void NaClBrowser::PersistValidationCache() {
- if (!validation_cache_file_path_.empty()) {
+ // validation_cache_is_modified_ may be false if the cache was cleared while
+ // this delayed task was pending.
+ // validation_cache_file_path_ may be empty if something went wrong during
+ // initialization.
+ if (validation_cache_is_modified_ && !validation_cache_file_path_.empty()) {
Pickle* pickle = new Pickle();
validation_cache_.Serialize(pickle);
diff --git a/chrome/browser/nacl_host/nacl_browser.h b/chrome/browser/nacl_host/nacl_browser.h
index f90e542..d6298f4 100644
--- a/chrome/browser/nacl_host/nacl_browser.h
+++ b/chrome/browser/nacl_host/nacl_browser.h
@@ -54,6 +54,7 @@ class NaClBrowser {
bool QueryKnownToValidate(const std::string& signature, bool off_the_record);
void SetKnownToValidate(const std::string& signature, bool off_the_record);
+ void ClearValidationCache(const base::Closure& callback);
private:
friend struct DefaultSingletonTraits<NaClBrowser>;
@@ -74,6 +75,7 @@ class NaClBrowser {
void OnIrtOpened(base::PlatformFileError error_code,
base::PassPlatformFile file, bool created);
+ void InitValidationCacheFilePath();
void EnsureValidationCacheAvailable();
void OnValidationCacheLoaded(const std::string* data);
void RunWithoutValidationCache();