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