Index: chrome/browser/browsing_data/browsing_data_remover_impl.cc |
diff --git a/chrome/browser/browsing_data/browsing_data_remover_impl.cc b/chrome/browser/browsing_data/browsing_data_remover_impl.cc |
deleted file mode 100644 |
index 606147bc97f8b689fb627919ed070f313de00549..0000000000000000000000000000000000000000 |
--- a/chrome/browser/browsing_data/browsing_data_remover_impl.cc |
+++ /dev/null |
@@ -1,681 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "chrome/browser/browsing_data/browsing_data_remover_impl.h" |
- |
-#include <map> |
-#include <set> |
-#include <string> |
-#include <utility> |
- |
-#include "base/bind.h" |
-#include "base/bind_helpers.h" |
-#include "base/callback.h" |
-#include "base/logging.h" |
-#include "base/memory/ptr_util.h" |
-#include "base/metrics/histogram_macros.h" |
-#include "base/metrics/user_metrics.h" |
-#include "chrome/browser/browsing_data/browsing_data_remover_delegate.h" |
-#include "chrome/browser/profiles/profile.h" |
-#include "chrome/common/pref_names.h" |
-#include "components/prefs/pref_service.h" |
-#include "content/public/browser/browser_context.h" |
-#include "content/public/browser/browser_thread.h" |
-#include "content/public/browser/browsing_data_filter_builder.h" |
-#include "content/public/browser/content_browser_client.h" |
-#include "content/public/browser/download_manager.h" |
-#include "content/public/browser/notification_service.h" |
-#include "content/public/browser/storage_partition.h" |
-#include "net/base/net_errors.h" |
-#include "net/cookies/cookie_store.h" |
-#include "net/http/http_network_session.h" |
-#include "net/http/http_transaction_factory.h" |
-#include "net/http/transport_security_state.h" |
-#include "net/ssl/channel_id_service.h" |
-#include "net/ssl/channel_id_store.h" |
-#include "net/url_request/url_request_context.h" |
-#include "net/url_request/url_request_context_getter.h" |
-#include "ppapi/features/features.h" |
-#include "storage/browser/quota/special_storage_policy.h" |
-#include "url/origin.h" |
- |
-using base::UserMetricsAction; |
-using content::BrowserContext; |
-using content::BrowserThread; |
-using content::BrowsingDataFilterBuilder; |
-using content::DOMStorageContext; |
- |
-namespace { |
- |
-// Returns whether |origin| matches |origin_type_mask| given the special |
-// storage |policy|; and if |predicate| is not null, then also whether |
-// it matches |predicate|. If |origin_type_mask| contains embedder-specific |
-// datatypes, |embedder_matcher| must not be null; the decision for those |
-// datatypes will be delegated to it. |
-bool DoesOriginMatchMaskAndURLs( |
- int origin_type_mask, |
- const base::Callback<bool(const GURL&)>& predicate, |
- const BrowsingDataRemoverDelegate::EmbedderOriginTypeMatcher& |
- embedder_matcher, |
- const GURL& origin, |
- storage::SpecialStoragePolicy* policy) { |
- if (!predicate.is_null() && !predicate.Run(origin)) |
- return false; |
- |
- const std::vector<std::string>& schemes = url::GetWebStorageSchemes(); |
- bool is_web_scheme = |
- (std::find(schemes.begin(), schemes.end(), origin.GetOrigin().scheme()) != |
- schemes.end()); |
- |
- // If a websafe origin is unprotected, it matches iff UNPROTECTED_WEB. |
- if ((!policy || !policy->IsStorageProtected(origin.GetOrigin())) && |
- is_web_scheme && |
- (origin_type_mask & BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB)) { |
- return true; |
- } |
- origin_type_mask &= ~BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB; |
- |
- // Hosted applications (protected and websafe origins) iff PROTECTED_WEB. |
- if (policy && policy->IsStorageProtected(origin.GetOrigin()) && |
- is_web_scheme && |
- (origin_type_mask & BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB)) { |
- return true; |
- } |
- origin_type_mask &= ~BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB; |
- |
- DCHECK(embedder_matcher || !origin_type_mask) |
- << "The mask contains embedder-defined origin types, but there is no " |
- << "embedder delegate matcher to process them."; |
- |
- if (!embedder_matcher.is_null()) |
- return embedder_matcher.Run(origin_type_mask, origin, policy); |
- |
- return false; |
-} |
- |
-void ClearHttpAuthCacheOnIOThread( |
- scoped_refptr<net::URLRequestContextGetter> context_getter, |
- base::Time delete_begin) { |
- DCHECK_CURRENTLY_ON(BrowserThread::IO); |
- |
- net::HttpNetworkSession* http_session = context_getter->GetURLRequestContext() |
- ->http_transaction_factory() |
- ->GetSession(); |
- DCHECK(http_session); |
- http_session->http_auth_cache()->ClearEntriesAddedWithin(base::Time::Now() - |
- delete_begin); |
- http_session->CloseAllConnections(); |
-} |
- |
-void OnClearedChannelIDsOnIOThread(net::URLRequestContextGetter* rq_context, |
- const base::Closure& callback) { |
- DCHECK_CURRENTLY_ON(BrowserThread::IO); |
- |
- // Need to close open SSL connections which may be using the channel ids we |
- // are deleting. |
- // TODO(mattm): http://crbug.com/166069 Make the server bound cert |
- // service/store have observers that can notify relevant things directly. |
- rq_context->GetURLRequestContext() |
- ->ssl_config_service() |
- ->NotifySSLConfigChange(); |
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback); |
-} |
- |
-void ClearChannelIDsOnIOThread( |
- const base::Callback<bool(const std::string&)>& domain_predicate, |
- base::Time delete_begin, |
- base::Time delete_end, |
- scoped_refptr<net::URLRequestContextGetter> rq_context, |
- const base::Closure& callback) { |
- DCHECK_CURRENTLY_ON(BrowserThread::IO); |
- net::ChannelIDService* channel_id_service = |
- rq_context->GetURLRequestContext()->channel_id_service(); |
- channel_id_service->GetChannelIDStore()->DeleteForDomainsCreatedBetween( |
- domain_predicate, delete_begin, delete_end, |
- base::Bind(&OnClearedChannelIDsOnIOThread, |
- base::RetainedRef(std::move(rq_context)), callback)); |
-} |
- |
-} // namespace |
- |
-BrowsingDataRemoverImpl::SubTask::SubTask(const base::Closure& forward_callback) |
- : is_pending_(false), |
- forward_callback_(forward_callback), |
- weak_ptr_factory_(this) { |
- DCHECK(!forward_callback_.is_null()); |
-} |
- |
-BrowsingDataRemoverImpl::SubTask::~SubTask() {} |
- |
-void BrowsingDataRemoverImpl::SubTask::Start() { |
- DCHECK_CURRENTLY_ON(BrowserThread::UI); |
- DCHECK(!is_pending_); |
- is_pending_ = true; |
-} |
- |
-base::Closure BrowsingDataRemoverImpl::SubTask::GetCompletionCallback() { |
- return base::Bind(&BrowsingDataRemoverImpl::SubTask::CompletionCallback, |
- weak_ptr_factory_.GetWeakPtr()); |
-} |
- |
-void BrowsingDataRemoverImpl::SubTask::CompletionCallback() { |
- DCHECK_CURRENTLY_ON(BrowserThread::UI); |
- DCHECK(is_pending_); |
- is_pending_ = false; |
- forward_callback_.Run(); |
-} |
- |
-BrowsingDataRemoverImpl::BrowsingDataRemoverImpl( |
- content::BrowserContext* browser_context) |
- : browser_context_(browser_context), |
- remove_mask_(-1), |
- origin_type_mask_(-1), |
- is_removing_(false), |
- sub_task_forward_callback_( |
- base::Bind(&BrowsingDataRemoverImpl::NotifyIfDone, |
- base::Unretained(this))), |
- synchronous_clear_operations_(sub_task_forward_callback_), |
- clear_embedder_data_(sub_task_forward_callback_), |
- clear_cache_(sub_task_forward_callback_), |
- clear_channel_ids_(sub_task_forward_callback_), |
- clear_http_auth_cache_(sub_task_forward_callback_), |
- clear_storage_partition_data_(sub_task_forward_callback_), |
- storage_partition_for_testing_(nullptr), |
- weak_ptr_factory_(this) { |
- DCHECK(browser_context_); |
-} |
- |
-BrowsingDataRemoverImpl::~BrowsingDataRemoverImpl() { |
- if (!task_queue_.empty()) { |
- VLOG(1) << "BrowsingDataRemoverImpl shuts down with " << task_queue_.size() |
- << " pending tasks"; |
- } |
- |
- // If we are still removing data, notify observers that their task has been |
- // (albeit unsucessfuly) processed, so they can unregister themselves. |
- // TODO(bauerb): If it becomes a problem that browsing data might not actually |
- // be fully cleared when an observer is notified, add a success flag. |
- while (!task_queue_.empty()) { |
- if (observer_list_.HasObserver(task_queue_.front().observer)) |
- task_queue_.front().observer->OnBrowsingDataRemoverDone(); |
- task_queue_.pop(); |
- } |
-} |
- |
-void BrowsingDataRemoverImpl::Shutdown() { |
- embedder_delegate_.reset(); |
-} |
- |
-void BrowsingDataRemoverImpl::SetRemoving(bool is_removing) { |
- DCHECK_NE(is_removing_, is_removing); |
- is_removing_ = is_removing; |
-} |
- |
-void BrowsingDataRemoverImpl::SetEmbedderDelegate( |
- std::unique_ptr<BrowsingDataRemoverDelegate> embedder_delegate) { |
- embedder_delegate_ = std::move(embedder_delegate); |
-} |
- |
-BrowsingDataRemoverDelegate* |
-BrowsingDataRemoverImpl::GetEmbedderDelegate() const { |
- return embedder_delegate_.get(); |
-} |
- |
-bool BrowsingDataRemoverImpl::DoesOriginMatchMask( |
- int origin_type_mask, |
- const GURL& origin, |
- storage::SpecialStoragePolicy* policy) const { |
- BrowsingDataRemoverDelegate::EmbedderOriginTypeMatcher embedder_matcher; |
- if (embedder_delegate_) |
- embedder_matcher = embedder_delegate_->GetOriginTypeMatcher(); |
- |
- return DoesOriginMatchMaskAndURLs(origin_type_mask, |
- base::Callback<bool(const GURL&)>(), |
- embedder_matcher, origin, policy); |
-} |
- |
-void BrowsingDataRemoverImpl::Remove(const base::Time& delete_begin, |
- const base::Time& delete_end, |
- int remove_mask, |
- int origin_type_mask) { |
- RemoveInternal(delete_begin, delete_end, remove_mask, origin_type_mask, |
- std::unique_ptr<BrowsingDataFilterBuilder>(), nullptr); |
-} |
- |
-void BrowsingDataRemoverImpl::RemoveAndReply( |
- const base::Time& delete_begin, |
- const base::Time& delete_end, |
- int remove_mask, |
- int origin_type_mask, |
- Observer* observer) { |
- DCHECK(observer); |
- RemoveInternal(delete_begin, delete_end, remove_mask, origin_type_mask, |
- std::unique_ptr<BrowsingDataFilterBuilder>(), observer); |
-} |
- |
-void BrowsingDataRemoverImpl::RemoveWithFilter( |
- const base::Time& delete_begin, |
- const base::Time& delete_end, |
- int remove_mask, |
- int origin_type_mask, |
- std::unique_ptr<BrowsingDataFilterBuilder> filter_builder) { |
- DCHECK(filter_builder); |
- RemoveInternal(delete_begin, delete_end, remove_mask, origin_type_mask, |
- std::move(filter_builder), nullptr); |
-} |
- |
-void BrowsingDataRemoverImpl::RemoveWithFilterAndReply( |
- const base::Time& delete_begin, |
- const base::Time& delete_end, |
- int remove_mask, |
- int origin_type_mask, |
- std::unique_ptr<BrowsingDataFilterBuilder> filter_builder, |
- Observer* observer) { |
- DCHECK(filter_builder); |
- DCHECK(observer); |
- RemoveInternal(delete_begin, delete_end, remove_mask, origin_type_mask, |
- std::move(filter_builder), observer); |
-} |
- |
-void BrowsingDataRemoverImpl::RemoveInternal( |
- const base::Time& delete_begin, |
- const base::Time& delete_end, |
- int remove_mask, |
- int origin_type_mask, |
- std::unique_ptr<BrowsingDataFilterBuilder> filter_builder, |
- Observer* observer) { |
- DCHECK(!observer || observer_list_.HasObserver(observer)) |
- << "Every observer must register itself (by calling AddObserver()) " |
- << "before observing a removal task."; |
- |
- // Remove() and RemoveAndReply() pass a null pointer to indicate no filter. |
- // No filter is equivalent to one that |IsEmptyBlacklist()|. |
- if (!filter_builder) { |
- filter_builder = BrowsingDataFilterBuilder::Create( |
- BrowsingDataFilterBuilder::BLACKLIST); |
- DCHECK(filter_builder->IsEmptyBlacklist()); |
- } |
- |
- task_queue_.emplace( |
- delete_begin, |
- delete_end, |
- remove_mask, |
- origin_type_mask, |
- std::move(filter_builder), |
- observer); |
- |
- // If this is the only scheduled task, execute it immediately. Otherwise, |
- // it will be automatically executed when all tasks scheduled before it |
- // finish. |
- if (task_queue_.size() == 1) { |
- SetRemoving(true); |
- RunNextTask(); |
- } |
-} |
- |
-void BrowsingDataRemoverImpl::RunNextTask() { |
- DCHECK(!task_queue_.empty()); |
- const RemovalTask& removal_task = task_queue_.front(); |
- |
- RemoveImpl(removal_task.delete_begin, |
- removal_task.delete_end, |
- removal_task.remove_mask, |
- *removal_task.filter_builder, |
- removal_task.origin_type_mask); |
-} |
- |
-void BrowsingDataRemoverImpl::RemoveImpl( |
- const base::Time& delete_begin, |
- const base::Time& delete_end, |
- int remove_mask, |
- const BrowsingDataFilterBuilder& filter_builder, |
- int origin_type_mask) { |
- // =============== README before adding more storage backends =============== |
- // |
- // If you're adding a data storage backend that is included among |
- // RemoveDataMask::FILTERABLE_DATATYPES, you must do one of the following: |
- // 1. Support one of the filters generated by |filter_builder|. |
- // 2. Add a comment explaining why is it acceptable in your case to delete all |
- // data without filtering URLs / origins / domains. |
- // 3. Do not support partial deletion, i.e. only delete your data if |
- // |filter_builder.IsEmptyBlacklist()|. Add a comment explaining why this |
- // is acceptable. |
- synchronous_clear_operations_.Start(); |
- |
- // crbug.com/140910: Many places were calling this with base::Time() as |
- // delete_end, even though they should've used base::Time::Max(). |
- DCHECK_NE(base::Time(), delete_end); |
- |
- delete_begin_ = delete_begin; |
- delete_end_ = delete_end; |
- remove_mask_ = remove_mask; |
- origin_type_mask_ = origin_type_mask; |
- |
- // Record the combined deletion of cookies and cache. |
- CookieOrCacheDeletionChoice choice = NEITHER_COOKIES_NOR_CACHE; |
- if (remove_mask & DATA_TYPE_COOKIES && |
- origin_type_mask_ & ORIGIN_TYPE_UNPROTECTED_WEB) { |
- choice = |
- remove_mask & DATA_TYPE_CACHE ? BOTH_COOKIES_AND_CACHE : ONLY_COOKIES; |
- } else if (remove_mask & DATA_TYPE_CACHE) { |
- choice = ONLY_CACHE; |
- } |
- |
- UMA_HISTOGRAM_ENUMERATION( |
- "History.ClearBrowsingData.UserDeletedCookieOrCache", |
- choice, MAX_CHOICE_VALUE); |
- |
- // Managed devices and supervised users can have restrictions on history |
- // deletion. |
- // TODO(crbug.com/668114): This should be provided via ContentBrowserClient |
- // once BrowsingDataRemoverImpl moves to content. |
- PrefService* prefs = |
- Profile::FromBrowserContext(browser_context_)->GetPrefs(); |
- bool may_delete_history = |
- prefs->GetBoolean(prefs::kAllowDeletingBrowserHistory); |
- |
- ////////////////////////////////////////////////////////////////////////////// |
- // INITIALIZATION |
- base::Callback<bool(const GURL& url)> filter = |
- filter_builder.BuildGeneralFilter(); |
- |
- ////////////////////////////////////////////////////////////////////////////// |
- // DATA_TYPE_DOWNLOADS |
- if ((remove_mask & DATA_TYPE_DOWNLOADS) && may_delete_history) { |
- base::RecordAction(UserMetricsAction("ClearBrowsingData_Downloads")); |
- content::DownloadManager* download_manager = |
- BrowserContext::GetDownloadManager(browser_context_); |
- download_manager->RemoveDownloadsByURLAndTime(filter, |
- delete_begin_, delete_end_); |
- } |
- |
- ////////////////////////////////////////////////////////////////////////////// |
- // DATA_TYPE_CHANNEL_IDS |
- // Channel IDs are not separated for protected and unprotected web |
- // origins. We check the origin_type_mask_ to prevent unintended deletion. |
- if (remove_mask & DATA_TYPE_CHANNEL_IDS && |
- origin_type_mask_ & ORIGIN_TYPE_UNPROTECTED_WEB) { |
- base::RecordAction(UserMetricsAction("ClearBrowsingData_ChannelIDs")); |
- // Since we are running on the UI thread don't call GetURLRequestContext(). |
- scoped_refptr<net::URLRequestContextGetter> rq_context = |
- content::BrowserContext::GetDefaultStoragePartition(browser_context_)-> |
- GetURLRequestContext(); |
- clear_channel_ids_.Start(); |
- BrowserThread::PostTask( |
- BrowserThread::IO, FROM_HERE, |
- base::BindOnce(&ClearChannelIDsOnIOThread, |
- filter_builder.BuildChannelIDFilter(), delete_begin_, |
- delete_end_, std::move(rq_context), |
- clear_channel_ids_.GetCompletionCallback())); |
- } |
- |
- ////////////////////////////////////////////////////////////////////////////// |
- // STORAGE PARTITION DATA |
- uint32_t storage_partition_remove_mask = 0; |
- |
- // We ignore the DATA_TYPE_COOKIES request if UNPROTECTED_WEB is not set, |
- // so that callers who request DATA_TYPE_SITE_DATA with another origin type |
- // don't accidentally remove the cookies that are associated with the |
- // UNPROTECTED_WEB origin. This is necessary because cookies are not separated |
- // between UNPROTECTED_WEB and other origin types. |
- if (remove_mask & DATA_TYPE_COOKIES && |
- origin_type_mask_ & ORIGIN_TYPE_UNPROTECTED_WEB) { |
- storage_partition_remove_mask |= |
- content::StoragePartition::REMOVE_DATA_MASK_COOKIES; |
- } |
- if (remove_mask & DATA_TYPE_LOCAL_STORAGE) { |
- storage_partition_remove_mask |= |
- content::StoragePartition::REMOVE_DATA_MASK_LOCAL_STORAGE; |
- } |
- if (remove_mask & DATA_TYPE_INDEXED_DB) { |
- storage_partition_remove_mask |= |
- content::StoragePartition::REMOVE_DATA_MASK_INDEXEDDB; |
- } |
- if (remove_mask & DATA_TYPE_WEB_SQL) { |
- storage_partition_remove_mask |= |
- content::StoragePartition::REMOVE_DATA_MASK_WEBSQL; |
- } |
- if (remove_mask & DATA_TYPE_APP_CACHE) { |
- storage_partition_remove_mask |= |
- content::StoragePartition::REMOVE_DATA_MASK_APPCACHE; |
- } |
- if (remove_mask & DATA_TYPE_SERVICE_WORKERS) { |
- storage_partition_remove_mask |= |
- content::StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS; |
- } |
- if (remove_mask & DATA_TYPE_CACHE_STORAGE) { |
- storage_partition_remove_mask |= |
- content::StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE; |
- } |
- if (remove_mask & DATA_TYPE_FILE_SYSTEMS) { |
- storage_partition_remove_mask |= |
- content::StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS; |
- } |
- |
- // Content Decryption Modules used by Encrypted Media store licenses in a |
- // private filesystem. These are different than content licenses used by |
- // Flash (which are deleted father down in this method). |
- if (remove_mask & DATA_TYPE_MEDIA_LICENSES) { |
- storage_partition_remove_mask |= |
- content::StoragePartition::REMOVE_DATA_MASK_PLUGIN_PRIVATE_DATA; |
- } |
- |
- content::StoragePartition* storage_partition; |
- if (storage_partition_for_testing_) { |
- storage_partition = storage_partition_for_testing_; |
- } else { |
- storage_partition = |
- BrowserContext::GetDefaultStoragePartition(browser_context_); |
- } |
- |
- if (storage_partition_remove_mask) { |
- clear_storage_partition_data_.Start(); |
- |
- uint32_t quota_storage_remove_mask = |
- ~content::StoragePartition::QUOTA_MANAGED_STORAGE_MASK_PERSISTENT; |
- |
- if (delete_begin_ == base::Time() || |
- ((origin_type_mask_ & ~ORIGIN_TYPE_UNPROTECTED_WEB) != 0)) { |
- // If we're deleting since the beginning of time, or we're removing |
- // protected origins, then remove persistent quota data. |
- quota_storage_remove_mask |= |
- content::StoragePartition::QUOTA_MANAGED_STORAGE_MASK_PERSISTENT; |
- } |
- |
- // If cookies are supposed to be conditionally deleted from the storage |
- // partition, create a cookie matcher function. |
- content::StoragePartition::CookieMatcherFunction cookie_matcher; |
- if (!filter_builder.IsEmptyBlacklist() && |
- (storage_partition_remove_mask & |
- content::StoragePartition::REMOVE_DATA_MASK_COOKIES)) { |
- cookie_matcher = filter_builder.BuildCookieFilter(); |
- } |
- |
- BrowsingDataRemoverDelegate::EmbedderOriginTypeMatcher embedder_matcher; |
- if (embedder_delegate_) |
- embedder_matcher = embedder_delegate_->GetOriginTypeMatcher(); |
- |
- storage_partition->ClearData( |
- storage_partition_remove_mask, quota_storage_remove_mask, |
- base::Bind(&DoesOriginMatchMaskAndURLs, origin_type_mask_, filter, |
- embedder_matcher), |
- cookie_matcher, delete_begin_, delete_end_, |
- clear_storage_partition_data_.GetCompletionCallback()); |
- } |
- |
- ////////////////////////////////////////////////////////////////////////////// |
- // CACHE |
- if (remove_mask & DATA_TYPE_CACHE) { |
- base::RecordAction(UserMetricsAction("ClearBrowsingData_Cache")); |
- |
- // TODO(msramek): Clear the cache of all renderers. |
- |
- clear_cache_.Start(); |
- storage_partition->ClearHttpAndMediaCaches( |
- delete_begin, delete_end, |
- filter_builder.IsEmptyBlacklist() ? base::Callback<bool(const GURL&)>() |
- : filter, |
- clear_cache_.GetCompletionCallback()); |
- |
- // Tell the shader disk cache to clear. |
- base::RecordAction(UserMetricsAction("ClearBrowsingData_ShaderCache")); |
- storage_partition_remove_mask |= |
- content::StoragePartition::REMOVE_DATA_MASK_SHADER_CACHE; |
- } |
- |
- ////////////////////////////////////////////////////////////////////////////// |
- // Auth cache. |
- if (remove_mask & DATA_TYPE_COOKIES) { |
- scoped_refptr<net::URLRequestContextGetter> request_context = |
- BrowserContext::GetDefaultStoragePartition(browser_context_) |
- ->GetURLRequestContext(); |
- clear_http_auth_cache_.Start(); |
- BrowserThread::PostTaskAndReply( |
- BrowserThread::IO, FROM_HERE, |
- base::BindOnce(&ClearHttpAuthCacheOnIOThread, |
- std::move(request_context), delete_begin_), |
- clear_http_auth_cache_.GetCompletionCallback()); |
- } |
- |
- ////////////////////////////////////////////////////////////////////////////// |
- // Embedder data. |
- if (embedder_delegate_) { |
- clear_embedder_data_.Start(); |
- embedder_delegate_->RemoveEmbedderData( |
- delete_begin_, |
- delete_end_, |
- remove_mask, |
- filter_builder, |
- origin_type_mask, |
- clear_embedder_data_.GetCompletionCallback()); |
- } |
- |
- // Notify in case all actions taken were synchronous. |
- synchronous_clear_operations_.GetCompletionCallback().Run(); |
-} |
- |
-void BrowsingDataRemoverImpl::AddObserver(Observer* observer) { |
- observer_list_.AddObserver(observer); |
-} |
- |
-void BrowsingDataRemoverImpl::RemoveObserver(Observer* observer) { |
- observer_list_.RemoveObserver(observer); |
-} |
- |
-void BrowsingDataRemoverImpl::SetWouldCompleteCallbackForTesting( |
- const base::Callback<void(const base::Closure& continue_to_completion)>& |
- callback) { |
- would_complete_callback_ = callback; |
-} |
- |
-void BrowsingDataRemoverImpl::OverrideStoragePartitionForTesting( |
- content::StoragePartition* storage_partition) { |
- storage_partition_for_testing_ = storage_partition; |
-} |
- |
-const base::Time& BrowsingDataRemoverImpl::GetLastUsedBeginTime() { |
- return delete_begin_; |
-} |
- |
-const base::Time& BrowsingDataRemoverImpl::GetLastUsedEndTime() { |
- return delete_end_; |
-} |
- |
-int BrowsingDataRemoverImpl::GetLastUsedRemovalMask() { |
- return remove_mask_; |
-} |
- |
-int BrowsingDataRemoverImpl::GetLastUsedOriginTypeMask() { |
- return origin_type_mask_; |
-} |
- |
-BrowsingDataRemoverImpl::RemovalTask::RemovalTask( |
- const base::Time& delete_begin, |
- const base::Time& delete_end, |
- int remove_mask, |
- int origin_type_mask, |
- std::unique_ptr<BrowsingDataFilterBuilder> filter_builder, |
- Observer* observer) |
- : delete_begin(delete_begin), |
- delete_end(delete_end), |
- remove_mask(remove_mask), |
- origin_type_mask(origin_type_mask), |
- filter_builder(std::move(filter_builder)), |
- observer(observer) {} |
- |
-BrowsingDataRemoverImpl::RemovalTask::~RemovalTask() {} |
- |
-bool BrowsingDataRemoverImpl::AllDone() { |
- return !synchronous_clear_operations_.is_pending() && |
- !clear_embedder_data_.is_pending() && |
- !clear_cache_.is_pending() && |
- !clear_channel_ids_.is_pending() && |
- !clear_http_auth_cache_.is_pending() && |
- !clear_storage_partition_data_.is_pending(); |
-} |
- |
-void BrowsingDataRemoverImpl::Notify() { |
- // Some tests call |RemoveImpl| directly, without using the task scheduler. |
- // TODO(msramek): Improve those tests so we don't have to do this. Tests |
- // relying on |RemoveImpl| do so because they need to pass in |
- // BrowsingDataFilterBuilder while still keeping ownership of it. Making |
- // BrowsingDataFilterBuilder copyable would solve this. |
- if (!is_removing_) { |
- DCHECK(task_queue_.empty()); |
- return; |
- } |
- |
- // Inform the observer of the current task unless it has unregistered |
- // itself in the meantime. |
- DCHECK(!task_queue_.empty()); |
- |
- if (task_queue_.front().observer != nullptr && |
- observer_list_.HasObserver(task_queue_.front().observer)) { |
- task_queue_.front().observer->OnBrowsingDataRemoverDone(); |
- } |
- |
- task_queue_.pop(); |
- |
- if (task_queue_.empty()) { |
- // All removal tasks have finished. Inform the observers that we're idle. |
- SetRemoving(false); |
- return; |
- } |
- |
- // Yield to the UI thread before executing the next removal task. |
- // TODO(msramek): Consider also adding a backoff if too many tasks |
- // are scheduled. |
- BrowserThread::PostTask( |
- BrowserThread::UI, FROM_HERE, |
- base::BindOnce(&BrowsingDataRemoverImpl::RunNextTask, GetWeakPtr())); |
-} |
- |
-void BrowsingDataRemoverImpl::NotifyIfDone() { |
- // TODO(brettw) http://crbug.com/305259: This should also observe session |
- // clearing (what about other things such as passwords, etc.?) and wait for |
- // them to complete before continuing. |
- |
- if (!AllDone()) |
- return; |
- |
- if (!would_complete_callback_.is_null()) { |
- would_complete_callback_.Run( |
- base::Bind(&BrowsingDataRemoverImpl::Notify, GetWeakPtr())); |
- return; |
- } |
- |
- Notify(); |
-} |
- |
-base::WeakPtr<BrowsingDataRemoverImpl> BrowsingDataRemoverImpl::GetWeakPtr() { |
- DCHECK_CURRENTLY_ON(BrowserThread::UI); |
- base::WeakPtr<BrowsingDataRemoverImpl> weak_ptr = |
- weak_ptr_factory_.GetWeakPtr(); |
- |
- // Immediately bind the weak pointer to the UI thread. This makes it easier |
- // to discover potential misuse on the IO thread. |
- weak_ptr.get(); |
- |
- return weak_ptr; |
-} |