• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/callback.h"
13 #include "base/logging.h"
14 #include "base/platform_file.h"
15 #include "base/prefs/pref_service.h"
16 #include "chrome/browser/autofill/personal_data_manager_factory.h"
17 #include "chrome/browser/browser_process.h"
18 #include "chrome/browser/browsing_data/browsing_data_helper.h"
19 #include "chrome/browser/chrome_notification_types.h"
20 #if defined(OS_CHROMEOS)
21 #include "chrome/browser/chromeos/login/user.h"
22 #include "chrome/browser/chromeos/login/user_manager.h"
23 #endif
24 #include "chrome/browser/download/download_prefs.h"
25 #include "chrome/browser/download/download_service_factory.h"
26 #include "chrome/browser/extensions/activity_log/activity_log.h"
27 #include "chrome/browser/extensions/extension_service.h"
28 #include "chrome/browser/extensions/extension_special_storage_policy.h"
29 #include "chrome/browser/history/history_service.h"
30 #include "chrome/browser/history/history_service_factory.h"
31 #include "chrome/browser/io_thread.h"
32 #include "chrome/browser/media/media_device_id_salt.h"
33 #include "chrome/browser/net/chrome_url_request_context.h"
34 #include "chrome/browser/net/predictor.h"
35 #include "chrome/browser/password_manager/password_store.h"
36 #include "chrome/browser/password_manager/password_store_factory.h"
37 #include "chrome/browser/predictors/logged_in_predictor_table.h"
38 #include "chrome/browser/predictors/predictor_database.h"
39 #include "chrome/browser/predictors/predictor_database_factory.h"
40 #include "chrome/browser/prerender/prerender_manager.h"
41 #include "chrome/browser/prerender/prerender_manager_factory.h"
42 #include "chrome/browser/profiles/profile.h"
43 #include "chrome/browser/renderer_host/web_cache_manager.h"
44 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
45 #include "chrome/browser/search_engines/template_url_service.h"
46 #include "chrome/browser/search_engines/template_url_service_factory.h"
47 #include "chrome/browser/sessions/session_service.h"
48 #include "chrome/browser/sessions/session_service_factory.h"
49 #include "chrome/browser/sessions/tab_restore_service.h"
50 #include "chrome/browser/sessions/tab_restore_service_factory.h"
51 #include "chrome/browser/webdata/web_data_service_factory.h"
52 #include "chrome/common/pref_names.h"
53 #include "chrome/common/url_constants.h"
54 #if defined(OS_CHROMEOS)
55 #include "chromeos/attestation/attestation_constants.h"
56 #include "chromeos/dbus/cryptohome_client.h"
57 #include "chromeos/dbus/dbus_thread_manager.h"
58 #endif
59 #include "components/autofill/core/browser/personal_data_manager.h"
60 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
61 #include "components/nacl/browser/nacl_browser.h"
62 #include "components/nacl/browser/pnacl_host.h"
63 #include "content/public/browser/browser_thread.h"
64 #include "content/public/browser/dom_storage_context.h"
65 #include "content/public/browser/download_manager.h"
66 #include "content/public/browser/local_storage_usage_info.h"
67 #include "content/public/browser/notification_service.h"
68 #include "content/public/browser/plugin_data_remover.h"
69 #include "content/public/browser/session_storage_usage_info.h"
70 #include "content/public/browser/storage_partition.h"
71 #include "content/public/browser/user_metrics.h"
72 #include "net/base/net_errors.h"
73 #include "net/cookies/cookie_store.h"
74 #include "net/disk_cache/disk_cache.h"
75 #include "net/http/http_cache.h"
76 #include "net/http/transport_security_state.h"
77 #include "net/ssl/server_bound_cert_service.h"
78 #include "net/ssl/server_bound_cert_store.h"
79 #include "net/url_request/url_request_context.h"
80 #include "net/url_request/url_request_context_getter.h"
81 #include "webkit/browser/quota/quota_manager.h"
82 #include "webkit/browser/quota/special_storage_policy.h"
83 #include "webkit/common/quota/quota_types.h"
84 
85 using content::BrowserContext;
86 using content::BrowserThread;
87 using content::DOMStorageContext;
88 using content::UserMetricsAction;
89 
90 bool BrowsingDataRemover::is_removing_ = false;
91 
92 // Helper to create callback for BrowsingDataRemover::DoesOriginMatchMask.
93 // Static.
DoesOriginMatchMask(int origin_set_mask,const GURL & origin,quota::SpecialStoragePolicy * special_storage_policy)94 bool DoesOriginMatchMask(int origin_set_mask,
95                          const GURL& origin,
96                          quota::SpecialStoragePolicy* special_storage_policy) {
97   return BrowsingDataHelper::DoesOriginMatchMask(
98       origin, origin_set_mask,
99       static_cast<ExtensionSpecialStoragePolicy*>(special_storage_policy));
100 }
101 
NotificationDetails()102 BrowsingDataRemover::NotificationDetails::NotificationDetails()
103     : removal_begin(base::Time()),
104       removal_mask(-1),
105       origin_set_mask(-1) {
106 }
107 
NotificationDetails(const BrowsingDataRemover::NotificationDetails & details)108 BrowsingDataRemover::NotificationDetails::NotificationDetails(
109     const BrowsingDataRemover::NotificationDetails& details)
110     : removal_begin(details.removal_begin),
111       removal_mask(details.removal_mask),
112       origin_set_mask(details.origin_set_mask) {
113 }
114 
NotificationDetails(base::Time removal_begin,int removal_mask,int origin_set_mask)115 BrowsingDataRemover::NotificationDetails::NotificationDetails(
116     base::Time removal_begin,
117     int removal_mask,
118     int origin_set_mask)
119     : removal_begin(removal_begin),
120       removal_mask(removal_mask),
121       origin_set_mask(origin_set_mask) {
122 }
123 
~NotificationDetails()124 BrowsingDataRemover::NotificationDetails::~NotificationDetails() {}
125 
126 // Static.
CreateForUnboundedRange(Profile * profile)127 BrowsingDataRemover* BrowsingDataRemover::CreateForUnboundedRange(
128     Profile* profile) {
129   return new BrowsingDataRemover(profile, base::Time(), base::Time::Max());
130 }
131 
132 // Static.
CreateForRange(Profile * profile,base::Time start,base::Time end)133 BrowsingDataRemover* BrowsingDataRemover::CreateForRange(Profile* profile,
134     base::Time start, base::Time end) {
135   return new BrowsingDataRemover(profile, start, end);
136 }
137 
138 // Static.
CreateForPeriod(Profile * profile,TimePeriod period)139 BrowsingDataRemover* BrowsingDataRemover::CreateForPeriod(Profile* profile,
140     TimePeriod period) {
141   switch (period) {
142     case LAST_HOUR:
143       content::RecordAction(
144           UserMetricsAction("ClearBrowsingData_LastHour"));
145       break;
146     case LAST_DAY:
147       content::RecordAction(
148           UserMetricsAction("ClearBrowsingData_LastDay"));
149       break;
150     case LAST_WEEK:
151       content::RecordAction(
152           UserMetricsAction("ClearBrowsingData_LastWeek"));
153       break;
154     case FOUR_WEEKS:
155       content::RecordAction(
156           UserMetricsAction("ClearBrowsingData_LastMonth"));
157       break;
158     case EVERYTHING:
159       content::RecordAction(
160           UserMetricsAction("ClearBrowsingData_Everything"));
161       break;
162   }
163   return new BrowsingDataRemover(profile,
164       BrowsingDataRemover::CalculateBeginDeleteTime(period),
165       base::Time::Max());
166 }
167 
BrowsingDataRemover(Profile * profile,base::Time delete_begin,base::Time delete_end)168 BrowsingDataRemover::BrowsingDataRemover(Profile* profile,
169                                          base::Time delete_begin,
170                                          base::Time delete_end)
171     : profile_(profile),
172       special_storage_policy_(profile->GetExtensionSpecialStoragePolicy()),
173       delete_begin_(delete_begin),
174       delete_end_(delete_end),
175       next_cache_state_(STATE_NONE),
176       cache_(NULL),
177       main_context_getter_(profile->GetRequestContext()),
178       media_context_getter_(profile->GetMediaRequestContext()),
179       deauthorize_content_licenses_request_id_(0),
180       waiting_for_clear_autofill_origin_urls_(false),
181       waiting_for_clear_cache_(false),
182       waiting_for_clear_content_licenses_(false),
183       waiting_for_clear_cookies_count_(0),
184       waiting_for_clear_form_(false),
185       waiting_for_clear_history_(false),
186       waiting_for_clear_hostname_resolution_cache_(false),
187       waiting_for_clear_keyword_data_(false),
188       waiting_for_clear_logged_in_predictor_(false),
189       waiting_for_clear_nacl_cache_(false),
190       waiting_for_clear_network_predictor_(false),
191       waiting_for_clear_networking_history_(false),
192       waiting_for_clear_platform_keys_(false),
193       waiting_for_clear_plugin_data_(false),
194       waiting_for_clear_pnacl_cache_(false),
195       waiting_for_clear_server_bound_certs_(false),
196       waiting_for_clear_storage_partition_data_(false),
197       remove_mask_(0),
198       remove_origin_(GURL()),
199       origin_set_mask_(0),
200       storage_partition_for_testing_(NULL) {
201   DCHECK(profile);
202   // crbug.com/140910: Many places were calling this with base::Time() as
203   // delete_end, even though they should've used base::Time::Max(). Work around
204   // it here. New code should use base::Time::Max().
205   DCHECK(delete_end_ != base::Time());
206   if (delete_end_ == base::Time())
207     delete_end_ = base::Time::Max();
208 }
209 
~BrowsingDataRemover()210 BrowsingDataRemover::~BrowsingDataRemover() {
211   DCHECK(AllDone());
212 }
213 
214 // Static.
set_removing(bool is_removing)215 void BrowsingDataRemover::set_removing(bool is_removing) {
216   DCHECK(is_removing_ != is_removing);
217   is_removing_ = is_removing;
218 }
219 
Remove(int remove_mask,int origin_set_mask)220 void BrowsingDataRemover::Remove(int remove_mask, int origin_set_mask) {
221   RemoveImpl(remove_mask, GURL(), origin_set_mask);
222 }
223 
RemoveImpl(int remove_mask,const GURL & origin,int origin_set_mask)224 void BrowsingDataRemover::RemoveImpl(int remove_mask,
225                                      const GURL& origin,
226                                      int origin_set_mask) {
227   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
228   set_removing(true);
229   remove_mask_ = remove_mask;
230   remove_origin_ = origin;
231   origin_set_mask_ = origin_set_mask;
232 
233   PrefService* prefs = profile_->GetPrefs();
234   bool may_delete_history = prefs->GetBoolean(
235       prefs::kAllowDeletingBrowserHistory);
236 
237   // All the UI entry points into the BrowsingDataRemover should be disabled,
238   // but this will fire if something was missed or added.
239   DCHECK(may_delete_history ||
240       (!(remove_mask & REMOVE_HISTORY) && !(remove_mask & REMOVE_DOWNLOADS)));
241 
242   if (origin_set_mask_ & BrowsingDataHelper::UNPROTECTED_WEB) {
243     content::RecordAction(
244         UserMetricsAction("ClearBrowsingData_MaskContainsUnprotectedWeb"));
245   }
246   if (origin_set_mask_ & BrowsingDataHelper::PROTECTED_WEB) {
247     content::RecordAction(
248         UserMetricsAction("ClearBrowsingData_MaskContainsProtectedWeb"));
249   }
250   if (origin_set_mask_ & BrowsingDataHelper::EXTENSION) {
251     content::RecordAction(
252         UserMetricsAction("ClearBrowsingData_MaskContainsExtension"));
253   }
254   // If this fires, we added a new BrowsingDataHelper::OriginSetMask without
255   // updating the user metrics above.
256   COMPILE_ASSERT(
257       BrowsingDataHelper::ALL == (BrowsingDataHelper::UNPROTECTED_WEB |
258                                   BrowsingDataHelper::PROTECTED_WEB |
259                                   BrowsingDataHelper::EXTENSION),
260       forgotten_to_add_origin_mask_type);
261 
262   if ((remove_mask & REMOVE_HISTORY) && may_delete_history) {
263     HistoryService* history_service = HistoryServiceFactory::GetForProfile(
264         profile_, Profile::EXPLICIT_ACCESS);
265     if (history_service) {
266       std::set<GURL> restrict_urls;
267       if (!remove_origin_.is_empty())
268         restrict_urls.insert(remove_origin_);
269       content::RecordAction(UserMetricsAction("ClearBrowsingData_History"));
270       waiting_for_clear_history_ = true;
271 
272       history_service->ExpireLocalAndRemoteHistoryBetween(
273           restrict_urls, delete_begin_, delete_end_,
274           base::Bind(&BrowsingDataRemover::OnHistoryDeletionDone,
275                      base::Unretained(this)),
276           &history_task_tracker_);
277 
278 #if defined(ENABLE_EXTENSIONS)
279       // The extension activity contains details of which websites extensions
280       // were active on. It therefore indirectly stores details of websites a
281       // user has visited so best clean from here as well.
282       extensions::ActivityLog::GetInstance(profile_)->RemoveURLs(restrict_urls);
283 #endif
284     }
285 
286     // Need to clear the host cache and accumulated speculative data, as it also
287     // reveals some history: we have no mechanism to track when these items were
288     // created, so we'll clear them all. Better safe than sorry.
289     if (g_browser_process->io_thread()) {
290       waiting_for_clear_hostname_resolution_cache_ = true;
291       BrowserThread::PostTask(
292           BrowserThread::IO, FROM_HERE,
293           base::Bind(
294               &BrowsingDataRemover::ClearHostnameResolutionCacheOnIOThread,
295               base::Unretained(this),
296               g_browser_process->io_thread()));
297     }
298     if (profile_->GetNetworkPredictor()) {
299       waiting_for_clear_network_predictor_ = true;
300       BrowserThread::PostTask(
301           BrowserThread::IO, FROM_HERE,
302           base::Bind(&BrowsingDataRemover::ClearNetworkPredictorOnIOThread,
303                      base::Unretained(this)));
304     }
305 
306     // As part of history deletion we also delete the auto-generated keywords.
307     TemplateURLService* keywords_model =
308         TemplateURLServiceFactory::GetForProfile(profile_);
309     if (keywords_model && !keywords_model->loaded()) {
310       template_url_sub_ = keywords_model->RegisterOnLoadedCallback(
311           base::Bind(&BrowsingDataRemover::OnKeywordsLoaded,
312                      base::Unretained(this)));
313       keywords_model->Load();
314       waiting_for_clear_keyword_data_ = true;
315     } else if (keywords_model) {
316       keywords_model->RemoveAutoGeneratedForOriginBetween(remove_origin_,
317           delete_begin_, delete_end_);
318     }
319 
320     // The PrerenderManager keeps history of prerendered pages, so clear that.
321     // It also may have a prerendered page. If so, the page could be
322     // considered to have a small amount of historical information, so delete
323     // it, too.
324     prerender::PrerenderManager* prerender_manager =
325         prerender::PrerenderManagerFactory::GetForProfile(profile_);
326     if (prerender_manager) {
327       prerender_manager->ClearData(
328           prerender::PrerenderManager::CLEAR_PRERENDER_CONTENTS |
329           prerender::PrerenderManager::CLEAR_PRERENDER_HISTORY);
330     }
331 
332     // If the caller is removing history for all hosts, then clear ancillary
333     // historical information.
334     if (remove_origin_.is_empty()) {
335       // We also delete the list of recently closed tabs. Since these expire,
336       // they can't be more than a day old, so we can simply clear them all.
337       TabRestoreService* tab_service =
338           TabRestoreServiceFactory::GetForProfile(profile_);
339       if (tab_service) {
340         tab_service->ClearEntries();
341         tab_service->DeleteLastSession();
342       }
343 
344 #if defined(ENABLE_SESSION_SERVICE)
345       // We also delete the last session when we delete the history.
346       SessionService* session_service =
347           SessionServiceFactory::GetForProfile(profile_);
348       if (session_service)
349         session_service->DeleteLastSession();
350 #endif
351     }
352 
353     // The saved Autofill profiles and credit cards can include the origin from
354     // which these profiles and credit cards were learned.  These are a form of
355     // history, so clear them as well.
356     scoped_refptr<autofill::AutofillWebDataService> web_data_service =
357         WebDataServiceFactory::GetAutofillWebDataForProfile(
358             profile_, Profile::EXPLICIT_ACCESS);
359     if (web_data_service.get()) {
360       waiting_for_clear_autofill_origin_urls_ = true;
361       web_data_service->RemoveOriginURLsModifiedBetween(
362           delete_begin_, delete_end_);
363       // The above calls are done on the UI thread but do their work on the DB
364       // thread. So wait for it.
365       BrowserThread::PostTaskAndReply(
366           BrowserThread::DB, FROM_HERE,
367           base::Bind(&base::DoNothing),
368           base::Bind(&BrowsingDataRemover::OnClearedAutofillOriginURLs,
369                      base::Unretained(this)));
370 
371       autofill::PersonalDataManager* data_manager =
372           autofill::PersonalDataManagerFactory::GetForProfile(profile_);
373       if (data_manager)
374         data_manager->Refresh();
375     }
376 
377   }
378 
379   if ((remove_mask & REMOVE_DOWNLOADS) && may_delete_history) {
380     content::RecordAction(UserMetricsAction("ClearBrowsingData_Downloads"));
381     content::DownloadManager* download_manager =
382         BrowserContext::GetDownloadManager(profile_);
383     download_manager->RemoveDownloadsBetween(delete_begin_, delete_end_);
384     DownloadPrefs* download_prefs = DownloadPrefs::FromDownloadManager(
385         download_manager);
386     download_prefs->SetSaveFilePath(download_prefs->DownloadPath());
387   }
388 
389   uint32 storage_partition_remove_mask = 0;
390 
391   // We ignore the REMOVE_COOKIES request if UNPROTECTED_WEB is not set,
392   // so that callers who request REMOVE_SITE_DATA with PROTECTED_WEB
393   // don't accidentally remove the cookies that are associated with the
394   // UNPROTECTED_WEB origin. This is necessary because cookies are not separated
395   // between UNPROTECTED_WEB and PROTECTED_WEB.
396   if (remove_mask & REMOVE_COOKIES &&
397       origin_set_mask_ & BrowsingDataHelper::UNPROTECTED_WEB) {
398     content::RecordAction(UserMetricsAction("ClearBrowsingData_Cookies"));
399 
400     storage_partition_remove_mask |=
401         content::StoragePartition::REMOVE_DATA_MASK_COOKIES;
402 
403     // Also delete the LoggedIn Predictor, which tries to keep track of which
404     // sites a user is logged into.
405     ClearLoggedInPredictor();
406 
407 #if defined(FULL_SAFE_BROWSING) || defined(MOBILE_SAFE_BROWSING)
408     // Clear the safebrowsing cookies only if time period is for "all time".  It
409     // doesn't make sense to apply the time period of deleting in the last X
410     // hours/days to the safebrowsing cookies since they aren't the result of
411     // any user action.
412     if (delete_begin_ == base::Time()) {
413       SafeBrowsingService* sb_service =
414           g_browser_process->safe_browsing_service();
415       if (sb_service) {
416         net::URLRequestContextGetter* sb_context =
417             sb_service->url_request_context();
418         ++waiting_for_clear_cookies_count_;
419         BrowserThread::PostTask(
420             BrowserThread::IO, FROM_HERE,
421             base::Bind(&BrowsingDataRemover::ClearCookiesOnIOThread,
422                        base::Unretained(this), base::Unretained(sb_context)));
423       }
424     }
425 #endif
426     MediaDeviceIDSalt::Reset(profile_->GetPrefs());
427   }
428 
429   // Server bound certs are not separated for protected and unprotected web
430   // origins. We check the origin_set_mask_ to prevent unintended deletion.
431   if (remove_mask & REMOVE_SERVER_BOUND_CERTS &&
432       origin_set_mask_ & BrowsingDataHelper::UNPROTECTED_WEB) {
433     content::RecordAction(
434         UserMetricsAction("ClearBrowsingData_ServerBoundCerts"));
435     // Since we are running on the UI thread don't call GetURLRequestContext().
436     net::URLRequestContextGetter* rq_context = profile_->GetRequestContext();
437     if (rq_context) {
438       waiting_for_clear_server_bound_certs_ = true;
439       BrowserThread::PostTask(
440           BrowserThread::IO, FROM_HERE,
441           base::Bind(&BrowsingDataRemover::ClearServerBoundCertsOnIOThread,
442                      base::Unretained(this), base::Unretained(rq_context)));
443     }
444   }
445 
446   if (remove_mask & REMOVE_LOCAL_STORAGE) {
447     storage_partition_remove_mask |=
448         content::StoragePartition::REMOVE_DATA_MASK_LOCAL_STORAGE;
449   }
450 
451   if (remove_mask & REMOVE_INDEXEDDB) {
452     storage_partition_remove_mask |=
453         content::StoragePartition::REMOVE_DATA_MASK_INDEXEDDB;
454   }
455   if (remove_mask & REMOVE_WEBSQL) {
456     storage_partition_remove_mask |=
457         content::StoragePartition::REMOVE_DATA_MASK_WEBSQL;
458   }
459   if (remove_mask & REMOVE_APPCACHE) {
460     storage_partition_remove_mask |=
461         content::StoragePartition::REMOVE_DATA_MASK_APPCACHE;
462   }
463   if (remove_mask & REMOVE_FILE_SYSTEMS) {
464     storage_partition_remove_mask |=
465         content::StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS;
466   }
467 
468 #if defined(ENABLE_PLUGINS)
469   // Plugin is data not separated for protected and unprotected web origins. We
470   // check the origin_set_mask_ to prevent unintended deletion.
471   if (remove_mask & REMOVE_PLUGIN_DATA &&
472       origin_set_mask_ & BrowsingDataHelper::UNPROTECTED_WEB) {
473     content::RecordAction(UserMetricsAction("ClearBrowsingData_LSOData"));
474 
475     waiting_for_clear_plugin_data_ = true;
476     if (!plugin_data_remover_.get())
477       plugin_data_remover_.reset(content::PluginDataRemover::Create(profile_));
478     base::WaitableEvent* event =
479         plugin_data_remover_->StartRemoving(delete_begin_);
480 
481     base::WaitableEventWatcher::EventCallback watcher_callback =
482         base::Bind(&BrowsingDataRemover::OnWaitableEventSignaled,
483                    base::Unretained(this));
484     watcher_.StartWatching(event, watcher_callback);
485   }
486 #endif
487 
488   if (remove_mask & REMOVE_PASSWORDS) {
489     content::RecordAction(UserMetricsAction("ClearBrowsingData_Passwords"));
490     PasswordStore* password_store = PasswordStoreFactory::GetForProfile(
491         profile_, Profile::EXPLICIT_ACCESS).get();
492 
493     if (password_store)
494       password_store->RemoveLoginsCreatedBetween(delete_begin_, delete_end_);
495   }
496 
497   if (remove_mask & REMOVE_FORM_DATA) {
498     content::RecordAction(UserMetricsAction("ClearBrowsingData_Autofill"));
499     scoped_refptr<autofill::AutofillWebDataService> web_data_service =
500         WebDataServiceFactory::GetAutofillWebDataForProfile(
501             profile_, Profile::EXPLICIT_ACCESS);
502 
503     if (web_data_service.get()) {
504       waiting_for_clear_form_ = true;
505       web_data_service->RemoveFormElementsAddedBetween(delete_begin_,
506           delete_end_);
507       web_data_service->RemoveAutofillDataModifiedBetween(
508           delete_begin_, delete_end_);
509       // The above calls are done on the UI thread but do their work on the DB
510       // thread. So wait for it.
511       BrowserThread::PostTaskAndReply(
512           BrowserThread::DB, FROM_HERE,
513           base::Bind(&base::DoNothing),
514           base::Bind(&BrowsingDataRemover::OnClearedFormData,
515                      base::Unretained(this)));
516 
517       autofill::PersonalDataManager* data_manager =
518           autofill::PersonalDataManagerFactory::GetForProfile(profile_);
519       if (data_manager)
520         data_manager->Refresh();
521     }
522   }
523 
524   if (remove_mask & REMOVE_CACHE) {
525     // Tell the renderers to clear their cache.
526     WebCacheManager::GetInstance()->ClearCache();
527 
528     // Invoke DoClearCache on the IO thread.
529     waiting_for_clear_cache_ = true;
530     content::RecordAction(UserMetricsAction("ClearBrowsingData_Cache"));
531 
532     BrowserThread::PostTask(
533         BrowserThread::IO, FROM_HERE,
534         base::Bind(&BrowsingDataRemover::ClearCacheOnIOThread,
535                    base::Unretained(this)));
536 
537 #if !defined(DISABLE_NACL)
538     waiting_for_clear_nacl_cache_ = true;
539 
540     BrowserThread::PostTask(
541         BrowserThread::IO, FROM_HERE,
542         base::Bind(&BrowsingDataRemover::ClearNaClCacheOnIOThread,
543                    base::Unretained(this)));
544 
545     waiting_for_clear_pnacl_cache_ = true;
546     BrowserThread::PostTask(
547         BrowserThread::IO, FROM_HERE,
548         base::Bind(&BrowsingDataRemover::ClearPnaclCacheOnIOThread,
549                    base::Unretained(this), delete_begin_, delete_end_));
550 #endif
551 
552     // The PrerenderManager may have a page actively being prerendered, which
553     // is essentially a preemptively cached page.
554     prerender::PrerenderManager* prerender_manager =
555         prerender::PrerenderManagerFactory::GetForProfile(profile_);
556     if (prerender_manager) {
557       prerender_manager->ClearData(
558           prerender::PrerenderManager::CLEAR_PRERENDER_CONTENTS);
559     }
560 
561     // Tell the shader disk cache to clear.
562     content::RecordAction(UserMetricsAction("ClearBrowsingData_ShaderCache"));
563     storage_partition_remove_mask |=
564         content::StoragePartition::REMOVE_DATA_MASK_SHADER_CACHE;
565 
566     storage_partition_remove_mask |=
567         content::StoragePartition::REMOVE_DATA_MASK_WEBRTC_IDENTITY;
568   }
569 
570   if (storage_partition_remove_mask) {
571     waiting_for_clear_storage_partition_data_ = true;
572 
573     content::StoragePartition* storage_partition;
574     if (storage_partition_for_testing_)
575       storage_partition = storage_partition_for_testing_;
576     else
577       storage_partition = BrowserContext::GetDefaultStoragePartition(profile_);
578 
579     uint32 quota_storage_remove_mask =
580         ~content::StoragePartition::QUOTA_MANAGED_STORAGE_MASK_PERSISTENT;
581 
582     if (delete_begin_ == base::Time() ||
583         origin_set_mask_ &
584           (BrowsingDataHelper::PROTECTED_WEB | BrowsingDataHelper::EXTENSION)) {
585       // If we're deleting since the beginning of time, or we're removing
586       // protected origins, then remove persistent quota data.
587       quota_storage_remove_mask |=
588           content::StoragePartition::QUOTA_MANAGED_STORAGE_MASK_PERSISTENT;
589     }
590 
591     storage_partition->ClearData(
592         storage_partition_remove_mask,
593         quota_storage_remove_mask,
594         &remove_origin_,
595         base::Bind(&DoesOriginMatchMask, origin_set_mask_),
596         delete_begin_,
597         delete_end_,
598         base::Bind(&BrowsingDataRemover::OnClearedStoragePartitionData,
599                    base::Unretained(this)));
600   }
601 
602 #if defined(ENABLE_PLUGINS)
603   if (remove_mask & REMOVE_CONTENT_LICENSES) {
604     content::RecordAction(
605         UserMetricsAction("ClearBrowsingData_ContentLicenses"));
606 
607     waiting_for_clear_content_licenses_ = true;
608     if (!pepper_flash_settings_manager_.get()) {
609       pepper_flash_settings_manager_.reset(
610           new PepperFlashSettingsManager(this, profile_));
611     }
612     deauthorize_content_licenses_request_id_ =
613         pepper_flash_settings_manager_->DeauthorizeContentLicenses(prefs);
614 #if defined(OS_CHROMEOS)
615     // On Chrome OS, also delete any content protection platform keys.
616     chromeos::User* user = chromeos::UserManager::Get()->
617         GetUserByProfile(profile_);
618     if (!user) {
619       LOG(WARNING) << "Failed to find user for current profile.";
620     } else {
621       chromeos::DBusThreadManager::Get()->GetCryptohomeClient()->
622           TpmAttestationDeleteKeys(
623               chromeos::attestation::KEY_USER,
624               user->email(),
625               chromeos::attestation::kContentProtectionKeyPrefix,
626               base::Bind(&BrowsingDataRemover::OnClearPlatformKeys,
627                          base::Unretained(this)));
628       waiting_for_clear_platform_keys_ = true;
629     }
630 #endif
631   }
632 #endif
633 
634   // Always wipe accumulated network related data (TransportSecurityState and
635   // HttpServerPropertiesManager data).
636   waiting_for_clear_networking_history_ = true;
637   profile_->ClearNetworkingHistorySince(
638       delete_begin_,
639       base::Bind(&BrowsingDataRemover::OnClearedNetworkingHistory,
640                  base::Unretained(this)));
641 }
642 
AddObserver(Observer * observer)643 void BrowsingDataRemover::AddObserver(Observer* observer) {
644   observer_list_.AddObserver(observer);
645 }
646 
RemoveObserver(Observer * observer)647 void BrowsingDataRemover::RemoveObserver(Observer* observer) {
648   observer_list_.RemoveObserver(observer);
649 }
650 
OnHistoryDeletionDone()651 void BrowsingDataRemover::OnHistoryDeletionDone() {
652   waiting_for_clear_history_ = false;
653   NotifyAndDeleteIfDone();
654 }
655 
OverrideStoragePartitionForTesting(content::StoragePartition * storage_partition)656 void BrowsingDataRemover::OverrideStoragePartitionForTesting(
657     content::StoragePartition* storage_partition) {
658   storage_partition_for_testing_ = storage_partition;
659 }
660 
CalculateBeginDeleteTime(TimePeriod time_period)661 base::Time BrowsingDataRemover::CalculateBeginDeleteTime(
662     TimePeriod time_period) {
663   base::TimeDelta diff;
664   base::Time delete_begin_time = base::Time::Now();
665   switch (time_period) {
666     case LAST_HOUR:
667       diff = base::TimeDelta::FromHours(1);
668       break;
669     case LAST_DAY:
670       diff = base::TimeDelta::FromHours(24);
671       break;
672     case LAST_WEEK:
673       diff = base::TimeDelta::FromHours(7*24);
674       break;
675     case FOUR_WEEKS:
676       diff = base::TimeDelta::FromHours(4*7*24);
677       break;
678     case EVERYTHING:
679       delete_begin_time = base::Time();
680       break;
681     default:
682       NOTREACHED() << L"Missing item";
683       break;
684   }
685   return delete_begin_time - diff;
686 }
687 
AllDone()688 bool BrowsingDataRemover::AllDone() {
689   return !waiting_for_clear_keyword_data_ &&
690          !waiting_for_clear_autofill_origin_urls_ &&
691          !waiting_for_clear_cache_ && !waiting_for_clear_nacl_cache_ &&
692          !waiting_for_clear_cookies_count_ && !waiting_for_clear_history_ &&
693          !waiting_for_clear_logged_in_predictor_ &&
694          !waiting_for_clear_networking_history_ &&
695          !waiting_for_clear_server_bound_certs_ &&
696          !waiting_for_clear_plugin_data_ &&
697          !waiting_for_clear_pnacl_cache_ &&
698          !waiting_for_clear_content_licenses_ && !waiting_for_clear_form_ &&
699          !waiting_for_clear_hostname_resolution_cache_ &&
700          !waiting_for_clear_network_predictor_ &&
701          !waiting_for_clear_platform_keys_ &&
702          !waiting_for_clear_storage_partition_data_;
703 }
704 
OnKeywordsLoaded()705 void BrowsingDataRemover::OnKeywordsLoaded() {
706   // Deletes the entries from the model, and if we're not waiting on anything
707   // else notifies observers and deletes this BrowsingDataRemover.
708   TemplateURLService* model =
709       TemplateURLServiceFactory::GetForProfile(profile_);
710   DCHECK_EQ(profile_, model->profile());
711   model->RemoveAutoGeneratedBetween(delete_begin_, delete_end_);
712   waiting_for_clear_keyword_data_ = false;
713   template_url_sub_.reset();
714   NotifyAndDeleteIfDone();
715 }
716 
NotifyAndDeleteIfDone()717 void BrowsingDataRemover::NotifyAndDeleteIfDone() {
718   // TODO(brettw) http://crbug.com/305259: This should also observe session
719   // clearing (what about other things such as passwords, etc.?) and wait for
720   // them to complete before continuing.
721 
722   if (!AllDone())
723     return;
724 
725   set_removing(false);
726 
727   // Send global notification, then notify any explicit observers.
728   BrowsingDataRemover::NotificationDetails details(delete_begin_, remove_mask_,
729       origin_set_mask_);
730   content::NotificationService::current()->Notify(
731       chrome::NOTIFICATION_BROWSING_DATA_REMOVED,
732       content::Source<Profile>(profile_),
733       content::Details<BrowsingDataRemover::NotificationDetails>(&details));
734 
735   FOR_EACH_OBSERVER(Observer, observer_list_, OnBrowsingDataRemoverDone());
736 
737   // History requests aren't happy if you delete yourself from the callback.
738   // As such, we do a delete later.
739   base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
740 }
741 
OnClearedHostnameResolutionCache()742 void BrowsingDataRemover::OnClearedHostnameResolutionCache() {
743   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
744   waiting_for_clear_hostname_resolution_cache_ = false;
745   NotifyAndDeleteIfDone();
746 }
747 
ClearHostnameResolutionCacheOnIOThread(IOThread * io_thread)748 void BrowsingDataRemover::ClearHostnameResolutionCacheOnIOThread(
749     IOThread* io_thread) {
750   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
751 
752   io_thread->ClearHostCache();
753 
754   // Notify the UI thread that we are done.
755   BrowserThread::PostTask(
756       BrowserThread::UI,
757       FROM_HERE,
758       base::Bind(&BrowsingDataRemover::OnClearedHostnameResolutionCache,
759                  base::Unretained(this)));
760 }
761 
OnClearedLoggedInPredictor()762 void BrowsingDataRemover::OnClearedLoggedInPredictor() {
763   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
764   DCHECK(waiting_for_clear_logged_in_predictor_);
765   waiting_for_clear_logged_in_predictor_ = false;
766   NotifyAndDeleteIfDone();
767 }
768 
ClearLoggedInPredictor()769 void BrowsingDataRemover::ClearLoggedInPredictor() {
770   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
771   DCHECK(!waiting_for_clear_logged_in_predictor_);
772 
773   predictors::PredictorDatabase* predictor_db =
774       predictors::PredictorDatabaseFactory::GetForProfile(profile_);
775   if (!predictor_db)
776     return;
777 
778   predictors::LoggedInPredictorTable* logged_in_table =
779       predictor_db->logged_in_table().get();
780   if (!logged_in_table)
781     return;
782 
783   waiting_for_clear_logged_in_predictor_ = true;
784 
785   BrowserThread::PostTaskAndReply(
786       BrowserThread::DB,
787       FROM_HERE,
788       base::Bind(&predictors::LoggedInPredictorTable::DeleteAllCreatedBetween,
789                  logged_in_table,
790                  delete_begin_,
791                  delete_end_),
792       base::Bind(&BrowsingDataRemover::OnClearedLoggedInPredictor,
793                  base::Unretained(this)));
794 }
795 
OnClearedNetworkPredictor()796 void BrowsingDataRemover::OnClearedNetworkPredictor() {
797   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
798   waiting_for_clear_network_predictor_ = false;
799   NotifyAndDeleteIfDone();
800 }
801 
ClearNetworkPredictorOnIOThread()802 void BrowsingDataRemover::ClearNetworkPredictorOnIOThread() {
803   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
804 
805   chrome_browser_net::Predictor* predictor = profile_->GetNetworkPredictor();
806   if (predictor) {
807     predictor->DiscardInitialNavigationHistory();
808     predictor->DiscardAllResults();
809   }
810 
811   // Notify the UI thread that we are done.
812   BrowserThread::PostTask(
813       BrowserThread::UI,
814       FROM_HERE,
815       base::Bind(&BrowsingDataRemover::OnClearedNetworkPredictor,
816                  base::Unretained(this)));
817 }
818 
OnClearedNetworkingHistory()819 void BrowsingDataRemover::OnClearedNetworkingHistory() {
820   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
821   waiting_for_clear_networking_history_ = false;
822   NotifyAndDeleteIfDone();
823 }
824 
ClearedCache()825 void BrowsingDataRemover::ClearedCache() {
826   waiting_for_clear_cache_ = false;
827 
828   NotifyAndDeleteIfDone();
829 }
830 
ClearCacheOnIOThread()831 void BrowsingDataRemover::ClearCacheOnIOThread() {
832   // This function should be called on the IO thread.
833   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
834   DCHECK_EQ(STATE_NONE, next_cache_state_);
835   DCHECK(main_context_getter_.get());
836   DCHECK(media_context_getter_.get());
837 
838   next_cache_state_ = STATE_CREATE_MAIN;
839   DoClearCache(net::OK);
840 }
841 
842 // The expected state sequence is STATE_NONE --> STATE_CREATE_MAIN -->
843 // STATE_DELETE_MAIN --> STATE_CREATE_MEDIA --> STATE_DELETE_MEDIA -->
844 // STATE_DONE, and any errors are ignored.
DoClearCache(int rv)845 void BrowsingDataRemover::DoClearCache(int rv) {
846   DCHECK_NE(STATE_NONE, next_cache_state_);
847 
848   while (rv != net::ERR_IO_PENDING && next_cache_state_ != STATE_NONE) {
849     switch (next_cache_state_) {
850       case STATE_CREATE_MAIN:
851       case STATE_CREATE_MEDIA: {
852         // Get a pointer to the cache.
853         net::URLRequestContextGetter* getter =
854             (next_cache_state_ == STATE_CREATE_MAIN)
855                 ? main_context_getter_.get()
856                 : media_context_getter_.get();
857         net::HttpTransactionFactory* factory =
858             getter->GetURLRequestContext()->http_transaction_factory();
859 
860         next_cache_state_ = (next_cache_state_ == STATE_CREATE_MAIN) ?
861                                 STATE_DELETE_MAIN : STATE_DELETE_MEDIA;
862         rv = factory->GetCache()->GetBackend(
863             &cache_, base::Bind(&BrowsingDataRemover::DoClearCache,
864                                 base::Unretained(this)));
865         break;
866       }
867       case STATE_DELETE_MAIN:
868       case STATE_DELETE_MEDIA: {
869         next_cache_state_ = (next_cache_state_ == STATE_DELETE_MAIN) ?
870                                 STATE_CREATE_MEDIA : STATE_DONE;
871 
872         // |cache_| can be null if it cannot be initialized.
873         if (cache_) {
874           if (delete_begin_.is_null()) {
875             rv = cache_->DoomAllEntries(
876                 base::Bind(&BrowsingDataRemover::DoClearCache,
877                            base::Unretained(this)));
878           } else {
879             rv = cache_->DoomEntriesBetween(
880                 delete_begin_, delete_end_,
881                 base::Bind(&BrowsingDataRemover::DoClearCache,
882                            base::Unretained(this)));
883           }
884           cache_ = NULL;
885         }
886         break;
887       }
888       case STATE_DONE: {
889         cache_ = NULL;
890         next_cache_state_ = STATE_NONE;
891 
892         // Notify the UI thread that we are done.
893         BrowserThread::PostTask(
894             BrowserThread::UI, FROM_HERE,
895             base::Bind(&BrowsingDataRemover::ClearedCache,
896                        base::Unretained(this)));
897         return;
898       }
899       default: {
900         NOTREACHED() << "bad state";
901         next_cache_state_ = STATE_NONE;  // Stop looping.
902         return;
903       }
904     }
905   }
906 }
907 
908 #if !defined(DISABLE_NACL)
ClearedNaClCache()909 void BrowsingDataRemover::ClearedNaClCache() {
910   // This function should be called on the UI thread.
911   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
912 
913   waiting_for_clear_nacl_cache_ = false;
914 
915   NotifyAndDeleteIfDone();
916 }
917 
ClearedNaClCacheOnIOThread()918 void BrowsingDataRemover::ClearedNaClCacheOnIOThread() {
919   // This function should be called on the IO thread.
920   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
921 
922   // Notify the UI thread that we are done.
923   BrowserThread::PostTask(
924       BrowserThread::UI, FROM_HERE,
925       base::Bind(&BrowsingDataRemover::ClearedNaClCache,
926                  base::Unretained(this)));
927 }
928 
ClearNaClCacheOnIOThread()929 void BrowsingDataRemover::ClearNaClCacheOnIOThread() {
930   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
931 
932   nacl::NaClBrowser::GetInstance()->ClearValidationCache(
933       base::Bind(&BrowsingDataRemover::ClearedNaClCacheOnIOThread,
934                  base::Unretained(this)));
935 }
936 
ClearedPnaclCache()937 void BrowsingDataRemover::ClearedPnaclCache() {
938   // This function should be called on the UI thread.
939   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
940 
941   waiting_for_clear_pnacl_cache_ = false;
942 
943   NotifyAndDeleteIfDone();
944 }
945 
ClearedPnaclCacheOnIOThread()946 void BrowsingDataRemover::ClearedPnaclCacheOnIOThread() {
947   // This function should be called on the IO thread.
948   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
949 
950   // Notify the UI thread that we are done.
951   BrowserThread::PostTask(
952       BrowserThread::UI, FROM_HERE,
953       base::Bind(&BrowsingDataRemover::ClearedPnaclCache,
954                  base::Unretained(this)));
955 }
956 
ClearPnaclCacheOnIOThread(base::Time begin,base::Time end)957 void BrowsingDataRemover::ClearPnaclCacheOnIOThread(base::Time begin,
958                                                     base::Time end) {
959   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
960 
961   pnacl::PnaclHost::GetInstance()->ClearTranslationCacheEntriesBetween(
962       begin, end,
963       base::Bind(&BrowsingDataRemover::ClearedPnaclCacheOnIOThread,
964                  base::Unretained(this)));
965 }
966 #endif
967 
OnWaitableEventSignaled(base::WaitableEvent * waitable_event)968 void BrowsingDataRemover::OnWaitableEventSignaled(
969     base::WaitableEvent* waitable_event) {
970   waiting_for_clear_plugin_data_ = false;
971   NotifyAndDeleteIfDone();
972 }
973 
974 #if defined(ENABLE_PLUGINS)
OnDeauthorizeContentLicensesCompleted(uint32 request_id,bool)975 void BrowsingDataRemover::OnDeauthorizeContentLicensesCompleted(
976     uint32 request_id,
977     bool /* success */) {
978   DCHECK(waiting_for_clear_content_licenses_);
979   DCHECK_EQ(request_id, deauthorize_content_licenses_request_id_);
980 
981   waiting_for_clear_content_licenses_ = false;
982   NotifyAndDeleteIfDone();
983 }
984 #endif
985 
986 #if defined(OS_CHROMEOS)
OnClearPlatformKeys(chromeos::DBusMethodCallStatus call_status,bool result)987 void BrowsingDataRemover::OnClearPlatformKeys(
988     chromeos::DBusMethodCallStatus call_status,
989     bool result) {
990   DCHECK(waiting_for_clear_platform_keys_);
991   if (call_status != chromeos::DBUS_METHOD_CALL_SUCCESS || !result) {
992     LOG(ERROR) << "Failed to clear platform keys.";
993   }
994   waiting_for_clear_platform_keys_ = false;
995   NotifyAndDeleteIfDone();
996 }
997 #endif
998 
OnClearedCookies(int num_deleted)999 void BrowsingDataRemover::OnClearedCookies(int num_deleted) {
1000   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
1001     BrowserThread::PostTask(
1002         BrowserThread::UI, FROM_HERE,
1003         base::Bind(&BrowsingDataRemover::OnClearedCookies,
1004                    base::Unretained(this), num_deleted));
1005     return;
1006   }
1007 
1008   DCHECK_GT(waiting_for_clear_cookies_count_, 0);
1009   --waiting_for_clear_cookies_count_;
1010   NotifyAndDeleteIfDone();
1011 }
1012 
ClearCookiesOnIOThread(net::URLRequestContextGetter * rq_context)1013 void BrowsingDataRemover::ClearCookiesOnIOThread(
1014     net::URLRequestContextGetter* rq_context) {
1015   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1016   net::CookieStore* cookie_store = rq_context->
1017       GetURLRequestContext()->cookie_store();
1018   cookie_store->DeleteAllCreatedBetweenAsync(
1019       delete_begin_, delete_end_,
1020       base::Bind(&BrowsingDataRemover::OnClearedCookies,
1021                  base::Unretained(this)));
1022 }
1023 
ClearServerBoundCertsOnIOThread(net::URLRequestContextGetter * rq_context)1024 void BrowsingDataRemover::ClearServerBoundCertsOnIOThread(
1025     net::URLRequestContextGetter* rq_context) {
1026   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1027   net::ServerBoundCertService* server_bound_cert_service =
1028       rq_context->GetURLRequestContext()->server_bound_cert_service();
1029   server_bound_cert_service->GetCertStore()->DeleteAllCreatedBetween(
1030       delete_begin_, delete_end_,
1031       base::Bind(&BrowsingDataRemover::OnClearedServerBoundCertsOnIOThread,
1032                  base::Unretained(this), base::Unretained(rq_context)));
1033 }
1034 
OnClearedServerBoundCertsOnIOThread(net::URLRequestContextGetter * rq_context)1035 void BrowsingDataRemover::OnClearedServerBoundCertsOnIOThread(
1036     net::URLRequestContextGetter* rq_context) {
1037   // Need to close open SSL connections which may be using the channel ids we
1038   // are deleting.
1039   // TODO(mattm): http://crbug.com/166069 Make the server bound cert
1040   // service/store have observers that can notify relevant things directly.
1041   rq_context->GetURLRequestContext()->ssl_config_service()->
1042       NotifySSLConfigChange();
1043   BrowserThread::PostTask(
1044       BrowserThread::UI, FROM_HERE,
1045       base::Bind(&BrowsingDataRemover::OnClearedServerBoundCerts,
1046                  base::Unretained(this)));
1047 }
1048 
OnClearedServerBoundCerts()1049 void BrowsingDataRemover::OnClearedServerBoundCerts() {
1050   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1051   waiting_for_clear_server_bound_certs_ = false;
1052   NotifyAndDeleteIfDone();
1053 }
1054 
OnClearedFormData()1055 void BrowsingDataRemover::OnClearedFormData() {
1056   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1057   waiting_for_clear_form_ = false;
1058   NotifyAndDeleteIfDone();
1059 }
1060 
OnClearedAutofillOriginURLs()1061 void BrowsingDataRemover::OnClearedAutofillOriginURLs() {
1062   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1063   waiting_for_clear_autofill_origin_urls_ = false;
1064   NotifyAndDeleteIfDone();
1065 }
1066 
OnClearedStoragePartitionData()1067 void BrowsingDataRemover::OnClearedStoragePartitionData() {
1068   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1069   waiting_for_clear_storage_partition_data_ = false;
1070   NotifyAndDeleteIfDone();
1071 }
1072