Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: chrome/browser/browsing_data_remover.cc

Issue 10805015: Move browsing_data_helper files into a separate directory. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix chrome_frame build Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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_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/file_util.h"
14 #include "base/logging.h"
15 #include "base/platform_file.h"
16 #include "chrome/browser/autofill/personal_data_manager.h"
17 #include "chrome/browser/autofill/personal_data_manager_factory.h"
18 #include "chrome/browser/browser_process.h"
19 #include "chrome/browser/browsing_data_helper.h"
20 #include "chrome/browser/download/download_service.h"
21 #include "chrome/browser/download/download_service_factory.h"
22 #include "chrome/browser/extensions/extension_service.h"
23 #include "chrome/browser/extensions/extension_special_storage_policy.h"
24 #include "chrome/browser/history/history.h"
25 #include "chrome/browser/history/history_service_factory.h"
26 #include "chrome/browser/io_thread.h"
27 #include "chrome/browser/nacl_host/nacl_browser.h"
28 #include "chrome/browser/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"
32 #include "chrome/browser/prefs/pref_member.h"
33 #include "chrome/browser/prerender/prerender_manager.h"
34 #include "chrome/browser/prerender/prerender_manager_factory.h"
35 #include "chrome/browser/profiles/profile.h"
36 #include "chrome/browser/renderer_host/web_cache_manager.h"
37 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
38 #include "chrome/browser/search_engines/template_url_service.h"
39 #include "chrome/browser/search_engines/template_url_service_factory.h"
40 #include "chrome/browser/sessions/session_service.h"
41 #include "chrome/browser/sessions/session_service_factory.h"
42 #include "chrome/browser/sessions/tab_restore_service.h"
43 #include "chrome/browser/sessions/tab_restore_service_factory.h"
44 #include "chrome/browser/webdata/web_data_service.h"
45 #include "chrome/browser/webdata/web_data_service_factory.h"
46 #include "chrome/common/chrome_notification_types.h"
47 #include "chrome/common/pref_names.h"
48 #include "chrome/common/url_constants.h"
49 #include "content/public/browser/browser_thread.h"
50 #include "content/public/browser/dom_storage_context.h"
51 #include "content/public/browser/download_manager.h"
52 #include "content/public/browser/notification_service.h"
53 #include "content/public/browser/plugin_data_remover.h"
54 #include "content/public/browser/user_metrics.h"
55 #include "net/base/net_errors.h"
56 #include "net/base/server_bound_cert_service.h"
57 #include "net/base/server_bound_cert_store.h"
58 #include "net/base/transport_security_state.h"
59 #include "net/cookies/cookie_store.h"
60 #include "net/disk_cache/disk_cache.h"
61 #include "net/http/http_cache.h"
62 #include "net/url_request/url_request_context.h"
63 #include "net/url_request/url_request_context_getter.h"
64 #include "webkit/dom_storage/dom_storage_context.h"
65 #include "webkit/quota/quota_manager.h"
66 #include "webkit/quota/quota_types.h"
67 #include "webkit/quota/special_storage_policy.h"
68
69 using content::BrowserContext;
70 using content::BrowserThread;
71 using content::DOMStorageContext;
72 using content::DownloadManager;
73 using content::UserMetricsAction;
74
75 bool BrowsingDataRemover::removing_ = false;
76
77 BrowsingDataRemover::NotificationDetails::NotificationDetails()
78 : removal_begin(base::Time()),
79 removal_mask(-1),
80 origin_set_mask(-1) {
81 }
82
83 BrowsingDataRemover::NotificationDetails::NotificationDetails(
84 const BrowsingDataRemover::NotificationDetails& details)
85 : removal_begin(details.removal_begin),
86 removal_mask(details.removal_mask),
87 origin_set_mask(details.origin_set_mask) {
88 }
89
90 BrowsingDataRemover::NotificationDetails::NotificationDetails(
91 base::Time removal_begin,
92 int removal_mask,
93 int origin_set_mask)
94 : removal_begin(removal_begin),
95 removal_mask(removal_mask),
96 origin_set_mask(origin_set_mask) {
97 }
98
99 BrowsingDataRemover::NotificationDetails::~NotificationDetails() {}
100
101 // TODO(mkwst): We should have one constructor, not two. http://crbug.com/130732
102 BrowsingDataRemover::BrowsingDataRemover(Profile* profile,
103 base::Time delete_begin,
104 base::Time delete_end)
105 : profile_(profile),
106 quota_manager_(NULL),
107 dom_storage_context_(NULL),
108 special_storage_policy_(profile->GetExtensionSpecialStoragePolicy()),
109 delete_begin_(delete_begin),
110 delete_end_(delete_end),
111 next_cache_state_(STATE_NONE),
112 cache_(NULL),
113 main_context_getter_(profile->GetRequestContext()),
114 media_context_getter_(profile->GetRequestContextForMedia()),
115 deauthorize_content_licenses_request_id_(0),
116 waiting_for_clear_cache_(false),
117 waiting_for_clear_nacl_cache_(false),
118 waiting_for_clear_cookies_count_(0),
119 waiting_for_clear_history_(false),
120 waiting_for_clear_local_storage_(false),
121 waiting_for_clear_networking_history_(false),
122 waiting_for_clear_server_bound_certs_(false),
123 waiting_for_clear_plugin_data_(false),
124 waiting_for_clear_quota_managed_data_(false),
125 waiting_for_clear_content_licenses_(false),
126 remove_mask_(0),
127 remove_origin_(GURL()),
128 origin_set_mask_(0) {
129 DCHECK(profile);
130 }
131
132 BrowsingDataRemover::BrowsingDataRemover(Profile* profile,
133 TimePeriod time_period,
134 base::Time delete_end)
135 : profile_(profile),
136 quota_manager_(NULL),
137 dom_storage_context_(NULL),
138 special_storage_policy_(profile->GetExtensionSpecialStoragePolicy()),
139 delete_begin_(CalculateBeginDeleteTime(time_period)),
140 delete_end_(delete_end),
141 next_cache_state_(STATE_NONE),
142 cache_(NULL),
143 main_context_getter_(profile->GetRequestContext()),
144 media_context_getter_(profile->GetRequestContextForMedia()),
145 deauthorize_content_licenses_request_id_(0),
146 waiting_for_clear_cache_(false),
147 waiting_for_clear_nacl_cache_(false),
148 waiting_for_clear_cookies_count_(0),
149 waiting_for_clear_history_(false),
150 waiting_for_clear_local_storage_(false),
151 waiting_for_clear_networking_history_(false),
152 waiting_for_clear_server_bound_certs_(false),
153 waiting_for_clear_plugin_data_(false),
154 waiting_for_clear_quota_managed_data_(false),
155 waiting_for_clear_content_licenses_(false),
156 remove_mask_(0),
157 remove_origin_(GURL()),
158 origin_set_mask_(0) {
159 DCHECK(profile);
160 }
161
162 BrowsingDataRemover::~BrowsingDataRemover() {
163 DCHECK(AllDone());
164 }
165
166 // Static.
167 void BrowsingDataRemover::set_removing(bool removing) {
168 DCHECK(removing_ != removing);
169 removing_ = removing;
170 }
171
172 // Static.
173 int BrowsingDataRemover::GenerateQuotaClientMask(int remove_mask) {
174 int quota_client_mask = 0;
175 if (remove_mask & BrowsingDataRemover::REMOVE_FILE_SYSTEMS)
176 quota_client_mask |= quota::QuotaClient::kFileSystem;
177 if (remove_mask & BrowsingDataRemover::REMOVE_WEBSQL)
178 quota_client_mask |= quota::QuotaClient::kDatabase;
179 if (remove_mask & BrowsingDataRemover::REMOVE_APPCACHE)
180 quota_client_mask |= quota::QuotaClient::kAppcache;
181 if (remove_mask & BrowsingDataRemover::REMOVE_INDEXEDDB)
182 quota_client_mask |= quota::QuotaClient::kIndexedDatabase;
183
184 return quota_client_mask;
185 }
186
187 void BrowsingDataRemover::Remove(int remove_mask, int origin_set_mask) {
188 RemoveImpl(remove_mask, GURL(), origin_set_mask);
189 }
190
191 void BrowsingDataRemover::RemoveImpl(int remove_mask,
192 const GURL& origin,
193 int origin_set_mask) {
194 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
195 set_removing(true);
196 remove_mask_ = remove_mask;
197 remove_origin_ = origin;
198 origin_set_mask_ = origin_set_mask;
199
200 if (origin_set_mask_ & BrowsingDataHelper::UNPROTECTED_WEB) {
201 content::RecordAction(
202 UserMetricsAction("ClearBrowsingData_MaskContainsUnprotectedWeb"));
203 }
204 if (origin_set_mask_ & BrowsingDataHelper::PROTECTED_WEB) {
205 content::RecordAction(
206 UserMetricsAction("ClearBrowsingData_MaskContainsProtectedWeb"));
207 }
208 if (origin_set_mask_ & BrowsingDataHelper::EXTENSION) {
209 content::RecordAction(
210 UserMetricsAction("ClearBrowsingData_MaskContainsExtension"));
211 }
212 // If this fires, we added a new BrowsingDataHelper::OriginSetMask without
213 // updating the user metrics above.
214 COMPILE_ASSERT(
215 BrowsingDataHelper::ALL == (BrowsingDataHelper::UNPROTECTED_WEB |
216 BrowsingDataHelper::PROTECTED_WEB |
217 BrowsingDataHelper::EXTENSION),
218 forgotten_to_add_origin_mask_type);
219
220 if (remove_mask & REMOVE_HISTORY) {
221 HistoryService* history_service = HistoryServiceFactory::GetForProfile(
222 profile_, Profile::EXPLICIT_ACCESS);
223 if (history_service) {
224 std::set<GURL> restrict_urls;
225 if (!remove_origin_.is_empty())
226 restrict_urls.insert(remove_origin_);
227 content::RecordAction(UserMetricsAction("ClearBrowsingData_History"));
228 waiting_for_clear_history_ = true;
229 history_service->ExpireHistoryBetween(restrict_urls,
230 delete_begin_, delete_end_,
231 &request_consumer_,
232 base::Bind(&BrowsingDataRemover::OnHistoryDeletionDone,
233 base::Unretained(this)));
234 }
235
236 // Need to clear the host cache and accumulated speculative data, as it also
237 // reveals some history: we have no mechanism to track when these items were
238 // created, so we'll clear them all. Better safe than sorry.
239 if (g_browser_process->io_thread()) {
240 waiting_for_clear_networking_history_ = true;
241 BrowserThread::PostTask(
242 BrowserThread::IO, FROM_HERE,
243 base::Bind(&BrowsingDataRemover::ClearNetworkingHistory,
244 base::Unretained(this), g_browser_process->io_thread()));
245 }
246
247 // As part of history deletion we also delete the auto-generated keywords.
248 TemplateURLService* keywords_model =
249 TemplateURLServiceFactory::GetForProfile(profile_);
250 if (keywords_model && !keywords_model->loaded()) {
251 registrar_.Add(this, chrome::NOTIFICATION_TEMPLATE_URL_SERVICE_LOADED,
252 content::Source<TemplateURLService>(keywords_model));
253 keywords_model->Load();
254 } else if (keywords_model) {
255 keywords_model->RemoveAutoGeneratedForOriginBetween(remove_origin_,
256 delete_begin_, delete_end_);
257 }
258
259 // The PrerenderManager keeps history of prerendered pages, so clear that.
260 // It also may have a prerendered page. If so, the page could be
261 // considered to have a small amount of historical information, so delete
262 // it, too.
263 prerender::PrerenderManager* prerender_manager =
264 prerender::PrerenderManagerFactory::GetForProfile(profile_);
265 if (prerender_manager) {
266 prerender_manager->ClearData(
267 prerender::PrerenderManager::CLEAR_PRERENDER_CONTENTS |
268 prerender::PrerenderManager::CLEAR_PRERENDER_HISTORY);
269 }
270
271 // If the caller is removing history for all hosts, then clear ancillary
272 // historical information.
273 if (remove_origin_.is_empty()) {
274 // We also delete the list of recently closed tabs. Since these expire,
275 // they can't be more than a day old, so we can simply clear them all.
276 TabRestoreService* tab_service =
277 TabRestoreServiceFactory::GetForProfile(profile_);
278 if (tab_service) {
279 tab_service->ClearEntries();
280 tab_service->DeleteLastSession();
281 }
282
283 #if defined(ENABLE_SESSION_SERVICE)
284 // We also delete the last session when we delete the history.
285 SessionService* session_service =
286 SessionServiceFactory::GetForProfile(profile_);
287 if (session_service)
288 session_service->DeleteLastSession();
289 #endif
290 }
291 }
292
293 if (remove_mask & REMOVE_DOWNLOADS) {
294 content::RecordAction(UserMetricsAction("ClearBrowsingData_Downloads"));
295 DownloadManager* download_manager =
296 BrowserContext::GetDownloadManager(profile_);
297 download_manager->RemoveDownloadsBetween(delete_begin_, delete_end_);
298 download_manager->ClearLastDownloadPath();
299 }
300
301 // We ignore the REMOVE_COOKIES request if UNPROTECTED_WEB is not set,
302 // so that callers who request REMOVE_SITE_DATA with PROTECTED_WEB
303 // don't accidentally remove the cookies that are associated with the
304 // UNPROTECTED_WEB origin. This is necessary because cookies are not separated
305 // between UNPROTECTED_WEB and PROTECTED_WEB.
306 if (remove_mask & REMOVE_COOKIES &&
307 origin_set_mask_ & BrowsingDataHelper::UNPROTECTED_WEB) {
308 content::RecordAction(UserMetricsAction("ClearBrowsingData_Cookies"));
309 // Since we are running on the UI thread don't call GetURLRequestContext().
310 net::URLRequestContextGetter* rq_context = profile_->GetRequestContext();
311 if (rq_context) {
312 ++waiting_for_clear_cookies_count_;
313 BrowserThread::PostTask(
314 BrowserThread::IO, FROM_HERE,
315 base::Bind(&BrowsingDataRemover::ClearCookiesOnIOThread,
316 base::Unretained(this), base::Unretained(rq_context)));
317 }
318
319 #if defined(ENABLE_SAFE_BROWSING)
320 // Clear the safebrowsing cookies only if time period is for "all time". It
321 // doesn't make sense to apply the time period of deleting in the last X
322 // hours/days to the safebrowsing cookies since they aren't the result of
323 // any user action.
324 if (delete_begin_ == base::Time()) {
325 SafeBrowsingService* sb_service =
326 g_browser_process->safe_browsing_service();
327 if (sb_service) {
328 net::URLRequestContextGetter* sb_context =
329 sb_service->url_request_context();
330 ++waiting_for_clear_cookies_count_;
331 BrowserThread::PostTask(
332 BrowserThread::IO, FROM_HERE,
333 base::Bind(&BrowsingDataRemover::ClearCookiesOnIOThread,
334 base::Unretained(this), base::Unretained(sb_context)));
335 }
336 }
337 #endif
338 }
339
340 // Server bound certs are not separated for protected and unprotected web
341 // origins. We check the origin_set_mask_ to prevent unintended deletion.
342 if (remove_mask & REMOVE_SERVER_BOUND_CERTS &&
343 origin_set_mask_ & BrowsingDataHelper::UNPROTECTED_WEB) {
344 content::RecordAction(
345 UserMetricsAction("ClearBrowsingData_ServerBoundCerts"));
346 // Since we are running on the UI thread don't call GetURLRequestContext().
347 net::URLRequestContextGetter* rq_context = profile_->GetRequestContext();
348 if (rq_context) {
349 waiting_for_clear_server_bound_certs_ = true;
350 BrowserThread::PostTask(
351 BrowserThread::IO, FROM_HERE,
352 base::Bind(&BrowsingDataRemover::ClearServerBoundCertsOnIOThread,
353 base::Unretained(this), base::Unretained(rq_context)));
354 }
355 }
356
357 if (remove_mask & REMOVE_LOCAL_STORAGE) {
358 waiting_for_clear_local_storage_ = true;
359 if (!dom_storage_context_)
360 dom_storage_context_ =
361 BrowserContext::GetDefaultDOMStorageContext(profile_);
362 ClearLocalStorageOnUIThread();
363 }
364
365 if (remove_mask & REMOVE_INDEXEDDB || remove_mask & REMOVE_WEBSQL ||
366 remove_mask & REMOVE_APPCACHE || remove_mask & REMOVE_FILE_SYSTEMS) {
367 if (!quota_manager_)
368 quota_manager_ = content::BrowserContext::GetQuotaManager(profile_);
369 waiting_for_clear_quota_managed_data_ = true;
370 BrowserThread::PostTask(
371 BrowserThread::IO, FROM_HERE,
372 base::Bind(&BrowsingDataRemover::ClearQuotaManagedDataOnIOThread,
373 base::Unretained(this)));
374 }
375
376 // Plugin is data not separated for protected and unprotected web origins. We
377 // check the origin_set_mask_ to prevent unintended deletion.
378 if (remove_mask & REMOVE_PLUGIN_DATA &&
379 origin_set_mask_ & BrowsingDataHelper::UNPROTECTED_WEB) {
380 content::RecordAction(UserMetricsAction("ClearBrowsingData_LSOData"));
381
382 waiting_for_clear_plugin_data_ = true;
383 if (!plugin_data_remover_.get())
384 plugin_data_remover_.reset(content::PluginDataRemover::Create(profile_));
385 base::WaitableEvent* event =
386 plugin_data_remover_->StartRemoving(delete_begin_);
387 watcher_.StartWatching(event, this);
388 }
389
390 if (remove_mask & REMOVE_PASSWORDS) {
391 content::RecordAction(UserMetricsAction("ClearBrowsingData_Passwords"));
392 PasswordStore* password_store = PasswordStoreFactory::GetForProfile(
393 profile_, Profile::EXPLICIT_ACCESS);
394
395 if (password_store)
396 password_store->RemoveLoginsCreatedBetween(delete_begin_, delete_end_);
397 }
398
399 if (remove_mask & REMOVE_FORM_DATA) {
400 content::RecordAction(UserMetricsAction("ClearBrowsingData_Autofill"));
401 scoped_refptr<WebDataService> web_data_service =
402 WebDataServiceFactory::GetForProfile(profile_,
403 Profile::EXPLICIT_ACCESS);
404
405 if (web_data_service.get()) {
406 web_data_service->RemoveFormElementsAddedBetween(delete_begin_,
407 delete_end_);
408 web_data_service->RemoveAutofillProfilesAndCreditCardsModifiedBetween(
409 delete_begin_, delete_end_);
410 PersonalDataManager* data_manager =
411 PersonalDataManagerFactory::GetForProfile(profile_);
412 if (data_manager) {
413 data_manager->Refresh();
414 }
415 }
416 }
417
418 if (remove_mask & REMOVE_CACHE) {
419 // Tell the renderers to clear their cache.
420 WebCacheManager::GetInstance()->ClearCache();
421
422 // Invoke DoClearCache on the IO thread.
423 waiting_for_clear_cache_ = true;
424 content::RecordAction(UserMetricsAction("ClearBrowsingData_Cache"));
425
426 BrowserThread::PostTask(
427 BrowserThread::IO, FROM_HERE,
428 base::Bind(&BrowsingDataRemover::ClearCacheOnIOThread,
429 base::Unretained(this)));
430
431 #if !defined(DISABLE_NACL)
432 waiting_for_clear_nacl_cache_ = true;
433
434 BrowserThread::PostTask(
435 BrowserThread::IO, FROM_HERE,
436 base::Bind(&BrowsingDataRemover::ClearNaClCacheOnIOThread,
437 base::Unretained(this)));
438 #endif
439
440 // The PrerenderManager may have a page actively being prerendered, which
441 // is essentially a preemptively cached page.
442 prerender::PrerenderManager* prerender_manager =
443 prerender::PrerenderManagerFactory::GetForProfile(profile_);
444 if (prerender_manager) {
445 prerender_manager->ClearData(
446 prerender::PrerenderManager::CLEAR_PRERENDER_CONTENTS);
447 }
448 }
449
450 if (remove_mask & REMOVE_CONTENT_LICENSES) {
451 content::RecordAction(
452 UserMetricsAction("ClearBrowsingData_ContentLicenses"));
453
454 waiting_for_clear_content_licenses_ = true;
455 if (!pepper_flash_settings_manager_.get()) {
456 pepper_flash_settings_manager_.reset(
457 new PepperFlashSettingsManager(this, profile_));
458 }
459 deauthorize_content_licenses_request_id_ =
460 pepper_flash_settings_manager_->DeauthorizeContentLicenses();
461 }
462
463 // Also delete cached network related data (like TransportSecurityState,
464 // HttpServerProperties data).
465 profile_->ClearNetworkingHistorySince(delete_begin_);
466
467 NotifyAndDeleteIfDone();
468 }
469
470 void BrowsingDataRemover::AddObserver(Observer* observer) {
471 observer_list_.AddObserver(observer);
472 }
473
474 void BrowsingDataRemover::RemoveObserver(Observer* observer) {
475 observer_list_.RemoveObserver(observer);
476 }
477
478 void BrowsingDataRemover::OnHistoryDeletionDone() {
479 waiting_for_clear_history_ = false;
480 NotifyAndDeleteIfDone();
481 }
482
483 void BrowsingDataRemover::OverrideQuotaManagerForTesting(
484 quota::QuotaManager* quota_manager) {
485 quota_manager_ = quota_manager;
486 }
487
488 base::Time BrowsingDataRemover::CalculateBeginDeleteTime(
489 TimePeriod time_period) {
490 base::TimeDelta diff;
491 base::Time delete_begin_time = base::Time::Now();
492 switch (time_period) {
493 case LAST_HOUR:
494 diff = base::TimeDelta::FromHours(1);
495 break;
496 case LAST_DAY:
497 diff = base::TimeDelta::FromHours(24);
498 break;
499 case LAST_WEEK:
500 diff = base::TimeDelta::FromHours(7*24);
501 break;
502 case FOUR_WEEKS:
503 diff = base::TimeDelta::FromHours(4*7*24);
504 break;
505 case EVERYTHING:
506 delete_begin_time = base::Time();
507 break;
508 default:
509 NOTREACHED() << L"Missing item";
510 break;
511 }
512 return delete_begin_time - diff;
513 }
514
515 bool BrowsingDataRemover::AllDone() {
516 return registrar_.IsEmpty() &&
517 !waiting_for_clear_cache_ &&
518 !waiting_for_clear_nacl_cache_ &&
519 !waiting_for_clear_cookies_count_&&
520 !waiting_for_clear_history_ &&
521 !waiting_for_clear_local_storage_ &&
522 !waiting_for_clear_networking_history_ &&
523 !waiting_for_clear_server_bound_certs_ &&
524 !waiting_for_clear_plugin_data_ &&
525 !waiting_for_clear_quota_managed_data_ &&
526 !waiting_for_clear_content_licenses_;
527 }
528
529 void BrowsingDataRemover::Observe(int type,
530 const content::NotificationSource& source,
531 const content::NotificationDetails& details) {
532 // TODO(brettw) bug 1139736: This should also observe session
533 // clearing (what about other things such as passwords, etc.?) and wait for
534 // them to complete before continuing.
535 DCHECK(type == chrome::NOTIFICATION_TEMPLATE_URL_SERVICE_LOADED);
536 TemplateURLService* model = content::Source<TemplateURLService>(source).ptr();
537 if (model->profile() == profile_) {
538 registrar_.RemoveAll();
539 model->RemoveAutoGeneratedBetween(delete_begin_, delete_end_);
540 NotifyAndDeleteIfDone();
541 }
542 }
543
544 void BrowsingDataRemover::NotifyAndDeleteIfDone() {
545 // TODO(brettw) bug 1139736: see TODO in Observe() above.
546 if (!AllDone())
547 return;
548
549 set_removing(false);
550
551 // Send global notification, then notify any explicit observers.
552 BrowsingDataRemover::NotificationDetails details(delete_begin_, remove_mask_,
553 origin_set_mask_);
554 content::NotificationService::current()->Notify(
555 chrome::NOTIFICATION_BROWSING_DATA_REMOVED,
556 content::Source<Profile>(profile_),
557 content::Details<BrowsingDataRemover::NotificationDetails>(&details));
558
559 FOR_EACH_OBSERVER(Observer, observer_list_, OnBrowsingDataRemoverDone());
560
561 // History requests aren't happy if you delete yourself from the callback.
562 // As such, we do a delete later.
563 MessageLoop::current()->DeleteSoon(FROM_HERE, this);
564 }
565
566 void BrowsingDataRemover::ClearedNetworkHistory() {
567 waiting_for_clear_networking_history_ = false;
568
569 NotifyAndDeleteIfDone();
570 }
571
572 void BrowsingDataRemover::ClearNetworkingHistory(IOThread* io_thread) {
573 // This function should be called on the IO thread.
574 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
575
576 io_thread->ClearHostCache();
577
578 chrome_browser_net::Predictor* predictor = profile_->GetNetworkPredictor();
579 if (predictor) {
580 predictor->DiscardInitialNavigationHistory();
581 predictor->DiscardAllResults();
582 }
583
584 // Notify the UI thread that we are done.
585 BrowserThread::PostTask(
586 BrowserThread::UI, FROM_HERE,
587 base::Bind(&BrowsingDataRemover::ClearedNetworkHistory,
588 base::Unretained(this)));
589 }
590
591 void BrowsingDataRemover::ClearedCache() {
592 waiting_for_clear_cache_ = false;
593
594 NotifyAndDeleteIfDone();
595 }
596
597 void BrowsingDataRemover::ClearCacheOnIOThread() {
598 // This function should be called on the IO thread.
599 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
600 DCHECK_EQ(STATE_NONE, next_cache_state_);
601 DCHECK(main_context_getter_);
602 DCHECK(media_context_getter_);
603
604 next_cache_state_ = STATE_CREATE_MAIN;
605 DoClearCache(net::OK);
606 }
607
608 // The expected state sequence is STATE_NONE --> STATE_CREATE_MAIN -->
609 // STATE_DELETE_MAIN --> STATE_CREATE_MEDIA --> STATE_DELETE_MEDIA -->
610 // STATE_DONE, and any errors are ignored.
611 void BrowsingDataRemover::DoClearCache(int rv) {
612 DCHECK_NE(STATE_NONE, next_cache_state_);
613
614 while (rv != net::ERR_IO_PENDING && next_cache_state_ != STATE_NONE) {
615 switch (next_cache_state_) {
616 case STATE_CREATE_MAIN:
617 case STATE_CREATE_MEDIA: {
618 // Get a pointer to the cache.
619 net::URLRequestContextGetter* getter =
620 (next_cache_state_ == STATE_CREATE_MAIN) ?
621 main_context_getter_ : media_context_getter_;
622 net::HttpTransactionFactory* factory =
623 getter->GetURLRequestContext()->http_transaction_factory();
624
625 rv = factory->GetCache()->GetBackend(
626 &cache_, base::Bind(&BrowsingDataRemover::DoClearCache,
627 base::Unretained(this)));
628 next_cache_state_ = (next_cache_state_ == STATE_CREATE_MAIN) ?
629 STATE_DELETE_MAIN : STATE_DELETE_MEDIA;
630 break;
631 }
632 case STATE_DELETE_MAIN:
633 case STATE_DELETE_MEDIA: {
634 // |cache_| can be null if it cannot be initialized.
635 if (cache_) {
636 if (delete_begin_.is_null()) {
637 rv = cache_->DoomAllEntries(
638 base::Bind(&BrowsingDataRemover::DoClearCache,
639 base::Unretained(this)));
640 } else {
641 rv = cache_->DoomEntriesBetween(
642 delete_begin_, delete_end_,
643 base::Bind(&BrowsingDataRemover::DoClearCache,
644 base::Unretained(this)));
645 }
646 cache_ = NULL;
647 }
648 next_cache_state_ = (next_cache_state_ == STATE_DELETE_MAIN) ?
649 STATE_CREATE_MEDIA : STATE_DONE;
650 break;
651 }
652 case STATE_DONE: {
653 cache_ = NULL;
654
655 // Notify the UI thread that we are done.
656 BrowserThread::PostTask(
657 BrowserThread::UI, FROM_HERE,
658 base::Bind(&BrowsingDataRemover::ClearedCache,
659 base::Unretained(this)));
660
661 next_cache_state_ = STATE_NONE;
662 break;
663 }
664 default: {
665 NOTREACHED() << "bad state";
666 next_cache_state_ = STATE_NONE; // Stop looping.
667 break;
668 }
669 }
670 }
671 }
672
673 #if !defined(DISABLE_NACL)
674 void BrowsingDataRemover::ClearedNaClCache() {
675 // This function should be called on the UI thread.
676 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
677
678 waiting_for_clear_nacl_cache_ = false;
679
680 NotifyAndDeleteIfDone();
681 }
682
683 void BrowsingDataRemover::ClearedNaClCacheOnIOThread() {
684 // This function should be called on the IO thread.
685 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
686
687 // Notify the UI thread that we are done.
688 BrowserThread::PostTask(
689 BrowserThread::UI, FROM_HERE,
690 base::Bind(&BrowsingDataRemover::ClearedNaClCache,
691 base::Unretained(this)));
692 }
693
694 void BrowsingDataRemover::ClearNaClCacheOnIOThread() {
695 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
696
697 NaClBrowser::GetInstance()->ClearValidationCache(
698 base::Bind(&BrowsingDataRemover::ClearedNaClCacheOnIOThread,
699 base::Unretained(this)));
700 }
701 #endif
702
703 void BrowsingDataRemover::ClearLocalStorageOnUIThread() {
704 DCHECK(waiting_for_clear_local_storage_);
705
706 dom_storage_context_->GetUsageInfo(
707 base::Bind(&BrowsingDataRemover::OnGotLocalStorageUsageInfo,
708 base::Unretained(this)));
709 }
710
711 void BrowsingDataRemover::OnGotLocalStorageUsageInfo(
712 const std::vector<dom_storage::DomStorageContext::UsageInfo>& infos) {
713 DCHECK(waiting_for_clear_local_storage_);
714
715 for (size_t i = 0; i < infos.size(); ++i) {
716 if (!BrowsingDataHelper::DoesOriginMatchMask(infos[i].origin,
717 origin_set_mask_,
718 special_storage_policy_))
719 continue;
720
721 if (infos[i].last_modified >= delete_begin_ &&
722 infos[i].last_modified <= delete_end_)
723 dom_storage_context_->DeleteOrigin(infos[i].origin);
724 }
725 BrowserThread::PostTask(
726 BrowserThread::UI, FROM_HERE,
727 base::Bind(&BrowsingDataRemover::OnLocalStorageCleared,
728 base::Unretained(this)));
729 }
730
731 void BrowsingDataRemover::OnLocalStorageCleared() {
732 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
733 DCHECK(waiting_for_clear_local_storage_);
734 waiting_for_clear_local_storage_ = false;
735 NotifyAndDeleteIfDone();
736 }
737
738 void BrowsingDataRemover::ClearQuotaManagedDataOnIOThread() {
739 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
740
741 // Ask the QuotaManager for all origins with temporary quota modified within
742 // the user-specified timeframe, and deal with the resulting set in
743 // OnGotQuotaManagedOrigins().
744 quota_managed_origins_to_delete_count_ = 0;
745 quota_managed_storage_types_to_delete_count_ = 0;
746
747 if (delete_begin_ == base::Time() ||
748 origin_set_mask_ &
749 (BrowsingDataHelper::PROTECTED_WEB | BrowsingDataHelper::EXTENSION)) {
750 // If we're deleting since the beginning of time, or we're removing
751 // protected origins, then ask the QuotaManager for all origins with
752 // persistent quota modified within the user-specified timeframe, and deal
753 // with the resulting set in OnGotQuotaManagedOrigins.
754 ++quota_managed_storage_types_to_delete_count_;
755 quota_manager_->GetOriginsModifiedSince(
756 quota::kStorageTypePersistent, delete_begin_,
757 base::Bind(&BrowsingDataRemover::OnGotQuotaManagedOrigins,
758 base::Unretained(this)));
759 }
760
761 // Do the same for temporary quota.
762 ++quota_managed_storage_types_to_delete_count_;
763 quota_manager_->GetOriginsModifiedSince(
764 quota::kStorageTypeTemporary, delete_begin_,
765 base::Bind(&BrowsingDataRemover::OnGotQuotaManagedOrigins,
766 base::Unretained(this)));
767 }
768
769 void BrowsingDataRemover::OnGotQuotaManagedOrigins(
770 const std::set<GURL>& origins, quota::StorageType type) {
771 DCHECK_GT(quota_managed_storage_types_to_delete_count_, 0);
772 // Walk through the origins passed in, delete quota of |type| from each that
773 // matches the |origin_set_mask_|.
774 std::set<GURL>::const_iterator origin;
775 for (origin = origins.begin(); origin != origins.end(); ++origin) {
776 // TODO(mkwst): Clean this up, it's slow. http://crbug.com/130746
777 if (!remove_origin_.is_empty() && remove_origin_ != origin->GetOrigin())
778 continue;
779
780 if (!BrowsingDataHelper::DoesOriginMatchMask(origin->GetOrigin(),
781 origin_set_mask_,
782 special_storage_policy_))
783 continue;
784
785 ++quota_managed_origins_to_delete_count_;
786 quota_manager_->DeleteOriginData(
787 origin->GetOrigin(), type,
788 BrowsingDataRemover::GenerateQuotaClientMask(remove_mask_),
789 base::Bind(&BrowsingDataRemover::OnQuotaManagedOriginDeletion,
790 base::Unretained(this), origin->GetOrigin(), type));
791 }
792
793 --quota_managed_storage_types_to_delete_count_;
794 CheckQuotaManagedDataDeletionStatus();
795 }
796
797 void BrowsingDataRemover::OnQuotaManagedOriginDeletion(
798 const GURL& origin,
799 quota::StorageType type,
800 quota::QuotaStatusCode status) {
801 DCHECK_GT(quota_managed_origins_to_delete_count_, 0);
802 if (status != quota::kQuotaStatusOk) {
803 DLOG(ERROR) << "Couldn't remove data of type " << type << " for origin "
804 << origin << ". Status: " << status;
805 }
806
807 --quota_managed_origins_to_delete_count_;
808 CheckQuotaManagedDataDeletionStatus();
809 }
810
811 void BrowsingDataRemover::CheckQuotaManagedDataDeletionStatus() {
812 if (quota_managed_storage_types_to_delete_count_ != 0 ||
813 quota_managed_origins_to_delete_count_ != 0) {
814 return;
815 }
816
817 BrowserThread::PostTask(
818 BrowserThread::UI, FROM_HERE,
819 base::Bind(&BrowsingDataRemover::OnQuotaManagedDataDeleted,
820 base::Unretained(this)));
821 }
822
823 void BrowsingDataRemover::OnQuotaManagedDataDeleted() {
824 DCHECK(waiting_for_clear_quota_managed_data_);
825 waiting_for_clear_quota_managed_data_ = false;
826 NotifyAndDeleteIfDone();
827 }
828
829 void BrowsingDataRemover::OnWaitableEventSignaled(
830 base::WaitableEvent* waitable_event) {
831 waiting_for_clear_plugin_data_ = false;
832 NotifyAndDeleteIfDone();
833 }
834
835 void BrowsingDataRemover::OnDeauthorizeContentLicensesCompleted(
836 uint32 request_id,
837 bool /* success */) {
838 DCHECK(waiting_for_clear_content_licenses_);
839 DCHECK_EQ(request_id, deauthorize_content_licenses_request_id_);
840
841 waiting_for_clear_content_licenses_ = false;
842 NotifyAndDeleteIfDone();
843 }
844
845 void BrowsingDataRemover::OnClearedCookies(int num_deleted) {
846 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
847 BrowserThread::PostTask(
848 BrowserThread::UI, FROM_HERE,
849 base::Bind(&BrowsingDataRemover::OnClearedCookies,
850 base::Unretained(this), num_deleted));
851 return;
852 }
853
854 DCHECK(waiting_for_clear_cookies_count_ > 0);
855 --waiting_for_clear_cookies_count_;
856 NotifyAndDeleteIfDone();
857 }
858
859 void BrowsingDataRemover::ClearCookiesOnIOThread(
860 net::URLRequestContextGetter* rq_context) {
861 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
862 net::CookieStore* cookie_store = rq_context->
863 GetURLRequestContext()->cookie_store();
864 cookie_store->DeleteAllCreatedBetweenAsync(
865 delete_begin_, delete_end_,
866 base::Bind(&BrowsingDataRemover::OnClearedCookies,
867 base::Unretained(this)));
868 }
869
870 void BrowsingDataRemover::ClearServerBoundCertsOnIOThread(
871 net::URLRequestContextGetter* rq_context) {
872 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
873 net::ServerBoundCertService* server_bound_cert_service =
874 rq_context->GetURLRequestContext()->server_bound_cert_service();
875 server_bound_cert_service->GetCertStore()->DeleteAllCreatedBetween(
876 delete_begin_, delete_end_);
877 BrowserThread::PostTask(
878 BrowserThread::UI, FROM_HERE,
879 base::Bind(&BrowsingDataRemover::OnClearedServerBoundCerts,
880 base::Unretained(this)));
881 }
882
883 void BrowsingDataRemover::OnClearedServerBoundCerts() {
884 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
885 waiting_for_clear_server_bound_certs_ = false;
886 NotifyAndDeleteIfDone();
887 }
OLDNEW
« no previous file with comments | « chrome/browser/browsing_data_remover.h ('k') | chrome/browser/browsing_data_remover_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698