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
85using content::BrowserContext;
86using content::BrowserThread;
87using content::DOMStorageContext;
88using content::UserMetricsAction;
89
90bool BrowsingDataRemover::is_removing_ = false;
91
92// Helper to create callback for BrowsingDataRemover::DoesOriginMatchMask.
93// Static.
94bool 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
102BrowsingDataRemover::NotificationDetails::NotificationDetails()
103    : removal_begin(base::Time()),
104      removal_mask(-1),
105      origin_set_mask(-1) {
106}
107
108BrowsingDataRemover::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
115BrowsingDataRemover::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
124BrowsingDataRemover::NotificationDetails::~NotificationDetails() {}
125
126// Static.
127BrowsingDataRemover* BrowsingDataRemover::CreateForUnboundedRange(
128    Profile* profile) {
129  return new BrowsingDataRemover(profile, base::Time(), base::Time::Max());
130}
131
132// Static.
133BrowsingDataRemover* BrowsingDataRemover::CreateForRange(Profile* profile,
134    base::Time start, base::Time end) {
135  return new BrowsingDataRemover(profile, start, end);
136}
137
138// Static.
139BrowsingDataRemover* 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
168BrowsingDataRemover::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
210BrowsingDataRemover::~BrowsingDataRemover() {
211  DCHECK(AllDone());
212}
213
214// Static.
215void BrowsingDataRemover::set_removing(bool is_removing) {
216  DCHECK(is_removing_ != is_removing);
217  is_removing_ = is_removing;
218}
219
220void BrowsingDataRemover::Remove(int remove_mask, int origin_set_mask) {
221  RemoveImpl(remove_mask, GURL(), origin_set_mask);
222}
223
224void 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
643void BrowsingDataRemover::AddObserver(Observer* observer) {
644  observer_list_.AddObserver(observer);
645}
646
647void BrowsingDataRemover::RemoveObserver(Observer* observer) {
648  observer_list_.RemoveObserver(observer);
649}
650
651void BrowsingDataRemover::OnHistoryDeletionDone() {
652  waiting_for_clear_history_ = false;
653  NotifyAndDeleteIfDone();
654}
655
656void BrowsingDataRemover::OverrideStoragePartitionForTesting(
657    content::StoragePartition* storage_partition) {
658  storage_partition_for_testing_ = storage_partition;
659}
660
661base::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
688bool 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
705void 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
717void 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
742void BrowsingDataRemover::OnClearedHostnameResolutionCache() {
743  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
744  waiting_for_clear_hostname_resolution_cache_ = false;
745  NotifyAndDeleteIfDone();
746}
747
748void 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
762void 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
769void 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
796void BrowsingDataRemover::OnClearedNetworkPredictor() {
797  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
798  waiting_for_clear_network_predictor_ = false;
799  NotifyAndDeleteIfDone();
800}
801
802void 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
819void BrowsingDataRemover::OnClearedNetworkingHistory() {
820  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
821  waiting_for_clear_networking_history_ = false;
822  NotifyAndDeleteIfDone();
823}
824
825void BrowsingDataRemover::ClearedCache() {
826  waiting_for_clear_cache_ = false;
827
828  NotifyAndDeleteIfDone();
829}
830
831void 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.
845void 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)
909void 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
918void 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
929void 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
937void 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
946void 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
957void 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
968void BrowsingDataRemover::OnWaitableEventSignaled(
969    base::WaitableEvent* waitable_event) {
970  waiting_for_clear_plugin_data_ = false;
971  NotifyAndDeleteIfDone();
972}
973
974#if defined(ENABLE_PLUGINS)
975void 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)
987void 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
999void 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
1013void 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
1024void 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
1035void 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
1049void BrowsingDataRemover::OnClearedServerBoundCerts() {
1050  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1051  waiting_for_clear_server_bound_certs_ = false;
1052  NotifyAndDeleteIfDone();
1053}
1054
1055void BrowsingDataRemover::OnClearedFormData() {
1056  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1057  waiting_for_clear_form_ = false;
1058  NotifyAndDeleteIfDone();
1059}
1060
1061void BrowsingDataRemover::OnClearedAutofillOriginURLs() {
1062  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1063  waiting_for_clear_autofill_origin_urls_ = false;
1064  NotifyAndDeleteIfDone();
1065}
1066
1067void BrowsingDataRemover::OnClearedStoragePartitionData() {
1068  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1069  waiting_for_clear_storage_partition_data_ = false;
1070  NotifyAndDeleteIfDone();
1071}
1072