OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.
h" | 5 #include "chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.
h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <vector> |
8 | 9 |
9 #include "base/macros.h" | 10 #include "base/macros.h" |
10 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
11 #include "base/metrics/histogram_macros.h" | 12 #include "base/metrics/histogram_macros.h" |
12 #include "base/metrics/sparse_histogram.h" | 13 #include "base/metrics/sparse_histogram.h" |
| 14 #include "base/values.h" |
13 #include "chrome/browser/browsing_data/browsing_data_counter_factory.h" | 15 #include "chrome/browser/browsing_data/browsing_data_counter_factory.h" |
14 #include "chrome/browser/browsing_data/browsing_data_counter_utils.h" | 16 #include "chrome/browser/browsing_data/browsing_data_counter_utils.h" |
15 #include "chrome/browser/browsing_data/browsing_data_helper.h" | 17 #include "chrome/browser/browsing_data/browsing_data_helper.h" |
| 18 #include "chrome/browser/browsing_data/browsing_data_important_sites_util.h" |
16 #include "chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h" | 19 #include "chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h" |
| 20 #include "chrome/browser/engagement/important_sites_util.h" |
17 #include "chrome/browser/history/web_history_service_factory.h" | 21 #include "chrome/browser/history/web_history_service_factory.h" |
18 #include "chrome/browser/sync/profile_sync_service_factory.h" | 22 #include "chrome/browser/sync/profile_sync_service_factory.h" |
19 #include "chrome/common/channel_info.h" | 23 #include "chrome/common/channel_info.h" |
20 #include "chrome/common/pref_names.h" | 24 #include "chrome/common/pref_names.h" |
21 #include "components/browsing_data/core/history_notice_utils.h" | 25 #include "components/browsing_data/core/history_notice_utils.h" |
22 #include "components/browsing_data/core/pref_names.h" | 26 #include "components/browsing_data/core/pref_names.h" |
23 #include "components/prefs/pref_service.h" | 27 #include "components/prefs/pref_service.h" |
| 28 #include "content/public/browser/browsing_data_filter_builder.h" |
24 #include "content/public/browser/web_ui.h" | 29 #include "content/public/browser/web_ui.h" |
| 30 #include "ui/base/text/bytes_formatting.h" |
| 31 |
| 32 using ImportantReason = ImportantSitesUtil::ImportantReason; |
25 | 33 |
26 namespace { | 34 namespace { |
27 | 35 |
28 const int kMaxTimesHistoryNoticeShown = 1; | 36 const int kMaxTimesHistoryNoticeShown = 1; |
29 | 37 |
| 38 const int kMaxImportantSites = 10; |
| 39 |
30 // TODO(msramek): Get the list of deletion preferences from the JS side. | 40 // TODO(msramek): Get the list of deletion preferences from the JS side. |
31 const char* kCounterPrefs[] = { | 41 const char* kCounterPrefs[] = { |
32 browsing_data::prefs::kDeleteBrowsingHistory, | 42 browsing_data::prefs::kDeleteBrowsingHistory, |
33 browsing_data::prefs::kDeleteCache, | 43 browsing_data::prefs::kDeleteCache, |
34 browsing_data::prefs::kDeleteDownloadHistory, | 44 browsing_data::prefs::kDeleteDownloadHistory, |
35 browsing_data::prefs::kDeleteFormData, | 45 browsing_data::prefs::kDeleteFormData, |
36 browsing_data::prefs::kDeleteHostedAppsData, | 46 browsing_data::prefs::kDeleteHostedAppsData, |
37 browsing_data::prefs::kDeleteMediaLicenses, | 47 browsing_data::prefs::kDeleteMediaLicenses, |
38 browsing_data::prefs::kDeletePasswords, | 48 browsing_data::prefs::kDeletePasswords, |
39 }; | 49 }; |
40 | 50 |
| 51 const char kRegisterableDomainField[] = "registerableDomain"; |
| 52 const char kReasonBitField[] = "reasonBitfield"; |
| 53 const char kExampleOriginField[] = "exampleOrigin"; |
| 54 const char kIsCheckedField[] = "isChecked"; |
| 55 const char kStorageSizeField[] = "storageSize"; |
| 56 const char kHasNotificationsField[] = "hasNotifications"; |
| 57 |
41 } // namespace | 58 } // namespace |
42 | 59 |
43 namespace settings { | 60 namespace settings { |
44 | 61 |
45 // TaskObserver ---------------------------------------------------------------- | |
46 | |
47 class ClearBrowsingDataHandler::TaskObserver | |
48 : public content::BrowsingDataRemover::Observer { | |
49 public: | |
50 TaskObserver(content::BrowsingDataRemover* remover, | |
51 const base::Closure& callback); | |
52 ~TaskObserver() override; | |
53 | |
54 void OnBrowsingDataRemoverDone() override; | |
55 | |
56 private: | |
57 base::Closure callback_; | |
58 ScopedObserver<content::BrowsingDataRemover, | |
59 content::BrowsingDataRemover::Observer> | |
60 remover_observer_; | |
61 | |
62 DISALLOW_COPY_AND_ASSIGN(TaskObserver); | |
63 }; | |
64 | |
65 ClearBrowsingDataHandler::TaskObserver::TaskObserver( | |
66 content::BrowsingDataRemover* remover, | |
67 const base::Closure& callback) | |
68 : callback_(callback), remover_observer_(this) { | |
69 remover_observer_.Add(remover); | |
70 } | |
71 | |
72 ClearBrowsingDataHandler::TaskObserver::~TaskObserver() {} | |
73 | |
74 void ClearBrowsingDataHandler::TaskObserver::OnBrowsingDataRemoverDone() { | |
75 remover_observer_.RemoveAll(); | |
76 callback_.Run(); | |
77 } | |
78 | |
79 // ClearBrowsingDataHandler ---------------------------------------------------- | 62 // ClearBrowsingDataHandler ---------------------------------------------------- |
80 | 63 |
81 ClearBrowsingDataHandler::ClearBrowsingDataHandler(content::WebUI* webui) | 64 ClearBrowsingDataHandler::ClearBrowsingDataHandler(content::WebUI* webui) |
82 : profile_(Profile::FromWebUI(webui)), | 65 : profile_(Profile::FromWebUI(webui)), |
83 sync_service_(ProfileSyncServiceFactory::GetForProfile(profile_)), | 66 sync_service_(ProfileSyncServiceFactory::GetForProfile(profile_)), |
84 sync_service_observer_(this), | 67 sync_service_observer_(this), |
85 show_history_footer_(false), | 68 show_history_footer_(false), |
86 show_history_deletion_dialog_(false), | 69 show_history_deletion_dialog_(false), |
87 weak_ptr_factory_(this) {} | 70 weak_ptr_factory_(this) {} |
88 | 71 |
89 ClearBrowsingDataHandler::~ClearBrowsingDataHandler() { | 72 ClearBrowsingDataHandler::~ClearBrowsingDataHandler() { |
90 } | 73 } |
91 | 74 |
92 void ClearBrowsingDataHandler::RegisterMessages() { | 75 void ClearBrowsingDataHandler::RegisterMessages() { |
93 web_ui()->RegisterMessageCallback( | 76 web_ui()->RegisterMessageCallback( |
94 "clearBrowsingData", | 77 "clearBrowsingData", |
95 base::Bind(&ClearBrowsingDataHandler::HandleClearBrowsingData, | 78 base::Bind(&ClearBrowsingDataHandler::HandleClearBrowsingData, |
96 base::Unretained(this))); | 79 base::Unretained(this))); |
97 | 80 |
98 web_ui()->RegisterMessageCallback( | 81 web_ui()->RegisterMessageCallback( |
| 82 "getImportantSites", |
| 83 base::Bind(&ClearBrowsingDataHandler::HandleGetImportantSites, |
| 84 base::Unretained(this))); |
| 85 |
| 86 web_ui()->RegisterMessageCallback( |
99 "initializeClearBrowsingData", | 87 "initializeClearBrowsingData", |
100 base::Bind(&ClearBrowsingDataHandler::HandleInitialize, | 88 base::Bind(&ClearBrowsingDataHandler::HandleInitialize, |
101 base::Unretained(this))); | 89 base::Unretained(this))); |
102 } | 90 } |
103 | 91 |
104 void ClearBrowsingDataHandler::OnJavascriptAllowed() { | 92 void ClearBrowsingDataHandler::OnJavascriptAllowed() { |
105 if (sync_service_) | 93 if (sync_service_) |
106 sync_service_observer_.Add(sync_service_); | 94 sync_service_observer_.Add(sync_service_); |
107 | 95 |
108 DCHECK(counters_.empty()); | 96 DCHECK(counters_.empty()); |
109 for (const std::string& pref : kCounterPrefs) { | 97 for (const std::string& pref : kCounterPrefs) { |
110 AddCounter( | 98 AddCounter( |
111 BrowsingDataCounterFactory::GetForProfileAndPref(profile_, pref)); | 99 BrowsingDataCounterFactory::GetForProfileAndPref(profile_, pref)); |
112 } | 100 } |
113 } | 101 } |
114 | 102 |
115 void ClearBrowsingDataHandler::OnJavascriptDisallowed() { | 103 void ClearBrowsingDataHandler::OnJavascriptDisallowed() { |
116 sync_service_observer_.RemoveAll(); | 104 sync_service_observer_.RemoveAll(); |
117 task_observer_.reset(); | 105 weak_ptr_factory_.InvalidateWeakPtrs(); |
118 counters_.clear(); | 106 counters_.clear(); |
119 } | 107 } |
120 | 108 |
121 void ClearBrowsingDataHandler::HandleClearBrowsingData( | 109 void ClearBrowsingDataHandler::HandleClearBrowsingData( |
122 const base::ListValue* args) { | 110 const base::ListValue* args) { |
123 DCHECK(!task_observer_); | |
124 | |
125 PrefService* prefs = profile_->GetPrefs(); | 111 PrefService* prefs = profile_->GetPrefs(); |
126 | 112 |
127 int site_data_mask = ChromeBrowsingDataRemoverDelegate::DATA_TYPE_SITE_DATA; | 113 int site_data_mask = ChromeBrowsingDataRemoverDelegate::DATA_TYPE_SITE_DATA; |
128 // Don't try to clear LSO data if it's not supported. | 114 // Don't try to clear LSO data if it's not supported. |
129 if (!prefs->GetBoolean(prefs::kClearPluginLSODataEnabled)) | 115 if (!prefs->GetBoolean(prefs::kClearPluginLSODataEnabled)) |
130 site_data_mask &= ~ChromeBrowsingDataRemoverDelegate::DATA_TYPE_PLUGIN_DATA; | 116 site_data_mask &= ~ChromeBrowsingDataRemoverDelegate::DATA_TYPE_PLUGIN_DATA; |
131 | 117 |
132 int remove_mask = 0; | 118 int remove_mask = 0; |
133 if (prefs->GetBoolean(prefs::kAllowDeletingBrowserHistory)) { | 119 if (prefs->GetBoolean(prefs::kAllowDeletingBrowserHistory)) { |
134 if (prefs->GetBoolean(browsing_data::prefs::kDeleteBrowsingHistory)) | 120 if (prefs->GetBoolean(browsing_data::prefs::kDeleteBrowsingHistory)) |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 [prefs](const std::string& pref) { return prefs->GetBoolean(pref); }); | 178 [prefs](const std::string& pref) { return prefs->GetBoolean(pref); }); |
193 UMA_HISTOGRAM_SPARSE_SLOWLY( | 179 UMA_HISTOGRAM_SPARSE_SLOWLY( |
194 "History.ClearBrowsingData.PasswordsDeletion.AdditionalDatatypesCount", | 180 "History.ClearBrowsingData.PasswordsDeletion.AdditionalDatatypesCount", |
195 checked_other_types); | 181 checked_other_types); |
196 } | 182 } |
197 | 183 |
198 int period_selected = | 184 int period_selected = |
199 prefs->GetInteger(browsing_data::prefs::kDeleteTimePeriod); | 185 prefs->GetInteger(browsing_data::prefs::kDeleteTimePeriod); |
200 | 186 |
201 std::string webui_callback_id; | 187 std::string webui_callback_id; |
202 CHECK_EQ(1U, args->GetSize()); | 188 CHECK_EQ(2U, args->GetSize()); |
203 CHECK(args->GetString(0, &webui_callback_id)); | 189 CHECK(args->GetString(0, &webui_callback_id)); |
204 | 190 |
| 191 const base::ListValue* important_sites = nullptr; |
| 192 CHECK(args->GetList(1, &important_sites)); |
| 193 std::unique_ptr<content::BrowsingDataFilterBuilder> filter_builder = |
| 194 ProcessImportantSites(important_sites); |
| 195 |
205 content::BrowsingDataRemover* remover = | 196 content::BrowsingDataRemover* remover = |
206 content::BrowserContext::GetBrowsingDataRemover(profile_); | 197 content::BrowserContext::GetBrowsingDataRemover(profile_); |
207 task_observer_ = base::MakeUnique<TaskObserver>( | 198 |
208 remover, | 199 base::OnceClosure callback = |
209 base::Bind(&ClearBrowsingDataHandler::OnClearingTaskFinished, | 200 base::BindOnce(&ClearBrowsingDataHandler::OnClearingTaskFinished, |
210 base::Unretained(this), webui_callback_id)); | 201 weak_ptr_factory_.GetWeakPtr(), webui_callback_id); |
211 browsing_data::TimePeriod time_period = | 202 browsing_data::TimePeriod time_period = |
212 static_cast<browsing_data::TimePeriod>(period_selected); | 203 static_cast<browsing_data::TimePeriod>(period_selected); |
213 browsing_data::RecordDeletionForPeriod(time_period); | 204 |
214 remover->RemoveAndReply( | 205 browsing_data_important_sites_util::Remove( |
215 browsing_data::CalculateBeginDeleteTime(time_period), | 206 remove_mask, origin_mask, time_period, std::move(filter_builder), remover, |
216 browsing_data::CalculateEndDeleteTime(time_period), | 207 std::move(callback)); |
217 remove_mask, origin_mask, task_observer_.get()); | 208 } |
| 209 |
| 210 std::unique_ptr<content::BrowsingDataFilterBuilder> |
| 211 ClearBrowsingDataHandler::ProcessImportantSites( |
| 212 const base::ListValue* important_sites) { |
| 213 std::vector<std::string> excluding_domains; |
| 214 std::vector<int32_t> excluding_domain_reasons; |
| 215 std::vector<std::string> ignoring_domains; |
| 216 std::vector<int32_t> ignoring_domain_reasons; |
| 217 for (const auto& item : *important_sites) { |
| 218 const base::DictionaryValue* site = nullptr; |
| 219 CHECK(item.GetAsDictionary(&site)); |
| 220 bool is_checked = false; |
| 221 CHECK(site->GetBoolean(kIsCheckedField, &is_checked)); |
| 222 std::string domain; |
| 223 CHECK(site->GetString(kRegisterableDomainField, &domain)); |
| 224 int domain_reason = -1; |
| 225 CHECK(site->GetInteger(kReasonBitField, &domain_reason)); |
| 226 if (is_checked) { // Selected important sites should be deleted. |
| 227 ignoring_domains.push_back(domain); |
| 228 ignoring_domain_reasons.push_back(domain_reason); |
| 229 } else { // Unselected sites should be kept. |
| 230 excluding_domains.push_back(domain); |
| 231 excluding_domain_reasons.push_back(domain_reason); |
| 232 } |
| 233 } |
| 234 |
| 235 if (!excluding_domains.empty() || !ignoring_domains.empty()) { |
| 236 ImportantSitesUtil::RecordBlacklistedAndIgnoredImportantSites( |
| 237 profile_->GetOriginalProfile(), excluding_domains, |
| 238 excluding_domain_reasons, ignoring_domains, ignoring_domain_reasons); |
| 239 } |
| 240 |
| 241 std::unique_ptr<content::BrowsingDataFilterBuilder> filter_builder( |
| 242 content::BrowsingDataFilterBuilder::Create( |
| 243 content::BrowsingDataFilterBuilder::BLACKLIST)); |
| 244 for (const std::string& domain : excluding_domains) { |
| 245 filter_builder->AddRegisterableDomain(domain); |
| 246 } |
| 247 return filter_builder; |
218 } | 248 } |
219 | 249 |
220 void ClearBrowsingDataHandler::OnClearingTaskFinished( | 250 void ClearBrowsingDataHandler::OnClearingTaskFinished( |
221 const std::string& webui_callback_id) { | 251 const std::string& webui_callback_id) { |
222 PrefService* prefs = profile_->GetPrefs(); | 252 PrefService* prefs = profile_->GetPrefs(); |
223 int notice_shown_times = prefs->GetInteger( | 253 int notice_shown_times = prefs->GetInteger( |
224 browsing_data::prefs::kClearBrowsingDataHistoryNoticeShownTimes); | 254 browsing_data::prefs::kClearBrowsingDataHistoryNoticeShownTimes); |
225 | 255 |
226 // When the deletion is complete, we might show an additional dialog with | 256 // When the deletion is complete, we might show an additional dialog with |
227 // a notice about other forms of browsing history. This is the case if | 257 // a notice about other forms of browsing history. This is the case if |
(...skipping 10 matching lines...) Expand all Loading... |
238 prefs->SetInteger( | 268 prefs->SetInteger( |
239 browsing_data::prefs::kClearBrowsingDataHistoryNoticeShownTimes, | 269 browsing_data::prefs::kClearBrowsingDataHistoryNoticeShownTimes, |
240 notice_shown_times + 1); | 270 notice_shown_times + 1); |
241 } | 271 } |
242 | 272 |
243 UMA_HISTOGRAM_BOOLEAN( | 273 UMA_HISTOGRAM_BOOLEAN( |
244 "History.ClearBrowsingData.ShownHistoryNoticeAfterClearing", show_notice); | 274 "History.ClearBrowsingData.ShownHistoryNoticeAfterClearing", show_notice); |
245 | 275 |
246 ResolveJavascriptCallback(base::Value(webui_callback_id), | 276 ResolveJavascriptCallback(base::Value(webui_callback_id), |
247 base::Value(show_notice)); | 277 base::Value(show_notice)); |
248 task_observer_.reset(); | 278 } |
| 279 |
| 280 void ClearBrowsingDataHandler::HandleGetImportantSites( |
| 281 const base::ListValue* args) { |
| 282 AllowJavascript(); |
| 283 const base::Value* callback_id; |
| 284 CHECK(args->Get(0, &callback_id)); |
| 285 |
| 286 Profile* profile = profile_->GetOriginalProfile(); |
| 287 bool important_sites_dialog_disabled = |
| 288 ImportantSitesUtil::IsDialogDisabled(profile); |
| 289 base::ListValue important_sites_list; |
| 290 |
| 291 if (!important_sites_dialog_disabled) { |
| 292 std::vector<ImportantSitesUtil::ImportantDomainInfo> important_sites = |
| 293 ImportantSitesUtil::GetImportantRegisterableDomains(profile, |
| 294 kMaxImportantSites); |
| 295 for (const auto& info : important_sites) { |
| 296 auto entry = base::MakeUnique<base::DictionaryValue>(); |
| 297 entry->SetString(kRegisterableDomainField, info.registerable_domain); |
| 298 // The |reason_bitfield| is only passed to Javascript to be logged |
| 299 // from |HandleClearBrowsingData|. |
| 300 entry->SetInteger(kReasonBitField, info.reason_bitfield); |
| 301 entry->SetString(kExampleOriginField, info.example_origin.spec()); |
| 302 // Initially all sites are selected for deletion. |
| 303 entry->SetBoolean(kIsCheckedField, true); |
| 304 // TODO(dullweber): Get size. |
| 305 entry->SetString(kStorageSizeField, ui::FormatBytes(0)); |
| 306 bool has_notifications = |
| 307 (info.reason_bitfield & (1 << ImportantReason::NOTIFICATIONS)) != 0; |
| 308 entry->SetBoolean(kHasNotificationsField, has_notifications); |
| 309 important_sites_list.Append(std::move(entry)); |
| 310 } |
| 311 } |
| 312 |
| 313 ResolveJavascriptCallback(*callback_id, important_sites_list); |
249 } | 314 } |
250 | 315 |
251 void ClearBrowsingDataHandler::HandleInitialize(const base::ListValue* args) { | 316 void ClearBrowsingDataHandler::HandleInitialize(const base::ListValue* args) { |
252 AllowJavascript(); | 317 AllowJavascript(); |
253 const base::Value* callback_id; | 318 const base::Value* callback_id; |
254 CHECK(args->Get(0, &callback_id)); | 319 CHECK(args->Get(0, &callback_id)); |
255 | 320 |
256 // Needed because WebUI doesn't handle renderer crashes. See crbug.com/610450. | 321 // Needed because WebUI doesn't handle renderer crashes. See crbug.com/610450. |
257 task_observer_.reset(); | 322 weak_ptr_factory_.InvalidateWeakPtrs(); |
258 | 323 |
259 UpdateSyncState(); | 324 UpdateSyncState(); |
260 RefreshHistoryNotice(); | 325 RefreshHistoryNotice(); |
261 | 326 |
262 // Restart the counters each time the dialog is reopened. | 327 // Restart the counters each time the dialog is reopened. |
263 for (const auto& counter : counters_) | 328 for (const auto& counter : counters_) |
264 counter->Restart(); | 329 counter->Restart(); |
265 | 330 |
266 ResolveJavascriptCallback(*callback_id, base::Value() /* Promise<void> */); | 331 ResolveJavascriptCallback(*callback_id, base::Value() /* Promise<void> */); |
267 } | 332 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 | 390 |
326 void ClearBrowsingDataHandler::UpdateCounterText( | 391 void ClearBrowsingDataHandler::UpdateCounterText( |
327 std::unique_ptr<browsing_data::BrowsingDataCounter::Result> result) { | 392 std::unique_ptr<browsing_data::BrowsingDataCounter::Result> result) { |
328 CallJavascriptFunction( | 393 CallJavascriptFunction( |
329 "cr.webUIListenerCallback", base::Value("update-counter-text"), | 394 "cr.webUIListenerCallback", base::Value("update-counter-text"), |
330 base::Value(result->source()->GetPrefName()), | 395 base::Value(result->source()->GetPrefName()), |
331 base::Value(GetChromeCounterTextFromResult(result.get()))); | 396 base::Value(GetChromeCounterTextFromResult(result.get()))); |
332 } | 397 } |
333 | 398 |
334 } // namespace settings | 399 } // namespace settings |
OLD | NEW |