Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(14)

Side by Side Diff: chrome/browser/browsing_data/browsing_data_remover.cc

Issue 2613833004: Split BrowsingDataRemover into an abstract interface and implementation. (Closed)
Patch Set: Removed unnecessary instantiations. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/browsing_data/browsing_data_remover.h"
6
7 #include <map>
8 #include <set>
9 #include <string>
10 #include <utility>
11
12 #include "base/bind.h"
13 #include "base/bind_helpers.h"
14 #include "base/callback.h"
15 #include "base/logging.h"
16 #include "base/memory/ptr_util.h"
17 #include "base/metrics/histogram_macros.h"
18 #include "chrome/browser/browsing_data/browsing_data_filter_builder.h"
19 #include "chrome/browser/browsing_data/browsing_data_helper.h"
20 #include "chrome/browser/browsing_data/browsing_data_remover_delegate.h"
21 #include "chrome/browser/browsing_data/registrable_domain_filter_builder.h"
22 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/common/pref_names.h"
24 #include "components/browsing_data/content/storage_partition_http_cache_data_rem over.h"
25 #include "components/prefs/pref_service.h"
26 #include "components/web_cache/browser/web_cache_manager.h"
27 #include "content/public/browser/browser_context.h"
28 #include "content/public/browser/browser_thread.h"
29 #include "content/public/browser/content_browser_client.h"
30 #include "content/public/browser/download_manager.h"
31 #include "content/public/browser/notification_service.h"
32 #include "content/public/browser/plugin_data_remover.h"
33 #include "content/public/browser/ssl_host_state_delegate.h"
34 #include "content/public/browser/storage_partition.h"
35 #include "content/public/browser/user_metrics.h"
36 #include "extensions/features/features.h"
37 #include "media/media_features.h"
38 #include "net/base/net_errors.h"
39 #include "net/cookies/cookie_store.h"
40 #include "net/http/http_network_session.h"
41 #include "net/http/http_transaction_factory.h"
42 #include "net/http/transport_security_state.h"
43 #include "net/ssl/channel_id_service.h"
44 #include "net/ssl/channel_id_store.h"
45 #include "net/url_request/url_request_context.h"
46 #include "net/url_request/url_request_context_getter.h"
47 #include "ppapi/features/features.h"
48 #include "storage/browser/quota/special_storage_policy.h"
49 #include "url/origin.h"
50
51 #if BUILDFLAG(ENABLE_PLUGINS)
52 #include "chrome/browser/browsing_data/browsing_data_flash_lso_helper.h"
53 #endif
54
55 using base::UserMetricsAction;
56 using content::BrowserContext;
57 using content::BrowserThread;
58 using content::DOMStorageContext;
59
60 namespace {
61
62 template <typename T>
63 void IgnoreArgumentHelper(const base::Closure& callback, T unused_argument) {
64 callback.Run();
65 }
66
67 // Another convenience method to turn a callback without arguments into one that
68 // accepts (and ignores) a single argument.
69 template <typename T>
70 base::Callback<void(T)> IgnoreArgument(const base::Closure& callback) {
71 return base::Bind(&IgnoreArgumentHelper<T>, callback);
72 }
73
74 // Helper to create callback for BrowsingDataRemover::DoesOriginMatchMask.
75 bool DoesOriginMatchMaskAndUrls(
76 int origin_type_mask,
77 const base::Callback<bool(const GURL&)>& predicate,
78 const GURL& origin,
79 storage::SpecialStoragePolicy* special_storage_policy) {
80 return predicate.Run(origin) &&
81 BrowsingDataHelper::DoesOriginMatchMask(origin, origin_type_mask,
82 special_storage_policy);
83 }
84
85 void ClearHttpAuthCacheOnIOThread(
86 scoped_refptr<net::URLRequestContextGetter> context_getter,
87 base::Time delete_begin) {
88 DCHECK_CURRENTLY_ON(BrowserThread::IO);
89
90 net::HttpNetworkSession* http_session = context_getter->GetURLRequestContext()
91 ->http_transaction_factory()
92 ->GetSession();
93 DCHECK(http_session);
94 http_session->http_auth_cache()->ClearEntriesAddedWithin(base::Time::Now() -
95 delete_begin);
96 http_session->CloseAllConnections();
97 }
98
99 void OnClearedChannelIDsOnIOThread(net::URLRequestContextGetter* rq_context,
100 const base::Closure& callback) {
101 DCHECK_CURRENTLY_ON(BrowserThread::IO);
102
103 // Need to close open SSL connections which may be using the channel ids we
104 // are deleting.
105 // TODO(mattm): http://crbug.com/166069 Make the server bound cert
106 // service/store have observers that can notify relevant things directly.
107 rq_context->GetURLRequestContext()
108 ->ssl_config_service()
109 ->NotifySSLConfigChange();
110 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
111 }
112
113 void ClearChannelIDsOnIOThread(
114 const base::Callback<bool(const std::string&)>& domain_predicate,
115 base::Time delete_begin,
116 base::Time delete_end,
117 scoped_refptr<net::URLRequestContextGetter> rq_context,
118 const base::Closure& callback) {
119 DCHECK_CURRENTLY_ON(BrowserThread::IO);
120 net::ChannelIDService* channel_id_service =
121 rq_context->GetURLRequestContext()->channel_id_service();
122 channel_id_service->GetChannelIDStore()->DeleteForDomainsCreatedBetween(
123 domain_predicate, delete_begin, delete_end,
124 base::Bind(&OnClearedChannelIDsOnIOThread,
125 base::RetainedRef(std::move(rq_context)), callback));
126 }
127
128 } // namespace
129
130 BrowsingDataRemover::CompletionInhibitor*
131 BrowsingDataRemover::completion_inhibitor_ = nullptr;
132
133 BrowsingDataRemover::SubTask::SubTask(const base::Closure& forward_callback)
134 : is_pending_(false),
135 forward_callback_(forward_callback),
136 weak_ptr_factory_(this) {
137 DCHECK(!forward_callback_.is_null());
138 }
139
140 BrowsingDataRemover::SubTask::~SubTask() {}
141
142 void BrowsingDataRemover::SubTask::Start() {
143 DCHECK_CURRENTLY_ON(BrowserThread::UI);
144 DCHECK(!is_pending_);
145 is_pending_ = true;
146 }
147
148 base::Closure BrowsingDataRemover::SubTask::GetCompletionCallback() {
149 return base::Bind(&BrowsingDataRemover::SubTask::CompletionCallback,
150 weak_ptr_factory_.GetWeakPtr());
151 }
152
153 void BrowsingDataRemover::SubTask::CompletionCallback() {
154 DCHECK_CURRENTLY_ON(BrowserThread::UI);
155 DCHECK(is_pending_);
156 is_pending_ = false;
157 forward_callback_.Run();
158 }
159
160 BrowsingDataRemover::BrowsingDataRemover(
161 content::BrowserContext* browser_context)
162 : browser_context_(browser_context),
163 remove_mask_(-1),
164 origin_type_mask_(-1),
165 is_removing_(false),
166 #if BUILDFLAG(ENABLE_PLUGINS)
167 flash_lso_helper_(BrowsingDataFlashLSOHelper::Create(browser_context_)),
168 #endif
169 sub_task_forward_callback_(
170 base::Bind(&BrowsingDataRemover::NotifyIfDone,
171 base::Unretained(this))),
172 synchronous_clear_operations_(sub_task_forward_callback_),
173 clear_embedder_data_(sub_task_forward_callback_),
174 clear_cache_(sub_task_forward_callback_),
175 clear_channel_ids_(sub_task_forward_callback_),
176 clear_http_auth_cache_(sub_task_forward_callback_),
177 clear_storage_partition_data_(sub_task_forward_callback_),
178 weak_ptr_factory_(this) {
179 DCHECK(browser_context_);
180 }
181
182 BrowsingDataRemover::~BrowsingDataRemover() {
183 if (!task_queue_.empty()) {
184 VLOG(1) << "BrowsingDataRemover shuts down with " << task_queue_.size()
185 << " pending tasks";
186 }
187
188 // If we are still removing data, notify observers that their task has been
189 // (albeit unsucessfuly) processed, so they can unregister themselves.
190 // TODO(bauerb): If it becomes a problem that browsing data might not actually
191 // be fully cleared when an observer is notified, add a success flag.
192 while (!task_queue_.empty()) {
193 if (observer_list_.HasObserver(task_queue_.front().observer))
194 task_queue_.front().observer->OnBrowsingDataRemoverDone();
195 task_queue_.pop();
196 }
197 }
198
199 void BrowsingDataRemover::Shutdown() {
200 embedder_delegate_.reset();
201 }
202
203 void BrowsingDataRemover::SetRemoving(bool is_removing) {
204 DCHECK_NE(is_removing_, is_removing);
205 is_removing_ = is_removing;
206 }
207
208 void BrowsingDataRemover::Remove(const base::Time& delete_begin,
209 const base::Time& delete_end,
210 int remove_mask,
211 int origin_type_mask) {
212 RemoveInternal(delete_begin, delete_end, remove_mask, origin_type_mask,
213 std::unique_ptr<RegistrableDomainFilterBuilder>(), nullptr);
214 }
215
216 void BrowsingDataRemover::RemoveAndReply(
217 const base::Time& delete_begin,
218 const base::Time& delete_end,
219 int remove_mask,
220 int origin_type_mask,
221 Observer* observer) {
222 DCHECK(observer);
223 RemoveInternal(delete_begin, delete_end, remove_mask, origin_type_mask,
224 std::unique_ptr<RegistrableDomainFilterBuilder>(), observer);
225 }
226
227 void BrowsingDataRemover::RemoveWithFilter(
228 const base::Time& delete_begin,
229 const base::Time& delete_end,
230 int remove_mask,
231 int origin_type_mask,
232 std::unique_ptr<BrowsingDataFilterBuilder> filter_builder) {
233 DCHECK_EQ(0, remove_mask & ~FILTERABLE_DATATYPES);
234 DCHECK(filter_builder);
235 RemoveInternal(delete_begin, delete_end, remove_mask, origin_type_mask,
236 std::move(filter_builder), nullptr);
237 }
238
239 void BrowsingDataRemover::RemoveWithFilterAndReply(
240 const base::Time& delete_begin,
241 const base::Time& delete_end,
242 int remove_mask,
243 int origin_type_mask,
244 std::unique_ptr<BrowsingDataFilterBuilder> filter_builder,
245 Observer* observer) {
246 DCHECK_EQ(0, remove_mask & ~FILTERABLE_DATATYPES);
247 DCHECK(filter_builder);
248 DCHECK(observer);
249 RemoveInternal(delete_begin, delete_end, remove_mask, origin_type_mask,
250 std::move(filter_builder), observer);
251 }
252
253 void BrowsingDataRemover::RemoveInternal(
254 const base::Time& delete_begin,
255 const base::Time& delete_end,
256 int remove_mask,
257 int origin_type_mask,
258 std::unique_ptr<BrowsingDataFilterBuilder> filter_builder,
259 Observer* observer) {
260 DCHECK(!observer || observer_list_.HasObserver(observer))
261 << "Every observer must register itself (by calling AddObserver()) "
262 << "before observing a removal task.";
263
264 // Remove() and RemoveAndReply() pass a null pointer to indicate no filter.
265 // No filter is equivalent to one that |IsEmptyBlacklist()|.
266 if (!filter_builder) {
267 filter_builder = base::MakeUnique<RegistrableDomainFilterBuilder>(
268 RegistrableDomainFilterBuilder::BLACKLIST);
269 DCHECK(filter_builder->IsEmptyBlacklist());
270 }
271
272 task_queue_.emplace(
273 delete_begin,
274 delete_end,
275 remove_mask,
276 origin_type_mask,
277 std::move(filter_builder),
278 observer);
279
280 // If this is the only scheduled task, execute it immediately. Otherwise,
281 // it will be automatically executed when all tasks scheduled before it
282 // finish.
283 if (task_queue_.size() == 1) {
284 SetRemoving(true);
285 RunNextTask();
286 }
287 }
288
289 void BrowsingDataRemover::RunNextTask() {
290 DCHECK(!task_queue_.empty());
291 const RemovalTask& removal_task = task_queue_.front();
292
293 RemoveImpl(removal_task.delete_begin,
294 removal_task.delete_end,
295 removal_task.remove_mask,
296 *removal_task.filter_builder,
297 removal_task.origin_type_mask);
298 }
299
300 void BrowsingDataRemover::RemoveImpl(
301 const base::Time& delete_begin,
302 const base::Time& delete_end,
303 int remove_mask,
304 const BrowsingDataFilterBuilder& filter_builder,
305 int origin_type_mask) {
306 // =============== README before adding more storage backends ===============
307 //
308 // If you're adding a data storage backend that is included among
309 // RemoveDataMask::FILTERABLE_DATATYPES, you must do one of the following:
310 // 1. Support one of the filters generated by |filter_builder|.
311 // 2. Add a comment explaining why is it acceptable in your case to delete all
312 // data without filtering URLs / origins / domains.
313 // 3. Do not support partial deletion, i.e. only delete your data if
314 // |filter_builder.IsEmptyBlacklist()|. Add a comment explaining why this
315 // is acceptable.
316 synchronous_clear_operations_.Start();
317
318 // crbug.com/140910: Many places were calling this with base::Time() as
319 // delete_end, even though they should've used base::Time::Max().
320 DCHECK_NE(base::Time(), delete_end);
321
322 delete_begin_ = delete_begin;
323 delete_end_ = delete_end;
324 remove_mask_ = remove_mask;
325 origin_type_mask_ = origin_type_mask;
326
327 if (origin_type_mask_ & BrowsingDataHelper::UNPROTECTED_WEB) {
328 content::RecordAction(
329 UserMetricsAction("ClearBrowsingData_MaskContainsUnprotectedWeb"));
330 }
331 if (origin_type_mask_ & BrowsingDataHelper::PROTECTED_WEB) {
332 content::RecordAction(
333 UserMetricsAction("ClearBrowsingData_MaskContainsProtectedWeb"));
334 }
335 if (origin_type_mask_ & BrowsingDataHelper::EXTENSION) {
336 content::RecordAction(
337 UserMetricsAction("ClearBrowsingData_MaskContainsExtension"));
338 }
339 // If this fires, we added a new BrowsingDataHelper::OriginTypeMask without
340 // updating the user metrics above.
341 static_assert(
342 BrowsingDataHelper::ALL == (BrowsingDataHelper::UNPROTECTED_WEB |
343 BrowsingDataHelper::PROTECTED_WEB |
344 BrowsingDataHelper::EXTENSION),
345 "OriginTypeMask has been updated without updating user metrics");
346
347 // Record the combined deletion of cookies and cache.
348 CookieOrCacheDeletionChoice choice = NEITHER_COOKIES_NOR_CACHE;
349 if (remove_mask & REMOVE_COOKIES &&
350 origin_type_mask_ & BrowsingDataHelper::UNPROTECTED_WEB) {
351 choice = remove_mask & REMOVE_CACHE ? BOTH_COOKIES_AND_CACHE
352 : ONLY_COOKIES;
353 } else if (remove_mask & REMOVE_CACHE) {
354 choice = ONLY_CACHE;
355 }
356
357 UMA_HISTOGRAM_ENUMERATION(
358 "History.ClearBrowsingData.UserDeletedCookieOrCache",
359 choice, MAX_CHOICE_VALUE);
360
361 // Managed devices and supervised users can have restrictions on history
362 // deletion.
363 // TODO(crbug.com/668114): This should be provided via ContentBrowserClient
364 // once BrowsingDataRemover moves to content.
365 PrefService* prefs =
366 Profile::FromBrowserContext(browser_context_)->GetPrefs();
367 bool may_delete_history =
368 prefs->GetBoolean(prefs::kAllowDeletingBrowserHistory);
369
370 // All the UI entry points into the BrowsingDataRemover should be disabled,
371 // but this will fire if something was missed or added.
372 DCHECK(may_delete_history || (remove_mask & REMOVE_NOCHECKS) ||
373 (!(remove_mask & REMOVE_HISTORY) && !(remove_mask & REMOVE_DOWNLOADS)));
374
375 //////////////////////////////////////////////////////////////////////////////
376 // INITIALIZATION
377 base::Callback<bool(const GURL& url)> filter =
378 filter_builder.BuildGeneralFilter();
379
380 if ((remove_mask & REMOVE_HISTORY) && may_delete_history) {
381 // The SSL Host State that tracks SSL interstitial "proceed" decisions may
382 // include origins that the user has visited, so it must be cleared.
383 // TODO(msramek): We can reuse the plugin filter here, since both plugins
384 // and SSL host state are scoped to hosts and represent them as std::string.
385 // Rename the method to indicate its more general usage.
386 if (browser_context_->GetSSLHostStateDelegate()) {
387 browser_context_->GetSSLHostStateDelegate()->Clear(
388 filter_builder.IsEmptyBlacklist()
389 ? base::Callback<bool(const std::string&)>()
390 : filter_builder.BuildPluginFilter());
391 }
392 }
393
394 //////////////////////////////////////////////////////////////////////////////
395 // REMOVE_DOWNLOADS
396 if ((remove_mask & REMOVE_DOWNLOADS) && may_delete_history) {
397 content::RecordAction(UserMetricsAction("ClearBrowsingData_Downloads"));
398 content::DownloadManager* download_manager =
399 BrowserContext::GetDownloadManager(browser_context_);
400 download_manager->RemoveDownloadsByURLAndTime(filter,
401 delete_begin_, delete_end_);
402 }
403
404 //////////////////////////////////////////////////////////////////////////////
405 // REMOVE_CHANNEL_IDS
406 // Channel IDs are not separated for protected and unprotected web
407 // origins. We check the origin_type_mask_ to prevent unintended deletion.
408 if (remove_mask & REMOVE_CHANNEL_IDS &&
409 origin_type_mask_ & BrowsingDataHelper::UNPROTECTED_WEB) {
410 content::RecordAction(
411 UserMetricsAction("ClearBrowsingData_ChannelIDs"));
412 // Since we are running on the UI thread don't call GetURLRequestContext().
413 scoped_refptr<net::URLRequestContextGetter> rq_context =
414 content::BrowserContext::GetDefaultStoragePartition(browser_context_)->
415 GetURLRequestContext();
416 clear_channel_ids_.Start();
417 BrowserThread::PostTask(
418 BrowserThread::IO, FROM_HERE,
419 base::Bind(&ClearChannelIDsOnIOThread,
420 filter_builder.BuildChannelIDFilter(),
421 delete_begin_, delete_end_, std::move(rq_context),
422 clear_channel_ids_.GetCompletionCallback()));
423 }
424
425 //////////////////////////////////////////////////////////////////////////////
426 // STORAGE PARTITION DATA
427 uint32_t storage_partition_remove_mask = 0;
428
429 // We ignore the REMOVE_COOKIES request if UNPROTECTED_WEB is not set,
430 // so that callers who request REMOVE_SITE_DATA with PROTECTED_WEB
431 // don't accidentally remove the cookies that are associated with the
432 // UNPROTECTED_WEB origin. This is necessary because cookies are not separated
433 // between UNPROTECTED_WEB and PROTECTED_WEB.
434 if (remove_mask & REMOVE_COOKIES &&
435 origin_type_mask_ & BrowsingDataHelper::UNPROTECTED_WEB) {
436 storage_partition_remove_mask |=
437 content::StoragePartition::REMOVE_DATA_MASK_COOKIES;
438 }
439 if (remove_mask & REMOVE_LOCAL_STORAGE) {
440 storage_partition_remove_mask |=
441 content::StoragePartition::REMOVE_DATA_MASK_LOCAL_STORAGE;
442 }
443 if (remove_mask & REMOVE_INDEXEDDB) {
444 storage_partition_remove_mask |=
445 content::StoragePartition::REMOVE_DATA_MASK_INDEXEDDB;
446 }
447 if (remove_mask & REMOVE_WEBSQL) {
448 storage_partition_remove_mask |=
449 content::StoragePartition::REMOVE_DATA_MASK_WEBSQL;
450 }
451 if (remove_mask & REMOVE_APPCACHE) {
452 storage_partition_remove_mask |=
453 content::StoragePartition::REMOVE_DATA_MASK_APPCACHE;
454 }
455 if (remove_mask & REMOVE_SERVICE_WORKERS) {
456 storage_partition_remove_mask |=
457 content::StoragePartition::REMOVE_DATA_MASK_SERVICE_WORKERS;
458 }
459 if (remove_mask & REMOVE_CACHE_STORAGE) {
460 storage_partition_remove_mask |=
461 content::StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE;
462 }
463 if (remove_mask & REMOVE_FILE_SYSTEMS) {
464 storage_partition_remove_mask |=
465 content::StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS;
466 }
467
468 // Content Decryption Modules used by Encrypted Media store licenses in a
469 // private filesystem. These are different than content licenses used by
470 // Flash (which are deleted father down in this method).
471 if (remove_mask & REMOVE_MEDIA_LICENSES) {
472 storage_partition_remove_mask |=
473 content::StoragePartition::REMOVE_DATA_MASK_PLUGIN_PRIVATE_DATA;
474 }
475
476 if (storage_partition_remove_mask) {
477 clear_storage_partition_data_.Start();
478
479 content::StoragePartition* storage_partition;
480 if (storage_partition_for_testing_) {
481 storage_partition = storage_partition_for_testing_;
482 } else {
483 storage_partition =
484 BrowserContext::GetDefaultStoragePartition(browser_context_);
485 }
486
487 uint32_t quota_storage_remove_mask =
488 ~content::StoragePartition::QUOTA_MANAGED_STORAGE_MASK_PERSISTENT;
489
490 if (delete_begin_ == base::Time() ||
491 origin_type_mask_ &
492 (BrowsingDataHelper::PROTECTED_WEB | BrowsingDataHelper::EXTENSION)) {
493 // If we're deleting since the beginning of time, or we're removing
494 // protected origins, then remove persistent quota data.
495 quota_storage_remove_mask |=
496 content::StoragePartition::QUOTA_MANAGED_STORAGE_MASK_PERSISTENT;
497 }
498
499 // If cookies are supposed to be conditionally deleted from the storage
500 // partition, create a cookie matcher function.
501 content::StoragePartition::CookieMatcherFunction cookie_matcher;
502 if (!filter_builder.IsEmptyBlacklist() &&
503 (storage_partition_remove_mask &
504 content::StoragePartition::REMOVE_DATA_MASK_COOKIES)) {
505 cookie_matcher = filter_builder.BuildCookieFilter();
506 }
507
508 storage_partition->ClearData(
509 storage_partition_remove_mask, quota_storage_remove_mask,
510 base::Bind(&DoesOriginMatchMaskAndUrls, origin_type_mask_, filter),
511 cookie_matcher, delete_begin_, delete_end_,
512 clear_storage_partition_data_.GetCompletionCallback());
513 }
514
515 //////////////////////////////////////////////////////////////////////////////
516 // REMOVE_PLUGINS
517 #if BUILDFLAG(ENABLE_PLUGINS)
518 // Plugin is data not separated for protected and unprotected web origins. We
519 // check the origin_type_mask_ to prevent unintended deletion.
520 if (remove_mask & REMOVE_PLUGIN_DATA &&
521 origin_type_mask_ & BrowsingDataHelper::UNPROTECTED_WEB) {
522 content::RecordAction(UserMetricsAction("ClearBrowsingData_LSOData"));
523 clear_plugin_data_count_ = 1;
524
525 if (filter_builder.IsEmptyBlacklist()) {
526 DCHECK(!plugin_data_remover_);
527 plugin_data_remover_.reset(
528 content::PluginDataRemover::Create(browser_context_));
529 base::WaitableEvent* event =
530 plugin_data_remover_->StartRemoving(delete_begin_);
531
532 base::WaitableEventWatcher::EventCallback watcher_callback =
533 base::Bind(&BrowsingDataRemover::OnWaitableEventSignaled,
534 weak_ptr_factory_.GetWeakPtr());
535 watcher_.StartWatching(event, watcher_callback);
536 } else {
537 // TODO(msramek): Store filters from the currently executed task on the
538 // object to avoid having to copy them to callback methods.
539 flash_lso_helper_->StartFetching(base::Bind(
540 &BrowsingDataRemover::OnSitesWithFlashDataFetched,
541 weak_ptr_factory_.GetWeakPtr(),
542 filter_builder.BuildPluginFilter()));
543 }
544 }
545 #endif
546
547 //////////////////////////////////////////////////////////////////////////////
548 // CACHE
549 if (remove_mask & REMOVE_CACHE) {
550 // Tell the renderers to clear their cache.
551 web_cache::WebCacheManager::GetInstance()->ClearCache();
552
553 content::RecordAction(UserMetricsAction("ClearBrowsingData_Cache"));
554
555 clear_cache_.Start();
556 // StoragePartitionHttpCacheDataRemover deletes itself when it is done.
557 if (filter_builder.IsEmptyBlacklist()) {
558 browsing_data::StoragePartitionHttpCacheDataRemover::CreateForRange(
559 BrowserContext::GetDefaultStoragePartition(browser_context_),
560 delete_begin_, delete_end_)
561 ->Remove(clear_cache_.GetCompletionCallback());
562 } else {
563 browsing_data::StoragePartitionHttpCacheDataRemover::
564 CreateForURLsAndRange(
565 BrowserContext::GetDefaultStoragePartition(browser_context_),
566 filter, delete_begin_, delete_end_)
567 ->Remove(clear_cache_.GetCompletionCallback());
568 }
569
570 // Tell the shader disk cache to clear.
571 content::RecordAction(UserMetricsAction("ClearBrowsingData_ShaderCache"));
572 storage_partition_remove_mask |=
573 content::StoragePartition::REMOVE_DATA_MASK_SHADER_CACHE;
574 }
575
576 //////////////////////////////////////////////////////////////////////////////
577 // Auth cache.
578 if (remove_mask & REMOVE_COOKIES || remove_mask & REMOVE_PASSWORDS) {
579 scoped_refptr<net::URLRequestContextGetter> request_context =
580 BrowserContext::GetDefaultStoragePartition(browser_context_)
581 ->GetURLRequestContext();
582 clear_http_auth_cache_.Start();
583 BrowserThread::PostTaskAndReply(
584 BrowserThread::IO, FROM_HERE,
585 base::Bind(&ClearHttpAuthCacheOnIOThread, std::move(request_context),
586 delete_begin_),
587 clear_http_auth_cache_.GetCompletionCallback());
588 }
589
590 //////////////////////////////////////////////////////////////////////////////
591 // Embedder data.
592 if (embedder_delegate_) {
593 clear_embedder_data_.Start();
594 embedder_delegate_->RemoveEmbedderData(
595 delete_begin_,
596 delete_end_,
597 remove_mask,
598 filter_builder,
599 origin_type_mask,
600 clear_embedder_data_.GetCompletionCallback());
601 }
602
603 // Notify in case all actions taken were synchronous.
604 synchronous_clear_operations_.GetCompletionCallback().Run();
605 }
606
607 void BrowsingDataRemover::AddObserver(Observer* observer) {
608 observer_list_.AddObserver(observer);
609 }
610
611 void BrowsingDataRemover::RemoveObserver(Observer* observer) {
612 observer_list_.RemoveObserver(observer);
613 }
614
615 void BrowsingDataRemover::OverrideStoragePartitionForTesting(
616 content::StoragePartition* storage_partition) {
617 storage_partition_for_testing_ = storage_partition;
618 }
619
620 #if BUILDFLAG(ENABLE_PLUGINS)
621 void BrowsingDataRemover::OverrideFlashLSOHelperForTesting(
622 scoped_refptr<BrowsingDataFlashLSOHelper> flash_lso_helper) {
623 flash_lso_helper_ = flash_lso_helper;
624 }
625 #endif
626
627 const base::Time& BrowsingDataRemover::GetLastUsedBeginTime() {
628 return delete_begin_;
629 }
630
631 const base::Time& BrowsingDataRemover::GetLastUsedEndTime() {
632 return delete_end_;
633 }
634
635 int BrowsingDataRemover::GetLastUsedRemovalMask() {
636 return remove_mask_;
637 }
638
639 int BrowsingDataRemover::GetLastUsedOriginTypeMask() {
640 return origin_type_mask_;
641 }
642
643 BrowsingDataRemover::RemovalTask::RemovalTask(
644 const base::Time& delete_begin,
645 const base::Time& delete_end,
646 int remove_mask,
647 int origin_type_mask,
648 std::unique_ptr<BrowsingDataFilterBuilder> filter_builder,
649 Observer* observer)
650 : delete_begin(delete_begin),
651 delete_end(delete_end),
652 remove_mask(remove_mask),
653 origin_type_mask(origin_type_mask),
654 filter_builder(std::move(filter_builder)),
655 observer(observer) {}
656
657 BrowsingDataRemover::RemovalTask::~RemovalTask() {}
658
659 bool BrowsingDataRemover::AllDone() {
660 return !synchronous_clear_operations_.is_pending() &&
661 !clear_embedder_data_.is_pending() &&
662 !clear_cache_.is_pending() &&
663 !clear_channel_ids_.is_pending() &&
664 !clear_http_auth_cache_.is_pending() &&
665 !clear_storage_partition_data_.is_pending() &&
666 !clear_plugin_data_count_;
667 }
668
669 void BrowsingDataRemover::Notify() {
670 // Some tests call |RemoveImpl| directly, without using the task scheduler.
671 // TODO(msramek): Improve those tests so we don't have to do this. Tests
672 // relying on |RemoveImpl| do so because they need to pass in
673 // BrowsingDataFilterBuilder while still keeping ownership of it. Making
674 // BrowsingDataFilterBuilder copyable would solve this.
675 if (!is_removing_) {
676 DCHECK(task_queue_.empty());
677 return;
678 }
679
680 // Inform the observer of the current task unless it has unregistered
681 // itself in the meantime.
682 DCHECK(!task_queue_.empty());
683
684 if (task_queue_.front().observer != nullptr &&
685 observer_list_.HasObserver(task_queue_.front().observer)) {
686 task_queue_.front().observer->OnBrowsingDataRemoverDone();
687 }
688
689 task_queue_.pop();
690
691 if (task_queue_.empty()) {
692 // All removal tasks have finished. Inform the observers that we're idle.
693 SetRemoving(false);
694 return;
695 }
696
697 // Yield to the UI thread before executing the next removal task.
698 // TODO(msramek): Consider also adding a backoff if too many tasks
699 // are scheduled.
700 BrowserThread::PostTask(
701 BrowserThread::UI, FROM_HERE,
702 base::Bind(&BrowsingDataRemover::RunNextTask,
703 weak_ptr_factory_.GetWeakPtr()));
704 }
705
706 void BrowsingDataRemover::NotifyIfDone() {
707 // TODO(brettw) http://crbug.com/305259: This should also observe session
708 // clearing (what about other things such as passwords, etc.?) and wait for
709 // them to complete before continuing.
710
711 if (!AllDone())
712 return;
713
714 if (completion_inhibitor_) {
715 completion_inhibitor_->OnBrowsingDataRemoverWouldComplete(
716 this, base::Bind(&BrowsingDataRemover::Notify,
717 weak_ptr_factory_.GetWeakPtr()));
718 return;
719 }
720
721 Notify();
722 }
723
724 #if BUILDFLAG(ENABLE_PLUGINS)
725 void BrowsingDataRemover::OnWaitableEventSignaled(
726 base::WaitableEvent* waitable_event) {
727 DCHECK_CURRENTLY_ON(BrowserThread::UI);
728
729 DCHECK_EQ(1, clear_plugin_data_count_);
730 clear_plugin_data_count_ = 0;
731
732 plugin_data_remover_.reset();
733 watcher_.StopWatching();
734 NotifyIfDone();
735 }
736
737 void BrowsingDataRemover::OnSitesWithFlashDataFetched(
738 base::Callback<bool(const std::string&)> plugin_filter,
739 const std::vector<std::string>& sites) {
740 DCHECK_EQ(1, clear_plugin_data_count_);
741 clear_plugin_data_count_ = 0;
742
743 std::vector<std::string> sites_to_delete;
744 for (const std::string& site : sites) {
745 if (plugin_filter.Run(site))
746 sites_to_delete.push_back(site);
747 }
748
749 clear_plugin_data_count_ = sites_to_delete.size();
750
751 for (const std::string& site : sites_to_delete) {
752 flash_lso_helper_->DeleteFlashLSOsForSite(
753 site,
754 base::Bind(&BrowsingDataRemover::OnFlashDataDeleted,
755 weak_ptr_factory_.GetWeakPtr()));
756 }
757
758 NotifyIfDone();
759 }
760
761 void BrowsingDataRemover::OnFlashDataDeleted() {
762 clear_plugin_data_count_--;
763 NotifyIfDone();
764 }
765 #endif
OLDNEW
« no previous file with comments | « chrome/browser/browsing_data/browsing_data_remover.h ('k') | chrome/browser/browsing_data/browsing_data_remover_factory.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698