blob: 9273f01ae3b63134f0a9a15e0f49457e42152aab [file] [log] [blame]
[email protected]ac4c6682012-01-04 00:57:391// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
5#include "chrome/browser/browsing_data_remover.h"
6
[email protected]3f934582010-06-23 01:18:397#include <map>
8#include <set>
9
[email protected]ade9abe2011-09-02 17:29:1210#include "base/bind.h"
[email protected]bbdd2982011-10-08 18:14:2411#include "base/bind_helpers.h"
[email protected]2041cf342010-02-19 03:15:5912#include "base/callback.h"
[email protected]6ccb5e52011-05-19 23:36:2513#include "base/file_util.h"
[email protected]94704172011-08-01 16:23:4014#include "base/logging.h"
[email protected]cdba46992011-06-07 11:51:3915#include "base/platform_file.h"
[email protected]18f92d4f2010-10-19 00:14:5816#include "chrome/browser/autofill/personal_data_manager.h"
[email protected]ea9edcb02011-09-23 22:05:0417#include "chrome/browser/autofill/personal_data_manager_factory.h"
[email protected]d6f37fc2011-02-13 23:58:4118#include "chrome/browser/browser_process.h"
[email protected]9bb54ee2011-10-12 17:43:3519#include "chrome/browser/download/download_service.h"
20#include "chrome/browser/download/download_service_factory.h"
[email protected]eaa7dd182010-12-14 11:09:0021#include "chrome/browser/extensions/extension_service.h"
[email protected]19eb80152011-02-26 00:28:4322#include "chrome/browser/extensions/extension_special_storage_policy.h"
[email protected]a9afddb2009-02-12 17:49:4223#include "chrome/browser/history/history.h"
[email protected]d6f37fc2011-02-13 23:58:4124#include "chrome/browser/io_thread.h"
[email protected]d6f37fc2011-02-13 23:58:4125#include "chrome/browser/net/chrome_net_log.h"
[email protected]d68a4fc62010-03-05 23:40:0226#include "chrome/browser/net/chrome_url_request_context.h"
[email protected]67372ecf2011-09-10 01:30:4627#include "chrome/browser/net/predictor.h"
[email protected]270b85e2009-07-10 23:40:2828#include "chrome/browser/password_manager/password_store.h"
[email protected]dceaa912011-09-06 17:17:2329#include "chrome/browser/prefs/pref_member.h"
[email protected]cf5db4c2011-06-20 21:02:5730#include "chrome/browser/prerender/prerender_manager.h"
[email protected]3085c502011-10-05 17:50:5031#include "chrome/browser/prerender/prerender_manager_factory.h"
[email protected]d6f37fc2011-02-13 23:58:4132#include "chrome/browser/profiles/profile.h"
[email protected]163753f2010-10-01 20:59:0333#include "chrome/browser/renderer_host/web_cache_manager.h"
[email protected]8e5c89a2011-06-07 18:13:3334#include "chrome/browser/search_engines/template_url_service.h"
35#include "chrome/browser/search_engines/template_url_service_factory.h"
[email protected]85e921fb82009-02-11 23:19:4436#include "chrome/browser/sessions/session_service.h"
[email protected]92371eb2011-04-28 11:50:1537#include "chrome/browser/sessions/session_service_factory.h"
[email protected]bd580a252009-02-12 01:16:3038#include "chrome/browser/sessions/tab_restore_service.h"
[email protected]92371eb2011-04-28 11:50:1539#include "chrome/browser/sessions/tab_restore_service_factory.h"
initial.commit09911bf2008-07-26 23:55:2940#include "chrome/browser/webdata/web_data_service.h"
[email protected]432115822011-07-10 15:52:2741#include "chrome/common/chrome_notification_types.h"
[email protected]dceaa912011-09-06 17:17:2342#include "chrome/common/pref_names.h"
[email protected]03c9d742010-02-05 21:15:1843#include "chrome/common/url_constants.h"
[email protected]567812d2011-02-24 17:40:5044#include "content/browser/in_process_webkit/webkit_context.h"
[email protected]c38831a12011-10-28 12:44:4945#include "content/public/browser/browser_thread.h"
[email protected]e582fdd2011-12-20 16:48:1746#include "content/public/browser/download_manager.h"
[email protected]8d7554d82011-12-13 17:11:0847#include "content/public/browser/notification_service.h"
[email protected]d8e682012011-11-17 18:31:5448#include "content/public/browser/plugin_data_remover.h"
[email protected]7f6f44c2011-12-14 13:23:3849#include "content/public/browser/user_metrics.h"
[email protected]b236b7d2011-12-21 09:06:2650#include "net/base/cookie_store.h"
[email protected]72cfd90f2010-02-06 03:08:0451#include "net/base/net_errors.h"
[email protected]eb7974c2012-01-25 17:38:4852#include "net/base/origin_bound_cert_service.h"
53#include "net/base/origin_bound_cert_store.h"
[email protected]4d0d8082010-02-23 01:03:1054#include "net/base/transport_security_state.h"
initial.commit09911bf2008-07-26 23:55:2955#include "net/disk_cache/disk_cache.h"
56#include "net/http/http_cache.h"
57#include "net/url_request/url_request_context.h"
[email protected]abe2c032011-03-31 18:49:3458#include "net/url_request/url_request_context_getter.h"
[email protected]94704172011-08-01 16:23:4059#include "webkit/quota/quota_manager.h"
60#include "webkit/quota/quota_types.h"
initial.commit09911bf2008-07-26 23:55:2961
[email protected]631bb742011-11-02 11:29:3962using content::BrowserThread;
[email protected]e582fdd2011-12-20 16:48:1763using content::DownloadManager;
[email protected]7f6f44c2011-12-14 13:23:3864using content::UserMetricsAction;
[email protected]631bb742011-11-02 11:29:3965
[email protected]13dc77912009-03-03 01:47:2266bool BrowsingDataRemover::removing_ = false;
67
[email protected]8d7554d82011-12-13 17:11:0868BrowsingDataRemover::NotificationDetails::NotificationDetails()
69 : removal_begin(base::Time()),
70 removal_mask(-1) {
71}
72
73BrowsingDataRemover::NotificationDetails::NotificationDetails(
74 const BrowsingDataRemover::NotificationDetails& details)
75 : removal_begin(details.removal_begin),
76 removal_mask(details.removal_mask) {
77}
78
79BrowsingDataRemover::NotificationDetails::NotificationDetails(
80 base::Time removal_begin,
81 int removal_mask)
82 : removal_begin(removal_begin),
83 removal_mask(removal_mask) {
84}
85
86BrowsingDataRemover::NotificationDetails::~NotificationDetails() {}
87
[email protected]25364e12009-05-22 01:37:1988BrowsingDataRemover::BrowsingDataRemover(Profile* profile,
89 base::Time delete_begin,
90 base::Time delete_end)
initial.commit09911bf2008-07-26 23:55:2991 : profile_(profile),
[email protected]94704172011-08-01 16:23:4092 quota_manager_(NULL),
[email protected]19eb80152011-02-26 00:28:4393 special_storage_policy_(profile->GetExtensionSpecialStoragePolicy()),
initial.commit09911bf2008-07-26 23:55:2994 delete_begin_(delete_begin),
95 delete_end_(delete_end),
[email protected]d885bfe2010-05-21 18:29:4596 next_cache_state_(STATE_NONE),
97 cache_(NULL),
[email protected]d6f37fc2011-02-13 23:58:4198 main_context_getter_(profile->GetRequestContext()),
99 media_context_getter_(profile->GetRequestContextForMedia()),
[email protected]d68a4fc62010-03-05 23:40:02100 waiting_for_clear_cache_(false),
[email protected]eb7974c2012-01-25 17:38:48101 waiting_for_clear_cookies_(false),
102 waiting_for_clear_history_(false),
103 waiting_for_clear_networking_history_(false),
104 waiting_for_clear_origin_bound_certs_(false),
[email protected]59eca0f2011-12-13 19:16:39105 waiting_for_clear_plugin_data_(false),
[email protected]eb7974c2012-01-25 17:38:48106 waiting_for_clear_quota_managed_data_(false),
[email protected]8d7554d82011-12-13 17:11:08107 remove_mask_(0) {
initial.commit09911bf2008-07-26 23:55:29108 DCHECK(profile);
109}
110
[email protected]25364e12009-05-22 01:37:19111BrowsingDataRemover::BrowsingDataRemover(Profile* profile,
112 TimePeriod time_period,
113 base::Time delete_end)
114 : profile_(profile),
[email protected]94704172011-08-01 16:23:40115 quota_manager_(NULL),
[email protected]19eb80152011-02-26 00:28:43116 special_storage_policy_(profile->GetExtensionSpecialStoragePolicy()),
[email protected]25364e12009-05-22 01:37:19117 delete_begin_(CalculateBeginDeleteTime(time_period)),
118 delete_end_(delete_end),
[email protected]d885bfe2010-05-21 18:29:45119 next_cache_state_(STATE_NONE),
120 cache_(NULL),
[email protected]d6f37fc2011-02-13 23:58:41121 main_context_getter_(profile->GetRequestContext()),
122 media_context_getter_(profile->GetRequestContextForMedia()),
[email protected]d68a4fc62010-03-05 23:40:02123 waiting_for_clear_cache_(false),
[email protected]eb7974c2012-01-25 17:38:48124 waiting_for_clear_cookies_(false),
125 waiting_for_clear_history_(false),
126 waiting_for_clear_networking_history_(false),
127 waiting_for_clear_origin_bound_certs_(false),
[email protected]59eca0f2011-12-13 19:16:39128 waiting_for_clear_plugin_data_(false),
[email protected]eb7974c2012-01-25 17:38:48129 waiting_for_clear_quota_managed_data_(false),
[email protected]8d7554d82011-12-13 17:11:08130 remove_mask_(0) {
[email protected]25364e12009-05-22 01:37:19131 DCHECK(profile);
132}
133
initial.commit09911bf2008-07-26 23:55:29134BrowsingDataRemover::~BrowsingDataRemover() {
135 DCHECK(all_done());
136}
137
[email protected]6093d742011-08-26 16:37:18138// Static.
139void BrowsingDataRemover::set_removing(bool removing) {
140 DCHECK(removing_ != removing);
141 removing_ = removing;
142}
143
initial.commit09911bf2008-07-26 23:55:29144void BrowsingDataRemover::Remove(int remove_mask) {
[email protected]ade9abe2011-09-02 17:29:12145 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]6093d742011-08-26 16:37:18146 set_removing(true);
[email protected]8d7554d82011-12-13 17:11:08147 remove_mask_ = remove_mask;
initial.commit09911bf2008-07-26 23:55:29148
149 if (remove_mask & REMOVE_HISTORY) {
150 HistoryService* history_service =
151 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
152 if (history_service) {
[email protected]21f4d2512010-03-05 08:15:53153 std::set<GURL> restrict_urls;
[email protected]7f6f44c2011-12-14 13:23:38154 content::RecordAction(UserMetricsAction("ClearBrowsingData_History"));
initial.commit09911bf2008-07-26 23:55:29155 waiting_for_clear_history_ = true;
[email protected]21f4d2512010-03-05 08:15:53156 history_service->ExpireHistoryBetween(restrict_urls,
157 delete_begin_, delete_end_,
initial.commit09911bf2008-07-26 23:55:29158 &request_consumer_,
[email protected]bbdd2982011-10-08 18:14:24159 base::Bind(&BrowsingDataRemover::OnHistoryDeletionDone,
160 base::Unretained(this)));
initial.commit09911bf2008-07-26 23:55:29161 }
162
[email protected]df2840d2011-02-20 16:32:32163 // Need to clear the host cache and accumulated speculative data, as it also
164 // reveals some history.
[email protected]9d4ca082011-05-30 16:39:41165 if (g_browser_process->io_thread()) {
166 waiting_for_clear_networking_history_ = true;
167 BrowserThread::PostTask(
168 BrowserThread::IO, FROM_HERE,
[email protected]006284f02011-10-19 22:06:23169 base::Bind(&BrowsingDataRemover::ClearNetworkingHistory,
170 base::Unretained(this), g_browser_process->io_thread()));
[email protected]9d4ca082011-05-30 16:39:41171 }
[email protected]d6f37fc2011-02-13 23:58:41172
initial.commit09911bf2008-07-26 23:55:29173 // As part of history deletion we also delete the auto-generated keywords.
[email protected]8e5c89a2011-06-07 18:13:33174 TemplateURLService* keywords_model =
175 TemplateURLServiceFactory::GetForProfile(profile_);
initial.commit09911bf2008-07-26 23:55:29176 if (keywords_model && !keywords_model->loaded()) {
[email protected]432115822011-07-10 15:52:27177 registrar_.Add(this, chrome::NOTIFICATION_TEMPLATE_URL_SERVICE_LOADED,
[email protected]6c2381d2011-10-19 02:52:53178 content::Source<TemplateURLService>(keywords_model));
initial.commit09911bf2008-07-26 23:55:29179 keywords_model->Load();
180 } else if (keywords_model) {
181 keywords_model->RemoveAutoGeneratedBetween(delete_begin_, delete_end_);
182 }
183
184 // We also delete the list of recently closed tabs. Since these expire,
185 // they can't be more than a day old, so we can simply clear them all.
[email protected]92371eb2011-04-28 11:50:15186 TabRestoreService* tab_service =
187 TabRestoreServiceFactory::GetForProfile(profile_);
[email protected]169627b2008-12-06 19:30:19188 if (tab_service) {
[email protected]d8375fd2008-11-25 22:45:39189 tab_service->ClearEntries();
[email protected]169627b2008-12-06 19:30:19190 tab_service->DeleteLastSession();
191 }
initial.commit09911bf2008-07-26 23:55:29192
193 // We also delete the last session when we delete the history.
[email protected]92371eb2011-04-28 11:50:15194 SessionService* session_service =
195 SessionServiceFactory::GetForProfile(profile_);
initial.commit09911bf2008-07-26 23:55:29196 if (session_service)
[email protected]169627b2008-12-06 19:30:19197 session_service->DeleteLastSession();
[email protected]cf5db4c2011-06-20 21:02:57198
199 // The PrerenderManager keeps history of prerendered pages, so clear that.
200 // It also may have a prerendered page. If so, the page could be considered
201 // to have a small amount of historical information, so delete it, too.
202 prerender::PrerenderManager* prerender_manager =
[email protected]3085c502011-10-05 17:50:50203 prerender::PrerenderManagerFactory::GetForProfile(profile_);
[email protected]cf5db4c2011-06-20 21:02:57204 if (prerender_manager) {
205 prerender_manager->ClearData(
206 prerender::PrerenderManager::CLEAR_PRERENDER_CONTENTS |
207 prerender::PrerenderManager::CLEAR_PRERENDER_HISTORY);
208 }
initial.commit09911bf2008-07-26 23:55:29209 }
210
211 if (remove_mask & REMOVE_DOWNLOADS) {
[email protected]7f6f44c2011-12-14 13:23:38212 content::RecordAction(UserMetricsAction("ClearBrowsingData_Downloads"));
[email protected]9bb54ee2011-10-12 17:43:35213 DownloadManager* download_manager =
214 DownloadServiceFactory::GetForProfile(profile_)->GetDownloadManager();
initial.commit09911bf2008-07-26 23:55:29215 download_manager->RemoveDownloadsBetween(delete_begin_, delete_end_);
[email protected]905a08d2008-11-19 07:24:12216 download_manager->ClearLastDownloadPath();
initial.commit09911bf2008-07-26 23:55:29217 }
218
219 if (remove_mask & REMOVE_COOKIES) {
[email protected]7f6f44c2011-12-14 13:23:38220 content::RecordAction(UserMetricsAction("ClearBrowsingData_Cookies"));
[email protected]be180c802009-10-23 06:33:31221 // Since we are running on the UI thread don't call GetURLRequestContext().
[email protected]cdba46992011-06-07 11:51:39222 net::URLRequestContextGetter* rq_context = profile_->GetRequestContext();
223 if (rq_context) {
[email protected]ade9abe2011-09-02 17:29:12224 waiting_for_clear_cookies_ = true;
225 BrowserThread::PostTask(
226 BrowserThread::IO, FROM_HERE,
227 base::Bind(&BrowsingDataRemover::ClearCookiesOnIOThread,
228 base::Unretained(this), base::Unretained(rq_context)));
[email protected]cdba46992011-06-07 11:51:39229 }
[email protected]dceaa912011-09-06 17:17:23230 }
[email protected]4d0d8082010-02-23 01:03:10231
[email protected]eb7974c2012-01-25 17:38:48232 if (remove_mask & REMOVE_ORIGIN_BOUND_CERTS) {
233 content::RecordAction(
234 UserMetricsAction("ClearBrowsingData_OriginBoundCerts"));
235 // Since we are running on the UI thread don't call GetURLRequestContext().
236 net::URLRequestContextGetter* rq_context = profile_->GetRequestContext();
237 if (rq_context) {
238 waiting_for_clear_origin_bound_certs_ = true;
239 BrowserThread::PostTask(
240 BrowserThread::IO, FROM_HERE,
241 base::Bind(&BrowsingDataRemover::ClearOriginBoundCertsOnIOThread,
242 base::Unretained(this), base::Unretained(rq_context)));
243 }
244 }
245
[email protected]dceaa912011-09-06 17:17:23246 if (remove_mask & REMOVE_LOCAL_STORAGE) {
247 // Remove data such as local databases, STS state, etc. These only can
[email protected]cdba46992011-06-07 11:51:39248 // be removed if a WEBKIT thread exists, so check that first:
[email protected]e1dd5622011-12-20 12:28:58249 if (BrowserThread::IsMessageLoopValid(BrowserThread::WEBKIT_DEPRECATED)) {
[email protected]cdba46992011-06-07 11:51:39250 // We assume the end time is now.
251 profile_->GetWebKitContext()->DeleteDataModifiedSince(delete_begin_);
252 }
[email protected]dceaa912011-09-06 17:17:23253 }
[email protected]72cfd90f2010-02-06 03:08:04254
[email protected]dceaa912011-09-06 17:17:23255 if (remove_mask & REMOVE_INDEXEDDB || remove_mask & REMOVE_WEBSQL ||
256 remove_mask & REMOVE_APPCACHE || remove_mask & REMOVE_FILE_SYSTEMS) {
257 // TODO(mkwst): At the moment, we don't have the ability to pass a mask into
258 // QuotaManager. Until then, we'll clear all quota-managed data types if any
259 // ought to be cleared.
[email protected]94704172011-08-01 16:23:40260 quota_manager_ = profile_->GetQuotaManager();
261 if (quota_manager_) {
262 waiting_for_clear_quota_managed_data_ = true;
[email protected]adc2e542011-07-07 10:52:48263 BrowserThread::PostTask(
264 BrowserThread::IO, FROM_HERE,
[email protected]006284f02011-10-19 22:06:23265 base::Bind(&BrowsingDataRemover::ClearQuotaManagedDataOnIOThread,
266 base::Unretained(this)));
[email protected]adc2e542011-07-07 10:52:48267 }
[email protected]dceaa912011-09-06 17:17:23268 }
[email protected]19eb80152011-02-26 00:28:43269
[email protected]59eca0f2011-12-13 19:16:39270 if (remove_mask & REMOVE_PLUGIN_DATA) {
[email protected]7f6f44c2011-12-14 13:23:38271 content::RecordAction(UserMetricsAction("ClearBrowsingData_LSOData"));
[email protected]dceaa912011-09-06 17:17:23272
[email protected]59eca0f2011-12-13 19:16:39273 waiting_for_clear_plugin_data_ = true;
[email protected]d8e682012011-11-17 18:31:54274 if (!plugin_data_remover_.get()) {
275 plugin_data_remover_.reset(
276 content::PluginDataRemover::Create(profile_->GetResourceContext()));
277 }
[email protected]dceaa912011-09-06 17:17:23278 base::WaitableEvent* event =
279 plugin_data_remover_->StartRemoving(delete_begin_);
280 watcher_.StartWatching(event, this);
initial.commit09911bf2008-07-26 23:55:29281 }
282
283 if (remove_mask & REMOVE_PASSWORDS) {
[email protected]7f6f44c2011-12-14 13:23:38284 content::RecordAction(UserMetricsAction("ClearBrowsingData_Passwords"));
[email protected]270b85e2009-07-10 23:40:28285 PasswordStore* password_store =
286 profile_->GetPasswordStore(Profile::EXPLICIT_ACCESS);
initial.commit09911bf2008-07-26 23:55:29287
[email protected]dbba57f2010-08-17 16:16:26288 if (password_store)
289 password_store->RemoveLoginsCreatedBetween(delete_begin_, delete_end_);
initial.commit09911bf2008-07-26 23:55:29290 }
291
[email protected]55209a4b2008-10-31 17:14:02292 if (remove_mask & REMOVE_FORM_DATA) {
[email protected]7f6f44c2011-12-14 13:23:38293 content::RecordAction(UserMetricsAction("ClearBrowsingData_Autofill"));
[email protected]603c1d02008-11-12 22:39:14294 WebDataService* web_data_service =
295 profile_->GetWebDataService(Profile::EXPLICIT_ACCESS);
296
[email protected]dbba57f2010-08-17 16:16:26297 if (web_data_service) {
298 web_data_service->RemoveFormElementsAddedBetween(delete_begin_,
299 delete_end_);
[email protected]e90c2252011-03-10 12:29:21300 web_data_service->RemoveAutofillProfilesAndCreditCardsModifiedBetween(
[email protected]18f92d4f2010-10-19 00:14:58301 delete_begin_, delete_end_);
[email protected]ea9edcb02011-09-23 22:05:04302 PersonalDataManager* data_manager =
303 PersonalDataManagerFactory::GetForProfile(profile_);
[email protected]7271ae62010-11-11 19:35:05304 if (data_manager) {
305 data_manager->Refresh();
306 }
[email protected]dbba57f2010-08-17 16:16:26307 }
[email protected]55209a4b2008-10-31 17:14:02308 }
309
initial.commit09911bf2008-07-26 23:55:29310 if (remove_mask & REMOVE_CACHE) {
[email protected]163753f2010-10-01 20:59:03311 // Tell the renderers to clear their cache.
312 WebCacheManager::GetInstance()->ClearCache();
313
[email protected]93dcf3d2011-03-16 00:00:57314 // Invoke DoClearCache on the IO thread.
[email protected]6fad2632009-11-02 05:59:37315 waiting_for_clear_cache_ = true;
[email protected]7f6f44c2011-12-14 13:23:38316 content::RecordAction(UserMetricsAction("ClearBrowsingData_Cache"));
[email protected]3d04ea52009-11-06 08:58:16317
[email protected]d04e7662010-10-10 22:24:48318 BrowserThread::PostTask(
319 BrowserThread::IO, FROM_HERE,
[email protected]006284f02011-10-19 22:06:23320 base::Bind(&BrowsingDataRemover::ClearCacheOnIOThread,
321 base::Unretained(this)));
[email protected]cf5db4c2011-06-20 21:02:57322
323 // The PrerenderManager may have a page actively being prerendered, which
324 // is essentially a preemptively cached page.
325 prerender::PrerenderManager* prerender_manager =
[email protected]3085c502011-10-05 17:50:50326 prerender::PrerenderManagerFactory::GetForProfile(profile_);
[email protected]cf5db4c2011-06-20 21:02:57327 if (prerender_manager) {
328 prerender_manager->ClearData(
329 prerender::PrerenderManager::CLEAR_PRERENDER_CONTENTS);
330 }
initial.commit09911bf2008-07-26 23:55:29331 }
332
[email protected]db96a882011-10-09 02:01:54333 // Also delete cached network related data (like TransportSecurityState,
334 // HttpServerProperties data).
335 profile_->ClearNetworkingHistorySince(delete_begin_);
[email protected]09d81f82010-12-15 16:46:42336
initial.commit09911bf2008-07-26 23:55:29337 NotifyAndDeleteIfDone();
338}
339
340void BrowsingDataRemover::AddObserver(Observer* observer) {
341 observer_list_.AddObserver(observer);
342}
343
344void BrowsingDataRemover::RemoveObserver(Observer* observer) {
345 observer_list_.RemoveObserver(observer);
346}
347
348void BrowsingDataRemover::OnHistoryDeletionDone() {
349 waiting_for_clear_history_ = false;
350 NotifyAndDeleteIfDone();
351}
352
[email protected]25364e12009-05-22 01:37:19353base::Time BrowsingDataRemover::CalculateBeginDeleteTime(
354 TimePeriod time_period) {
355 base::TimeDelta diff;
356 base::Time delete_begin_time = base::Time::Now();
357 switch (time_period) {
[email protected]5c7d3102010-02-11 00:25:44358 case LAST_HOUR:
359 diff = base::TimeDelta::FromHours(1);
360 break;
[email protected]25364e12009-05-22 01:37:19361 case LAST_DAY:
362 diff = base::TimeDelta::FromHours(24);
363 break;
364 case LAST_WEEK:
365 diff = base::TimeDelta::FromHours(7*24);
366 break;
367 case FOUR_WEEKS:
368 diff = base::TimeDelta::FromHours(4*7*24);
369 break;
370 case EVERYTHING:
371 delete_begin_time = base::Time();
372 break;
373 default:
374 NOTREACHED() << L"Missing item";
375 break;
376 }
377 return delete_begin_time - diff;
378}
379
[email protected]432115822011-07-10 15:52:27380void BrowsingDataRemover::Observe(int type,
[email protected]6c2381d2011-10-19 02:52:53381 const content::NotificationSource& source,
382 const content::NotificationDetails& details) {
initial.commit09911bf2008-07-26 23:55:29383 // TODO(brettw) bug 1139736: This should also observe session
384 // clearing (what about other things such as passwords, etc.?) and wait for
385 // them to complete before continuing.
[email protected]432115822011-07-10 15:52:27386 DCHECK(type == chrome::NOTIFICATION_TEMPLATE_URL_SERVICE_LOADED);
[email protected]6c2381d2011-10-19 02:52:53387 TemplateURLService* model = content::Source<TemplateURLService>(source).ptr();
[email protected]8d7554d82011-12-13 17:11:08388 if (model->profile() == profile_) {
[email protected]b3edb31e2009-05-22 01:47:16389 registrar_.RemoveAll();
initial.commit09911bf2008-07-26 23:55:29390 model->RemoveAutoGeneratedBetween(delete_begin_, delete_end_);
initial.commit09911bf2008-07-26 23:55:29391 NotifyAndDeleteIfDone();
392 }
393}
394
395void BrowsingDataRemover::NotifyAndDeleteIfDone() {
396 // TODO(brettw) bug 1139736: see TODO in Observe() above.
397 if (!all_done())
398 return;
399
[email protected]d6f37fc2011-02-13 23:58:41400 // The NetLog contains download history, but may also contain form data,
401 // cookies and passwords. Simplest just to always clear it. Must be cleared
402 // after the cache, as cleaning up the disk cache exposes some of the history
403 // in the NetLog.
[email protected]9d4ca082011-05-30 16:39:41404 if (g_browser_process->net_log())
405 g_browser_process->net_log()->ClearAllPassivelyCapturedEvents();
[email protected]d6f37fc2011-02-13 23:58:41406
[email protected]6093d742011-08-26 16:37:18407 set_removing(false);
[email protected]8d7554d82011-12-13 17:11:08408
409 // Send global notification, then notify any explicit observers.
410 BrowsingDataRemover::NotificationDetails details(delete_begin_, remove_mask_);
411 content::NotificationService::current()->Notify(
412 chrome::NOTIFICATION_BROWSING_DATA_REMOVED,
413 content::Source<Profile>(profile_),
414 content::Details<BrowsingDataRemover::NotificationDetails>(&details));
415
initial.commit09911bf2008-07-26 23:55:29416 FOR_EACH_OBSERVER(Observer, observer_list_, OnBrowsingDataRemoverDone());
417
418 // History requests aren't happy if you delete yourself from the callback.
419 // As such, we do a delete later.
420 MessageLoop::current()->DeleteSoon(FROM_HERE, this);
421}
422
[email protected]d6f37fc2011-02-13 23:58:41423void BrowsingDataRemover::ClearedNetworkHistory() {
[email protected]df2840d2011-02-20 16:32:32424 waiting_for_clear_networking_history_ = false;
[email protected]d6f37fc2011-02-13 23:58:41425
426 NotifyAndDeleteIfDone();
427}
428
[email protected]df2840d2011-02-20 16:32:32429void BrowsingDataRemover::ClearNetworkingHistory(IOThread* io_thread) {
[email protected]d6f37fc2011-02-13 23:58:41430 // This function should be called on the IO thread.
431 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
432
[email protected]67372ecf2011-09-10 01:30:46433 io_thread->ClearHostCache();
434
435 chrome_browser_net::Predictor* predictor = profile_->GetNetworkPredictor();
436 if (predictor) {
437 predictor->DiscardInitialNavigationHistory();
438 predictor->DiscardAllResults();
439 }
[email protected]d6f37fc2011-02-13 23:58:41440
441 // Notify the UI thread that we are done.
442 BrowserThread::PostTask(
443 BrowserThread::UI, FROM_HERE,
[email protected]006284f02011-10-19 22:06:23444 base::Bind(&BrowsingDataRemover::ClearedNetworkHistory,
445 base::Unretained(this)));
[email protected]d6f37fc2011-02-13 23:58:41446}
447
initial.commit09911bf2008-07-26 23:55:29448void BrowsingDataRemover::ClearedCache() {
449 waiting_for_clear_cache_ = false;
450
451 NotifyAndDeleteIfDone();
452}
453
[email protected]d885bfe2010-05-21 18:29:45454void BrowsingDataRemover::ClearCacheOnIOThread() {
initial.commit09911bf2008-07-26 23:55:29455 // This function should be called on the IO thread.
[email protected]d04e7662010-10-10 22:24:48456 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]d885bfe2010-05-21 18:29:45457 DCHECK_EQ(STATE_NONE, next_cache_state_);
458 DCHECK(main_context_getter_);
459 DCHECK(media_context_getter_);
initial.commit09911bf2008-07-26 23:55:29460
[email protected]d885bfe2010-05-21 18:29:45461 next_cache_state_ = STATE_CREATE_MAIN;
462 DoClearCache(net::OK);
463}
initial.commit09911bf2008-07-26 23:55:29464
[email protected]d885bfe2010-05-21 18:29:45465// The expected state sequence is STATE_NONE --> STATE_CREATE_MAIN -->
466// STATE_DELETE_MAIN --> STATE_CREATE_MEDIA --> STATE_DELETE_MEDIA -->
467// STATE_DONE, and any errors are ignored.
468void BrowsingDataRemover::DoClearCache(int rv) {
469 DCHECK_NE(STATE_NONE, next_cache_state_);
470
471 while (rv != net::ERR_IO_PENDING && next_cache_state_ != STATE_NONE) {
472 switch (next_cache_state_) {
473 case STATE_CREATE_MAIN:
474 case STATE_CREATE_MEDIA: {
475 // Get a pointer to the cache.
[email protected]abe2c032011-03-31 18:49:34476 net::URLRequestContextGetter* getter =
[email protected]d885bfe2010-05-21 18:29:45477 (next_cache_state_ == STATE_CREATE_MAIN) ?
478 main_context_getter_ : media_context_getter_;
479 net::HttpTransactionFactory* factory =
480 getter->GetURLRequestContext()->http_transaction_factory();
481
[email protected]2a65aceb82011-12-19 20:59:27482 rv = factory->GetCache()->GetBackend(
483 &cache_, base::Bind(&BrowsingDataRemover::DoClearCache,
484 base::Unretained(this)));
[email protected]d885bfe2010-05-21 18:29:45485 next_cache_state_ = (next_cache_state_ == STATE_CREATE_MAIN) ?
486 STATE_DELETE_MAIN : STATE_DELETE_MEDIA;
487 break;
488 }
489 case STATE_DELETE_MAIN:
490 case STATE_DELETE_MEDIA: {
491 // |cache_| can be null if it cannot be initialized.
492 if (cache_) {
493 if (delete_begin_.is_null()) {
[email protected]6ad7c0912011-12-15 19:10:19494 rv = cache_->DoomAllEntries(
495 base::Bind(&BrowsingDataRemover::DoClearCache,
496 base::Unretained(this)));
[email protected]d885bfe2010-05-21 18:29:45497 } else {
[email protected]6ad7c0912011-12-15 19:10:19498 rv = cache_->DoomEntriesBetween(
499 delete_begin_, delete_end_,
500 base::Bind(&BrowsingDataRemover::DoClearCache,
501 base::Unretained(this)));
[email protected]d885bfe2010-05-21 18:29:45502 }
503 cache_ = NULL;
504 }
505 next_cache_state_ = (next_cache_state_ == STATE_DELETE_MAIN) ?
506 STATE_CREATE_MEDIA : STATE_DONE;
507 break;
508 }
509 case STATE_DONE: {
[email protected]d885bfe2010-05-21 18:29:45510 cache_ = NULL;
511
512 // Notify the UI thread that we are done.
[email protected]d04e7662010-10-10 22:24:48513 BrowserThread::PostTask(
514 BrowserThread::UI, FROM_HERE,
[email protected]006284f02011-10-19 22:06:23515 base::Bind(&BrowsingDataRemover::ClearedCache,
516 base::Unretained(this)));
[email protected]d885bfe2010-05-21 18:29:45517
518 next_cache_state_ = STATE_NONE;
519 break;
520 }
521 default: {
522 NOTREACHED() << "bad state";
523 next_cache_state_ = STATE_NONE; // Stop looping.
524 break;
525 }
526 }
[email protected]6828b592009-10-14 19:09:10527 }
initial.commit09911bf2008-07-26 23:55:29528}
[email protected]72cfd90f2010-02-06 03:08:04529
[email protected]94704172011-08-01 16:23:40530void BrowsingDataRemover::ClearQuotaManagedDataOnIOThread() {
[email protected]d04e7662010-10-10 22:24:48531 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]d68a4fc62010-03-05 23:40:02532
[email protected]94704172011-08-01 16:23:40533 // Ask the QuotaManager for all origins with temporary quota modified within
534 // the user-specified timeframe, and deal with the resulting set in
535 // OnGotQuotaManagedOrigins().
536 quota_managed_origins_to_delete_count_ = 0;
537 quota_managed_storage_types_to_delete_count_ = 2;
[email protected]d68a4fc62010-03-05 23:40:02538
[email protected]94704172011-08-01 16:23:40539 if (delete_begin_ == base::Time()) {
540 // If we're deleting since the beginning of time, ask the QuotaManager for
541 // all origins with persistent quota modified within the user-specified
542 // timeframe, and deal with the resulting set in
543 // OnGotPersistentQuotaManagedOrigins.
544 profile_->GetQuotaManager()->GetOriginsModifiedSince(
[email protected]4d99be52011-10-18 14:11:03545 quota::kStorageTypePersistent, delete_begin_,
546 base::Bind(&BrowsingDataRemover::OnGotQuotaManagedOrigins,
547 base::Unretained(this)));
[email protected]94704172011-08-01 16:23:40548 } else {
549 // Otherwise, we don't need to deal with persistent storage.
550 --quota_managed_storage_types_to_delete_count_;
[email protected]d68a4fc62010-03-05 23:40:02551 }
552
[email protected]94704172011-08-01 16:23:40553 // Do the same for temporary quota, regardless, passing the resulting set into
554 // OnGotTemporaryQuotaManagedOrigins.
555 profile_->GetQuotaManager()->GetOriginsModifiedSince(
[email protected]4d99be52011-10-18 14:11:03556 quota::kStorageTypeTemporary, delete_begin_,
557 base::Bind(&BrowsingDataRemover::OnGotQuotaManagedOrigins,
558 base::Unretained(this)));
[email protected]d68a4fc62010-03-05 23:40:02559}
560
[email protected]4ac23ad22011-08-05 08:39:54561void BrowsingDataRemover::OnGotQuotaManagedOrigins(
562 const std::set<GURL>& origins, quota::StorageType type) {
[email protected]94704172011-08-01 16:23:40563 DCHECK_GT(quota_managed_storage_types_to_delete_count_, 0);
[email protected]4ac23ad22011-08-05 08:39:54564 // Walk through the origins passed in, delete quota of |type| from each that
[email protected]94704172011-08-01 16:23:40565 // isn't protected.
566 std::set<GURL>::const_iterator origin;
567 for (origin = origins.begin(); origin != origins.end(); ++origin) {
568 if (special_storage_policy_->IsStorageProtected(origin->GetOrigin()))
[email protected]cdba46992011-06-07 11:51:39569 continue;
[email protected]94704172011-08-01 16:23:40570 ++quota_managed_origins_to_delete_count_;
[email protected]4d99be52011-10-18 14:11:03571 quota_manager_->DeleteOriginData(
572 origin->GetOrigin(), type,
573 base::Bind(&BrowsingDataRemover::OnQuotaManagedOriginDeletion,
574 base::Unretained(this)));
[email protected]94704172011-08-01 16:23:40575 }
576
577 --quota_managed_storage_types_to_delete_count_;
[email protected]dcdf7a712011-09-06 11:46:17578 CheckQuotaManagedDataDeletionStatus();
[email protected]94704172011-08-01 16:23:40579}
580
581void BrowsingDataRemover::OnQuotaManagedOriginDeletion(
582 quota::QuotaStatusCode status) {
583 DCHECK_GT(quota_managed_origins_to_delete_count_, 0);
584 if (status != quota::kQuotaStatusOk) {
585 // TODO(mkwst): We should add the GURL to StatusCallback; this is a pretty
586 // worthless error message otherwise.
587 DLOG(ERROR) << "Couldn't remove origin. Status: " << status;
588 }
589
590 --quota_managed_origins_to_delete_count_;
[email protected]dcdf7a712011-09-06 11:46:17591 CheckQuotaManagedDataDeletionStatus();
[email protected]94704172011-08-01 16:23:40592}
593
594void BrowsingDataRemover::CheckQuotaManagedDataDeletionStatus() {
[email protected]dcdf7a712011-09-06 11:46:17595 if (quota_managed_storage_types_to_delete_count_ != 0 ||
596 quota_managed_origins_to_delete_count_ != 0) {
597 return;
598 }
[email protected]94704172011-08-01 16:23:40599
[email protected]cdba46992011-06-07 11:51:39600 BrowserThread::PostTask(
601 BrowserThread::UI, FROM_HERE,
[email protected]006284f02011-10-19 22:06:23602 base::Bind(&BrowsingDataRemover::OnQuotaManagedDataDeleted,
603 base::Unretained(this)));
[email protected]dcdf7a712011-09-06 11:46:17604}
605
606void BrowsingDataRemover::OnQuotaManagedDataDeleted() {
607 DCHECK(waiting_for_clear_quota_managed_data_);
608 waiting_for_clear_quota_managed_data_ = false;
609 NotifyAndDeleteIfDone();
[email protected]6ccb5e52011-05-19 23:36:25610}
611
[email protected]c7d58d62011-01-21 10:27:18612void BrowsingDataRemover::OnWaitableEventSignaled(
613 base::WaitableEvent* waitable_event) {
[email protected]59eca0f2011-12-13 19:16:39614 waiting_for_clear_plugin_data_ = false;
[email protected]09d81f82010-12-15 16:46:42615 NotifyAndDeleteIfDone();
616}
[email protected]ade9abe2011-09-02 17:29:12617
618void BrowsingDataRemover::OnClearedCookies(int num_deleted) {
619 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
620 BrowserThread::PostTask(
621 BrowserThread::UI, FROM_HERE,
622 base::Bind(&BrowsingDataRemover::OnClearedCookies,
623 base::Unretained(this), num_deleted));
624 return;
625 }
626
627 waiting_for_clear_cookies_ = false;
628 NotifyAndDeleteIfDone();
629}
630
631void BrowsingDataRemover::ClearCookiesOnIOThread(
632 net::URLRequestContextGetter* rq_context) {
633 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]b236b7d2011-12-21 09:06:26634 net::CookieStore* cookie_store = rq_context->
635 GetURLRequestContext()->cookie_store();
636 cookie_store->DeleteAllCreatedBetweenAsync(
637 delete_begin_, delete_end_,
638 base::Bind(&BrowsingDataRemover::OnClearedCookies,
639 base::Unretained(this)));
[email protected]ade9abe2011-09-02 17:29:12640}
[email protected]eb7974c2012-01-25 17:38:48641
642void BrowsingDataRemover::ClearOriginBoundCertsOnIOThread(
643 net::URLRequestContextGetter* rq_context) {
644 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
645 net::OriginBoundCertService* origin_bound_cert_service =
646 rq_context->GetURLRequestContext()->origin_bound_cert_service();
647 origin_bound_cert_service->GetCertStore()->DeleteAllCreatedBetween(
648 delete_begin_, delete_end_);
649 BrowserThread::PostTask(
650 BrowserThread::UI, FROM_HERE,
651 base::Bind(&BrowsingDataRemover::OnClearedOriginBoundCerts,
652 base::Unretained(this)));
653}
654
655void BrowsingDataRemover::OnClearedOriginBoundCerts() {
656 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
657 waiting_for_clear_origin_bound_certs_ = false;
658 NotifyAndDeleteIfDone();
659}