| Index: content/browser/appcache/chrome_appcache_service.cc
|
| diff --git a/content/browser/appcache/chrome_appcache_service.cc b/content/browser/appcache/chrome_appcache_service.cc
|
| index 169f59eaa919f7aa9ce22a1fc497c8dade11b063..75ef620309117b66f9dd8c2e328dcbf76192e9f4 100644
|
| --- a/content/browser/appcache/chrome_appcache_service.cc
|
| +++ b/content/browser/appcache/chrome_appcache_service.cc
|
| @@ -14,33 +14,26 @@
|
|
|
| static bool has_initialized_thread_ids;
|
|
|
| -namespace {
|
| -
|
| -// Used to defer deleting of local storage until the destructor has finished.
|
| -void DeleteLocalStateOnIOThread(FilePath cache_path) {
|
| - // Post the actual deletion to the DB thread to ensure it happens after the
|
| - // database file has been closed.
|
| - BrowserThread::PostTask(
|
| - BrowserThread::DB, FROM_HERE,
|
| - NewRunnableFunction<bool(*)(const FilePath&, bool), FilePath, bool>(
|
| - &file_util::Delete, cache_path, true));
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| // ----------------------------------------------------------------------------
|
|
|
| ChromeAppCacheService::ChromeAppCacheService(
|
| quota::QuotaManagerProxy* quota_manager_proxy)
|
| : AppCacheService(quota_manager_proxy),
|
| - resource_context_(NULL), clear_local_state_on_exit_(false) {
|
| + resource_context_(NULL),
|
| + ALLOW_THIS_IN_INITIALIZER_LIST(appcache_got_info_callback_(
|
| + this, &ChromeAppCacheService::OnGotAppCacheInfo)),
|
| + ALLOW_THIS_IN_INITIALIZER_LIST(origin_deleted_callback_(
|
| + this, &ChromeAppCacheService::OnOriginDeleted)),
|
| + origins_to_be_deleted_count_(0),
|
| + appcaches_cleared_event_(new base::WaitableEvent(true, false)),
|
| + appcaches_cleared_callback_(NULL),
|
| + waiting_for_clear_appcaches_(false) {
|
| }
|
|
|
| void ChromeAppCacheService::InitializeOnIOThread(
|
| const FilePath& cache_path,
|
| const content::ResourceContext* resource_context,
|
| - scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy,
|
| - bool clear_local_state_on_exit) {
|
| + scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
|
|
| if (!has_initialized_thread_ids) {
|
| @@ -52,7 +45,6 @@ void ChromeAppCacheService::InitializeOnIOThread(
|
| resource_context_ = resource_context;
|
| registrar_.Add(
|
| this, NotificationType::PURGE_MEMORY, NotificationService::AllSources());
|
| - SetClearLocalStateOnExit(clear_local_state_on_exit);
|
|
|
| // Init our base class.
|
| Initialize(cache_path_,
|
| @@ -62,26 +54,72 @@ void ChromeAppCacheService::InitializeOnIOThread(
|
| }
|
|
|
| ChromeAppCacheService::~ChromeAppCacheService() {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| +}
|
|
|
| - if (clear_local_state_on_exit_ && !cache_path_.empty()) {
|
| +base::WaitableEvent* ChromeAppCacheService::ClearAppCache(
|
| + net::CompletionCallback* callback)
|
| +{
|
| + if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
|
| BrowserThread::PostTask(
|
| - BrowserThread::IO, FROM_HERE,
|
| - NewRunnableFunction(DeleteLocalStateOnIOThread, cache_path_));
|
| + BrowserThread::IO, FROM_HERE,
|
| + NewRunnableMethod(this,
|
| + &ChromeAppCacheService::ClearAppCache,
|
| + callback));
|
| + return appcaches_cleared_event_.get();
|
| }
|
| +
|
| + // Only one appcache deletion should be in progress at any given time.
|
| + DCHECK(waiting_for_clear_appcaches_ == false);
|
| + waiting_for_clear_appcaches_ = true;
|
| + appcaches_cleared_callback_ = callback;
|
| + appcaches_cleared_event_->Reset();
|
| +
|
| + // Keep the ChromeAppCacheService instance alive until the deletion has
|
| + // finished.
|
| + AddRef();
|
| +
|
| + appcache_info_ = new appcache::AppCacheInfoCollection;
|
| + GetAllAppCacheInfo(
|
| + appcache_info_, &appcache_got_info_callback_);
|
| + // Continues in OnGotAppCacheInfo.
|
| +
|
| + return appcaches_cleared_event_.get();
|
| }
|
|
|
| -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,
|
| - NewRunnableMethod(this,
|
| - &ChromeAppCacheService::SetClearLocalStateOnExit,
|
| - clear_local_state));
|
| - return;
|
| +void ChromeAppCacheService::OnGotAppCacheInfo(int rv) {
|
| + using appcache::AppCacheInfoVector;
|
| + typedef std::map<GURL, AppCacheInfoVector> InfoByOrigin;
|
| +
|
| + origins_to_be_deleted_count_ = 0;
|
| + for (InfoByOrigin::const_iterator origin =
|
| + appcache_info_->infos_by_origin.begin();
|
| + origin != appcache_info_->infos_by_origin.end(); ++origin) {
|
| +
|
| + if (special_storage_policy_->IsStorageProtected(origin->first))
|
| + continue;
|
| +
|
| + ++origins_to_be_deleted_count_;
|
| + DeleteAppCachesForOrigin(origin->first, &origin_deleted_callback_);
|
| + }
|
| +
|
| + if (origins_to_be_deleted_count_ == 0)
|
| + OnClearedAppCache();
|
| + // Else continues in OnOriginDeleted.
|
| +}
|
| +
|
| +void ChromeAppCacheService::OnOriginDeleted(int rv) {
|
| + --origins_to_be_deleted_count_;
|
| + if (origins_to_be_deleted_count_ == 0)
|
| + OnClearedAppCache();
|
| +}
|
| +
|
| +void ChromeAppCacheService::OnClearedAppCache() {
|
| + appcaches_cleared_event_->Signal();
|
| + if (appcaches_cleared_callback_) {
|
| + appcaches_cleared_callback_->Run(0);
|
| }
|
| - clear_local_state_on_exit_ = clear_local_state;
|
| + waiting_for_clear_appcaches_ = false;
|
| + Release();
|
| }
|
|
|
| bool ChromeAppCacheService::CanLoadAppCache(const GURL& manifest_url) {
|
|
|