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

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

Issue 2175703002: Implement a task scheduler for BrowsingDataRemover (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@bdr-race-condition
Patch Set: Formatting. Created 4 years, 4 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/browsing_data/browsing_data_remover.h" 5 #include "chrome/browser/browsing_data/browsing_data_remover.h"
6 6
7 #include <map> 7 #include <map>
8 #include <set> 8 #include <set>
9 #include <string> 9 #include <string>
10 10
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 remove_mask_(-1), 292 remove_mask_(-1),
293 origin_type_mask_(-1), 293 origin_type_mask_(-1),
294 #if BUILDFLAG(ANDROID_JAVA_UI) 294 #if BUILDFLAG(ANDROID_JAVA_UI)
295 webapp_registry_(new WebappRegistry()), 295 webapp_registry_(new WebappRegistry()),
296 #endif 296 #endif
297 weak_ptr_factory_(this) { 297 weak_ptr_factory_(this) {
298 DCHECK(browser_context); 298 DCHECK(browser_context);
299 } 299 }
300 300
301 BrowsingDataRemover::~BrowsingDataRemover() { 301 BrowsingDataRemover::~BrowsingDataRemover() {
302 // If we are still removing data, notify observers so they can remove 302 if (!task_queue_.empty()) {
303 // themselves from the observer list. 303 VLOG(1) << "BrowsingDataRemover shuts down with " << task_queue_.size()
304 << " pending tasks";
305 }
306
307 // If we are still removing data, notify observers that their task has been
308 // (albeit unsucessfuly) processed, so they can unregister themselves.
304 // TODO(bauerb): If it becomes a problem that browsing data might not actually 309 // TODO(bauerb): If it becomes a problem that browsing data might not actually
305 // be fully cleared when an observer is notified, add a success flag. 310 // be fully cleared when an observer is notified, add a success flag.
306 if (is_removing_) 311 while (!task_queue_.empty()) {
307 Notify(); 312 if (observer_list_.HasObserver(task_queue_.front().observer))
313 task_queue_.front().observer->OnBrowsingDataRemoverDone();
314 task_queue_.pop();
315 }
308 } 316 }
309 317
310 void BrowsingDataRemover::Shutdown() { 318 void BrowsingDataRemover::Shutdown() {
311 history_task_tracker_.TryCancelAll(); 319 history_task_tracker_.TryCancelAll();
312 template_url_sub_.reset(); 320 template_url_sub_.reset();
313 } 321 }
314 322
315 void BrowsingDataRemover::SetRemoving(bool is_removing) { 323 void BrowsingDataRemover::SetRemoving(bool is_removing) {
316 DCHECK_NE(is_removing_, is_removing); 324 DCHECK_NE(is_removing_, is_removing);
317 is_removing_ = is_removing; 325 is_removing_ = is_removing;
318 FOR_EACH_OBSERVER(Observer, observer_list_, 326 FOR_EACH_OBSERVER(Observer, observer_list_,
319 OnBrowsingDataRemoving(is_removing)); 327 OnBrowsingDataRemoving(is_removing));
320 } 328 }
321 329
322 void BrowsingDataRemover::Remove(const TimeRange& time_range, 330 void BrowsingDataRemover::Remove(const TimeRange& time_range,
323 int remove_mask, 331 int remove_mask,
324 int origin_type_mask) { 332 int origin_type_mask) {
325 // Any instance of BrowsingDataFilterBuilder that |IsEmptyBlacklist()| 333 RemoveInternal(time_range, remove_mask, origin_type_mask,
326 // is OK to pass here. 334 std::unique_ptr<RegistrableDomainFilterBuilder>(), nullptr);
327 RegistrableDomainFilterBuilder builder( 335 }
328 RegistrableDomainFilterBuilder::BLACKLIST); 336
329 DCHECK(builder.IsEmptyBlacklist()); 337 void BrowsingDataRemover::RemoveAndReply(
330 RemoveImpl(time_range, remove_mask, builder, origin_type_mask); 338 const TimeRange& time_range,
339 int remove_mask,
340 int origin_type_mask,
341 Observer* observer) {
342 DCHECK(observer);
343 RemoveInternal(time_range, remove_mask, origin_type_mask,
344 std::unique_ptr<RegistrableDomainFilterBuilder>(), observer);
331 } 345 }
332 346
333 void BrowsingDataRemover::RemoveWithFilter( 347 void BrowsingDataRemover::RemoveWithFilter(
334 const TimeRange& time_range, 348 const TimeRange& time_range,
335 int remove_mask, 349 int remove_mask,
336 int origin_type_mask, 350 int origin_type_mask,
337 const BrowsingDataFilterBuilder& filter_builder) { 351 std::unique_ptr<BrowsingDataFilterBuilder> filter_builder) {
338 RemoveImpl(time_range, remove_mask, filter_builder, origin_type_mask); 352 DCHECK(filter_builder);
353 RemoveInternal(time_range, remove_mask, origin_type_mask,
354 std::move(filter_builder), nullptr);
355 }
356
357 void BrowsingDataRemover::RemoveWithFilterAndReply(
358 const TimeRange& time_range,
359 int remove_mask,
360 int origin_type_mask,
361 std::unique_ptr<BrowsingDataFilterBuilder> filter_builder,
362 Observer* observer) {
363 DCHECK(filter_builder);
364 DCHECK(observer);
365 RemoveInternal(time_range, remove_mask, origin_type_mask,
366 std::move(filter_builder), observer);
367 }
368
369 void BrowsingDataRemover::RemoveInternal(
370 const TimeRange& time_range,
371 int remove_mask,
372 int origin_type_mask,
373 std::unique_ptr<BrowsingDataFilterBuilder> filter_builder,
374 Observer* observer) {
375 DCHECK(!observer || observer_list_.HasObserver(observer))
376 << "Every observer must register itself (by calling AddObserver()) "
377 << "before observing a removal task.";
378
379 // Remove() and RemoveAndReply() pass a null pointer to indicate no filter.
380 // No filter is equivalent to one that |IsEmptyBlacklist()|.
381 if (!filter_builder) {
382 filter_builder = base::WrapUnique(new RegistrableDomainFilterBuilder(
383 RegistrableDomainFilterBuilder::BLACKLIST));
384 DCHECK(filter_builder->IsEmptyBlacklist());
385 }
386
387 task_queue_.emplace(
388 time_range,
389 remove_mask,
390 origin_type_mask,
391 std::move(filter_builder),
392 observer);
393
394 // If this is the only scheduled task, execute it immediately. Otherwise,
395 // it will be automatically executed when all tasks scheduled before it
396 // finish.
397 if (task_queue_.size() == 1) {
398 SetRemoving(true);
399 RunNextTask();
400 }
401 }
402
403 void BrowsingDataRemover::RunNextTask() {
404 DCHECK(!task_queue_.empty());
405 const RemovalTask& removal_task = task_queue_.front();
406
407 RemoveImpl(removal_task.time_range,
408 removal_task.remove_mask,
409 *removal_task.filter_builder,
410 removal_task.origin_type_mask);
339 } 411 }
340 412
341 void BrowsingDataRemover::RemoveImpl( 413 void BrowsingDataRemover::RemoveImpl(
342 const TimeRange& time_range, 414 const TimeRange& time_range,
343 int remove_mask, 415 int remove_mask,
344 const BrowsingDataFilterBuilder& filter_builder, 416 const BrowsingDataFilterBuilder& filter_builder,
345 int origin_type_mask) { 417 int origin_type_mask) {
346 DCHECK_CURRENTLY_ON(BrowserThread::UI); 418 DCHECK_CURRENTLY_ON(BrowserThread::UI);
347 waiting_for_synchronous_clear_operations_ = true; 419 waiting_for_synchronous_clear_operations_ = true;
348 420
349 // crbug.com/140910: Many places were calling this with base::Time() as 421 // crbug.com/140910: Many places were calling this with base::Time() as
350 // delete_end, even though they should've used base::Time::Max(). 422 // delete_end, even though they should've used base::Time::Max().
351 DCHECK_NE(base::Time(), time_range.end); 423 DCHECK_NE(base::Time(), time_range.end);
352 424
353 SetRemoving(true);
354 delete_begin_ = time_range.begin; 425 delete_begin_ = time_range.begin;
355 delete_end_ = time_range.end; 426 delete_end_ = time_range.end;
356 remove_mask_ = remove_mask; 427 remove_mask_ = remove_mask;
357 origin_type_mask_ = origin_type_mask; 428 origin_type_mask_ = origin_type_mask;
358 429
359 base::Callback<bool(const GURL& url)> filter = 430 base::Callback<bool(const GURL& url)> filter =
360 filter_builder.BuildGeneralFilter(); 431 filter_builder.BuildGeneralFilter();
361 base::Callback<bool(const ContentSettingsPattern& url)> same_pattern_filter = 432 base::Callback<bool(const ContentSettingsPattern& url)> same_pattern_filter =
362 filter_builder.BuildWebsiteSettingsPatternMatchesFilter(); 433 filter_builder.BuildWebsiteSettingsPatternMatchesFilter();
363 434
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after
1042 } 1113 }
1043 1114
1044 int BrowsingDataRemover::GetLastUsedRemovalMask() { 1115 int BrowsingDataRemover::GetLastUsedRemovalMask() {
1045 return remove_mask_; 1116 return remove_mask_;
1046 } 1117 }
1047 1118
1048 int BrowsingDataRemover::GetLastUsedOriginTypeMask() { 1119 int BrowsingDataRemover::GetLastUsedOriginTypeMask() {
1049 return origin_type_mask_; 1120 return origin_type_mask_;
1050 } 1121 }
1051 1122
1123 BrowsingDataRemover::RemovalTask::RemovalTask(
1124 const TimeRange& time_range,
1125 int remove_mask,
1126 int origin_type_mask,
1127 std::unique_ptr<BrowsingDataFilterBuilder> filter_builder,
1128 Observer* observer)
1129 : time_range(time_range),
1130 remove_mask(remove_mask),
1131 origin_type_mask(origin_type_mask),
1132 filter_builder(std::move(filter_builder)),
1133 observer(observer) {}
1134
1135 BrowsingDataRemover::RemovalTask::~RemovalTask() {}
1052 1136
1053 void BrowsingDataRemover::ClearSettingsForOneTypeWithPredicate( 1137 void BrowsingDataRemover::ClearSettingsForOneTypeWithPredicate(
1054 HostContentSettingsMap* content_settings_map, 1138 HostContentSettingsMap* content_settings_map,
1055 ContentSettingsType content_type, 1139 ContentSettingsType content_type,
1056 const base::Callback<bool(const ContentSettingsPattern& primary_pattern, 1140 const base::Callback<bool(const ContentSettingsPattern& primary_pattern,
1057 const ContentSettingsPattern& secondary_pattern)>& 1141 const ContentSettingsPattern& secondary_pattern)>&
1058 predicate) { 1142 predicate) {
1059 ContentSettingsForOneType settings; 1143 ContentSettingsForOneType settings;
1060 content_settings_map->GetSettingsForOneType(content_type, std::string(), 1144 content_settings_map->GetSettingsForOneType(content_type, std::string(),
1061 &settings); 1145 &settings);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1101 // else notifies observers and deletes this BrowsingDataRemover. 1185 // else notifies observers and deletes this BrowsingDataRemover.
1102 TemplateURLService* model = 1186 TemplateURLService* model =
1103 TemplateURLServiceFactory::GetForProfile(profile_); 1187 TemplateURLServiceFactory::GetForProfile(profile_);
1104 model->RemoveAutoGeneratedBetween(delete_begin_, delete_end_); 1188 model->RemoveAutoGeneratedBetween(delete_begin_, delete_end_);
1105 waiting_for_clear_keyword_data_ = false; 1189 waiting_for_clear_keyword_data_ = false;
1106 template_url_sub_.reset(); 1190 template_url_sub_.reset();
1107 NotifyIfDone(); 1191 NotifyIfDone();
1108 } 1192 }
1109 1193
1110 void BrowsingDataRemover::Notify() { 1194 void BrowsingDataRemover::Notify() {
1111 SetRemoving(false); 1195 // Some tests call |RemoveImpl| directly, without using the task scheduler.
1112 FOR_EACH_OBSERVER(Observer, observer_list_, OnBrowsingDataRemoverDone()); 1196 // TODO(msramek): Improve those tests so we don't have to do this. Tests
1197 // relying on |RemoveImpl| do so because they need to pass in
1198 // BrowsingDataFilterBuilder while still keeping ownership of it. Making
1199 // BrowsingDataFilterBuilder copyable would solve this.
1200 if (!is_removing_) {
1201 DCHECK(task_queue_.empty());
1202 return;
1203 }
1204
1205 // Inform the observer of the current task unless it has unregistered
1206 // itself in the meantime.
1207 DCHECK(!task_queue_.empty());
1208
1209 if (task_queue_.front().observer != nullptr &&
1210 observer_list_.HasObserver(task_queue_.front().observer)) {
1211 task_queue_.front().observer->OnBrowsingDataRemoverDone();
1212 }
1213
1214 task_queue_.pop();
1215
1216 if (task_queue_.empty()) {
1217 // All removal tasks have finished. Inform the observers that we're idle.
1218 SetRemoving(false);
1219 return;
1220 }
1221
1222 // Yield to the UI thread before executing the next removal task.
1223 // TODO(msramek): Consider also adding a backoff if too many tasks
1224 // are scheduled.
1225 BrowserThread::PostTask(
1226 BrowserThread::UI, FROM_HERE,
1227 base::Bind(&BrowsingDataRemover::RunNextTask,
1228 weak_ptr_factory_.GetWeakPtr()));
1113 } 1229 }
1114 1230
1115 void BrowsingDataRemover::NotifyIfDone() { 1231 void BrowsingDataRemover::NotifyIfDone() {
1116 // TODO(brettw) http://crbug.com/305259: This should also observe session 1232 // TODO(brettw) http://crbug.com/305259: This should also observe session
1117 // clearing (what about other things such as passwords, etc.?) and wait for 1233 // clearing (what about other things such as passwords, etc.?) and wait for
1118 // them to complete before continuing. 1234 // them to complete before continuing.
1119 1235
1120 if (!AllDone()) 1236 if (!AllDone())
1121 return; 1237 return;
1122 1238
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1291 waiting_for_clear_offline_page_data_ = false; 1407 waiting_for_clear_offline_page_data_ = false;
1292 NotifyIfDone(); 1408 NotifyIfDone();
1293 } 1409 }
1294 #endif 1410 #endif
1295 1411
1296 void BrowsingDataRemover::OnClearedDomainReliabilityMonitor() { 1412 void BrowsingDataRemover::OnClearedDomainReliabilityMonitor() {
1297 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1413 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1298 waiting_for_clear_domain_reliability_monitor_ = false; 1414 waiting_for_clear_domain_reliability_monitor_ = false;
1299 NotifyIfDone(); 1415 NotifyIfDone();
1300 } 1416 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698