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