[Metrics] Make MetricsStateManager take a callback param to check if UMA is enabled.
[chromium-blink-merge.git] / chrome / browser / safe_browsing / safe_browsing_blocking_page.cc
blobc5b4c449b0d539b87804e0550ea47bfb989e208e
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 // Implementation of the SafeBrowsingBlockingPage class.
7 #include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h"
9 #include <string>
11 #include "base/bind.h"
12 #include "base/i18n/rtl.h"
13 #include "base/lazy_instance.h"
14 #include "base/metrics/field_trial.h"
15 #include "base/metrics/histogram.h"
16 #include "base/prefs/pref_service.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/string_piece.h"
19 #include "base/strings/stringprintf.h"
20 #include "base/strings/utf_string_conversions.h"
21 #include "base/time/time.h"
22 #include "base/values.h"
23 #include "chrome/browser/browser_process.h"
24 #include "chrome/browser/google/google_util.h"
25 #include "chrome/browser/history/history_service_factory.h"
26 #include "chrome/browser/profiles/profile.h"
27 #include "chrome/browser/renderer_preferences_util.h"
28 #include "chrome/browser/safe_browsing/malware_details.h"
29 #include "chrome/browser/safe_browsing/ui_manager.h"
30 #include "chrome/browser/tab_contents/tab_util.h"
31 #include "chrome/common/pref_names.h"
32 #include "chrome/common/url_constants.h"
33 #include "content/public/browser/browser_thread.h"
34 #include "content/public/browser/interstitial_page.h"
35 #include "content/public/browser/navigation_controller.h"
36 #include "content/public/browser/user_metrics.h"
37 #include "content/public/browser/web_contents.h"
38 #include "grit/browser_resources.h"
39 #include "grit/chromium_strings.h"
40 #include "grit/generated_resources.h"
41 #include "grit/locale_settings.h"
42 #include "net/base/escape.h"
43 #include "ui/base/l10n/l10n_util.h"
44 #include "ui/base/resource/resource_bundle.h"
45 #include "ui/base/webui/jstemplate_builder.h"
46 #include "ui/base/webui/web_ui_util.h"
48 using base::UserMetricsAction;
49 using content::BrowserThread;
50 using content::InterstitialPage;
51 using content::OpenURLParams;
52 using content::Referrer;
53 using content::WebContents;
55 namespace {
57 // For malware interstitial pages, we link the problematic URL to Google's
58 // diagnostic page.
59 #if defined(GOOGLE_CHROME_BUILD)
60 const char* const kSbDiagnosticUrl =
61 "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=%s&client=googlechrome";
62 #else
63 const char* const kSbDiagnosticUrl =
64 "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=%s&client=chromium";
65 #endif
67 const char kSbReportPhishingErrorUrl[] =
68 "http://www.google.com/safebrowsing/report_error/";
70 // URL for the "Learn more" link on the multi threat malware blocking page.
71 const char kLearnMoreMalwareUrl[] =
72 "https://www.google.com/support/bin/answer.py?answer=45449&topic=360"
73 "&sa=X&oi=malwarewarninglink&resnum=1&ct=help";
75 // URL for malware and phishing, V2.
76 const char kLearnMoreMalwareUrlV2[] =
77 "https://www.google.com/transparencyreport/safebrowsing/";
78 const char kLearnMorePhishingUrlV2[] =
79 "https://www.google.com/transparencyreport/safebrowsing/";
81 // URL for the "Learn more" link on the phishing blocking page.
82 const char kLearnMorePhishingUrl[] =
83 "https://www.google.com/support/bin/answer.py?answer=106318";
85 const char kPrivacyLinkHtml[] =
86 "<a id=\"privacy-link\" href=\"\" onclick=\"sendCommand('showPrivacy'); "
87 "return false;\" onmousedown=\"return false;\">%s</a>";
89 // After a malware interstitial where the user opted-in to the report
90 // but clicked "proceed anyway", we delay the call to
91 // MalwareDetails::FinishCollection() by this much time (in
92 // milliseconds).
93 const int64 kMalwareDetailsProceedDelayMilliSeconds = 3000;
95 // The commands returned by the page when the user performs an action.
96 const char kShowDiagnosticCommand[] = "showDiagnostic";
97 const char kReportErrorCommand[] = "reportError";
98 const char kLearnMoreCommand[] = "learnMore";
99 const char kLearnMoreCommandV2[] = "learnMore2";
100 const char kShowPrivacyCommand[] = "showPrivacy";
101 const char kProceedCommand[] = "proceed";
102 const char kTakeMeBackCommand[] = "takeMeBack";
103 const char kDoReportCommand[] = "doReport";
104 const char kDontReportCommand[] = "dontReport";
105 const char kDisplayCheckBox[] = "displaycheckbox";
106 const char kBoxChecked[] = "boxchecked";
107 const char kExpandedSeeMore[] = "expandedSeeMore";
108 // Special command that we use when the user navigated away from the
109 // page. E.g., closed the tab or the window. This is only used by
110 // RecordUserReactionTime.
111 const char kNavigatedAwayMetaCommand[] = "closed";
113 base::LazyInstance<SafeBrowsingBlockingPage::UnsafeResourceMap>
114 g_unsafe_resource_map = LAZY_INSTANCE_INITIALIZER;
116 // These are the conditions for the summer 2013 Finch experiment.
117 // TODO(felt): Get rid of these now that experiment has ended.
118 const char kMalwareStudyName[] = "InterstitialMalware310";
119 const char kPhishingStudyName[] = "InterstitialPhishing564";
120 const char kCond7MalwareFearMsg[] = "cond7MalwareFearMsg";
121 const char kCond8PhishingFearMsg[] = "cond8PhishingFearMsg";
122 const char kCond9MalwareCollabMsg[] = "cond9MalwareCollabMsg";
123 const char kCond10PhishingCollabMsg[] = "cond10PhishingCollabMsg";
124 const char kCond11MalwareQuestion[] = "cond11MalwareQuestion";
125 const char kCond12PhishingQuestion[] = "cond12PhishingQuestion";
126 const char kCond13MalwareGoBack[] = "cond13MalwareGoBack";
127 const char kCond14PhishingGoBack[] = "cond14PhishingGoBack";
129 // This enum is used for a histogram. Don't reorder, delete, or insert
130 // elements. New elements should be added before MAX_ACTION only.
131 enum DetailedDecision {
132 MALWARE_SHOW_NEW_SITE = 0,
133 MALWARE_PROCEED_NEW_SITE,
134 MALWARE_SHOW_CROSS_SITE,
135 MALWARE_PROCEED_CROSS_SITE,
136 PHISHING_SHOW_NEW_SITE,
137 PHISHING_PROCEED_NEW_SITE,
138 PHISHING_SHOW_CROSS_SITE,
139 PHISHING_PROCEED_CROSS_SITE,
140 MAX_DETAILED_ACTION
143 void RecordDetailedUserAction(DetailedDecision decision) {
144 UMA_HISTOGRAM_ENUMERATION("SB2.InterstitialActionDetails",
145 decision,
146 MAX_DETAILED_ACTION);
149 } // namespace
151 // static
152 SafeBrowsingBlockingPageFactory* SafeBrowsingBlockingPage::factory_ = NULL;
154 // The default SafeBrowsingBlockingPageFactory. Global, made a singleton so we
155 // don't leak it.
156 class SafeBrowsingBlockingPageFactoryImpl
157 : public SafeBrowsingBlockingPageFactory {
158 public:
159 virtual SafeBrowsingBlockingPage* CreateSafeBrowsingPage(
160 SafeBrowsingUIManager* ui_manager,
161 WebContents* web_contents,
162 const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources)
163 OVERRIDE {
164 // Only use the V2 page if the interstitial is for a single malware or
165 // phishing resource, the multi-threat interstitial has not been updated to
166 // V2 yet.
167 if (unsafe_resources.size() == 1 &&
168 (unsafe_resources[0].threat_type == SB_THREAT_TYPE_URL_MALWARE ||
169 unsafe_resources[0].threat_type ==
170 SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL ||
171 unsafe_resources[0].threat_type == SB_THREAT_TYPE_URL_PHISHING ||
172 unsafe_resources[0].threat_type ==
173 SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL)) {
174 return new SafeBrowsingBlockingPageV2(ui_manager, web_contents,
175 unsafe_resources);
177 return new SafeBrowsingBlockingPageV1(ui_manager, web_contents,
178 unsafe_resources);
181 private:
182 friend struct base::DefaultLazyInstanceTraits<
183 SafeBrowsingBlockingPageFactoryImpl>;
185 SafeBrowsingBlockingPageFactoryImpl() { }
187 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingBlockingPageFactoryImpl);
190 static base::LazyInstance<SafeBrowsingBlockingPageFactoryImpl>
191 g_safe_browsing_blocking_page_factory_impl = LAZY_INSTANCE_INITIALIZER;
193 SafeBrowsingBlockingPage::SafeBrowsingBlockingPage(
194 SafeBrowsingUIManager* ui_manager,
195 WebContents* web_contents,
196 const UnsafeResourceList& unsafe_resources)
197 : malware_details_proceed_delay_ms_(
198 kMalwareDetailsProceedDelayMilliSeconds),
199 ui_manager_(ui_manager),
200 report_loop_(NULL),
201 is_main_frame_load_blocked_(IsMainPageLoadBlocked(unsafe_resources)),
202 unsafe_resources_(unsafe_resources),
203 proceeded_(false),
204 web_contents_(web_contents),
205 url_(unsafe_resources[0].url),
206 has_expanded_see_more_section_(false),
207 num_visits_(-1) {
208 bool malware = false;
209 bool phishing = false;
210 for (UnsafeResourceList::const_iterator iter = unsafe_resources_.begin();
211 iter != unsafe_resources_.end(); ++iter) {
212 const UnsafeResource& resource = *iter;
213 SBThreatType threat_type = resource.threat_type;
214 if (threat_type == SB_THREAT_TYPE_URL_MALWARE ||
215 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) {
216 malware = true;
217 } else {
218 DCHECK(threat_type == SB_THREAT_TYPE_URL_PHISHING ||
219 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL);
220 phishing = true;
223 DCHECK(phishing || malware);
224 if (malware && phishing)
225 interstitial_type_ = TYPE_MALWARE_AND_PHISHING;
226 else if (malware)
227 interstitial_type_ = TYPE_MALWARE;
228 else
229 interstitial_type_ = TYPE_PHISHING;
231 RecordUserAction(SHOW);
232 HistoryService* history_service = HistoryServiceFactory::GetForProfile(
233 Profile::FromBrowserContext(web_contents->GetBrowserContext()),
234 Profile::EXPLICIT_ACCESS);
235 if (history_service) {
236 history_service->GetVisibleVisitCountToHost(
237 url_,
238 &request_consumer_,
239 base::Bind(&SafeBrowsingBlockingPage::OnGotHistoryCount,
240 base::Unretained(this)));
243 if (!is_main_frame_load_blocked_) {
244 navigation_entry_index_to_remove_ =
245 web_contents->GetController().GetLastCommittedEntryIndex();
246 } else {
247 navigation_entry_index_to_remove_ = -1;
250 // Start computing malware details. They will be sent only
251 // if the user opts-in on the blocking page later.
252 // If there's more than one malicious resources, it means the user
253 // clicked through the first warning, so we don't prepare additional
254 // reports.
255 if (unsafe_resources.size() == 1 &&
256 unsafe_resources[0].threat_type == SB_THREAT_TYPE_URL_MALWARE &&
257 malware_details_.get() == NULL && CanShowMalwareDetailsOption()) {
258 malware_details_ = MalwareDetails::NewMalwareDetails(
259 ui_manager_, web_contents, unsafe_resources[0]);
262 interstitial_page_ = InterstitialPage::Create(
263 web_contents, IsMainPageLoadBlocked(unsafe_resources), url_, this);
266 bool SafeBrowsingBlockingPage::CanShowMalwareDetailsOption() {
267 return (!web_contents_->GetBrowserContext()->IsOffTheRecord() &&
268 web_contents_->GetURL().SchemeIs(url::kHttpScheme));
271 SafeBrowsingBlockingPage::~SafeBrowsingBlockingPage() {
274 void SafeBrowsingBlockingPage::CommandReceived(const std::string& cmd) {
275 std::string command(cmd); // Make a local copy so we can modify it.
276 // The Jasonified response has quotes, remove them.
277 if (command.length() > 1 && command[0] == '"') {
278 command = command.substr(1, command.length() - 2);
280 RecordUserReactionTime(command);
281 if (command == kDoReportCommand) {
282 SetReportingPreference(true);
283 return;
286 if (command == kDontReportCommand) {
287 SetReportingPreference(false);
288 return;
291 if (command == kLearnMoreCommand) {
292 // User pressed "Learn more".
293 GURL url;
294 SBThreatType threat_type = unsafe_resources_[0].threat_type;
295 if (threat_type == SB_THREAT_TYPE_URL_MALWARE ||
296 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) {
297 url = google_util::AppendGoogleLocaleParam(GURL(kLearnMoreMalwareUrl));
298 } else if (threat_type == SB_THREAT_TYPE_URL_PHISHING ||
299 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL) {
300 url = google_util::AppendGoogleLocaleParam(GURL(kLearnMorePhishingUrl));
301 } else {
302 NOTREACHED();
305 OpenURLParams params(
306 url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK, false);
307 web_contents_->OpenURL(params);
308 return;
311 if (command == kLearnMoreCommandV2) {
312 // User pressed "Learn more".
313 GURL url;
314 SBThreatType threat_type = unsafe_resources_[0].threat_type;
315 if (threat_type == SB_THREAT_TYPE_URL_MALWARE ||
316 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) {
317 url = google_util::AppendGoogleLocaleParam(GURL(kLearnMoreMalwareUrlV2));
318 } else if (threat_type == SB_THREAT_TYPE_URL_PHISHING ||
319 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL) {
320 url = google_util::AppendGoogleLocaleParam(GURL(kLearnMorePhishingUrlV2));
321 } else {
322 NOTREACHED();
325 OpenURLParams params(
326 url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK, false);
327 web_contents_->OpenURL(params);
328 return;
331 if (command == kShowPrivacyCommand) {
332 // User pressed "Safe Browsing privacy policy".
333 GURL url(l10n_util::GetStringUTF8(IDS_SAFE_BROWSING_PRIVACY_POLICY_URL));
334 OpenURLParams params(
335 url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK, false);
336 web_contents_->OpenURL(params);
337 return;
340 bool proceed_blocked = false;
341 if (command == kProceedCommand) {
342 if (IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled)) {
343 proceed_blocked = true;
344 } else {
345 interstitial_page_->Proceed();
346 // |this| has been deleted after Proceed() returns.
347 return;
351 if (command == kTakeMeBackCommand || proceed_blocked) {
352 if (is_main_frame_load_blocked_) {
353 // If the load is blocked, we want to close the interstitial and discard
354 // the pending entry.
355 interstitial_page_->DontProceed();
356 // |this| has been deleted after DontProceed() returns.
357 return;
360 // Otherwise the offending entry has committed, and we need to go back or
361 // to a safe page. We will close the interstitial when that page commits.
362 if (web_contents_->GetController().CanGoBack()) {
363 web_contents_->GetController().GoBack();
364 } else {
365 web_contents_->GetController().LoadURL(
366 GURL(chrome::kChromeUINewTabURL),
367 content::Referrer(),
368 content::PAGE_TRANSITION_AUTO_TOPLEVEL,
369 std::string());
371 return;
374 // The "report error" and "show diagnostic" commands can have a number
375 // appended to them, which is the index of the element they apply to.
376 size_t element_index = 0;
377 size_t colon_index = command.find(':');
378 if (colon_index != std::string::npos) {
379 DCHECK(colon_index < command.size() - 1);
380 int result_int = 0;
381 bool result = base::StringToInt(base::StringPiece(command.begin() +
382 colon_index + 1,
383 command.end()),
384 &result_int);
385 command = command.substr(0, colon_index);
386 if (result)
387 element_index = static_cast<size_t>(result_int);
390 if (element_index >= unsafe_resources_.size()) {
391 NOTREACHED();
392 return;
395 std::string bad_url_spec = unsafe_resources_[element_index].url.spec();
396 if (command == kReportErrorCommand) {
397 // User pressed "Report error" for a phishing site.
398 // Note that we cannot just put a link in the interstitial at this point.
399 // It is not OK to navigate in the context of an interstitial page.
400 SBThreatType threat_type = unsafe_resources_[element_index].threat_type;
401 DCHECK(threat_type == SB_THREAT_TYPE_URL_PHISHING ||
402 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL);
403 GURL report_url =
404 safe_browsing_util::GeneratePhishingReportUrl(
405 kSbReportPhishingErrorUrl,
406 bad_url_spec,
407 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL);
408 OpenURLParams params(
409 report_url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK,
410 false);
411 web_contents_->OpenURL(params);
412 return;
415 if (command == kShowDiagnosticCommand) {
416 // We're going to take the user to Google's SafeBrowsing diagnostic page.
417 std::string diagnostic =
418 base::StringPrintf(kSbDiagnosticUrl,
419 net::EscapeQueryParamValue(bad_url_spec, true).c_str());
420 GURL diagnostic_url(diagnostic);
421 diagnostic_url = google_util::AppendGoogleLocaleParam(diagnostic_url);
422 DCHECK(unsafe_resources_[element_index].threat_type ==
423 SB_THREAT_TYPE_URL_MALWARE ||
424 unsafe_resources_[element_index].threat_type ==
425 SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL);
426 OpenURLParams params(
427 diagnostic_url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK,
428 false);
429 web_contents_->OpenURL(params);
430 return;
433 if (command == kExpandedSeeMore) {
434 // User expanded the "see more info" section of the page. We don't actually
435 // do any action based on this, it's just so that RecordUserReactionTime can
436 // track it.
437 return;
440 NOTREACHED() << "Unexpected command: " << command;
443 void SafeBrowsingBlockingPage::OverrideRendererPrefs(
444 content::RendererPreferences* prefs) {
445 Profile* profile = Profile::FromBrowserContext(
446 web_contents_->GetBrowserContext());
447 renderer_preferences_util::UpdateFromSystemSettings(prefs, profile);
450 void SafeBrowsingBlockingPage::SetReportingPreference(bool report) {
451 Profile* profile = Profile::FromBrowserContext(
452 web_contents_->GetBrowserContext());
453 PrefService* pref = profile->GetPrefs();
454 pref->SetBoolean(prefs::kSafeBrowsingReportingEnabled, report);
455 UMA_HISTOGRAM_BOOLEAN("SB2.SetReportingEnabled", report);
458 void SafeBrowsingBlockingPage::OnProceed() {
459 proceeded_ = true;
460 RecordUserAction(PROCEED);
461 // Send the malware details, if we opted to.
462 FinishMalwareDetails(malware_details_proceed_delay_ms_);
464 NotifySafeBrowsingUIManager(ui_manager_, unsafe_resources_, true);
466 // Check to see if some new notifications of unsafe resources have been
467 // received while we were showing the interstitial.
468 UnsafeResourceMap* unsafe_resource_map = GetUnsafeResourcesMap();
469 UnsafeResourceMap::iterator iter = unsafe_resource_map->find(web_contents_);
470 SafeBrowsingBlockingPage* blocking_page = NULL;
471 if (iter != unsafe_resource_map->end() && !iter->second.empty()) {
472 // Build an interstitial for all the unsafe resources notifications.
473 // Don't show it now as showing an interstitial while an interstitial is
474 // already showing would cause DontProceed() to be invoked.
475 blocking_page = factory_->CreateSafeBrowsingPage(ui_manager_, web_contents_,
476 iter->second);
477 unsafe_resource_map->erase(iter);
480 // Now that this interstitial is gone, we can show the new one.
481 if (blocking_page)
482 blocking_page->interstitial_page_->Show();
485 void SafeBrowsingBlockingPage::OnDontProceed() {
486 // Calling this method twice will not double-count.
487 RecordUserReactionTime(kNavigatedAwayMetaCommand);
488 // We could have already called Proceed(), in which case we must not notify
489 // the SafeBrowsingUIManager again, as the client has been deleted.
490 if (proceeded_)
491 return;
493 RecordUserAction(DONT_PROCEED);
494 // Send the malware details, if we opted to.
495 FinishMalwareDetails(0); // No delay
497 NotifySafeBrowsingUIManager(ui_manager_, unsafe_resources_, false);
499 // The user does not want to proceed, clear the queued unsafe resources
500 // notifications we received while the interstitial was showing.
501 UnsafeResourceMap* unsafe_resource_map = GetUnsafeResourcesMap();
502 UnsafeResourceMap::iterator iter = unsafe_resource_map->find(web_contents_);
503 if (iter != unsafe_resource_map->end() && !iter->second.empty()) {
504 NotifySafeBrowsingUIManager(ui_manager_, iter->second, false);
505 unsafe_resource_map->erase(iter);
508 // We don't remove the navigation entry if the tab is being destroyed as this
509 // would trigger a navigation that would cause trouble as the render view host
510 // for the tab has by then already been destroyed. We also don't delete the
511 // current entry if it has been committed again, which is possible on a page
512 // that had a subresource warning.
513 int last_committed_index =
514 web_contents_->GetController().GetLastCommittedEntryIndex();
515 if (navigation_entry_index_to_remove_ != -1 &&
516 navigation_entry_index_to_remove_ != last_committed_index &&
517 !web_contents_->IsBeingDestroyed()) {
518 CHECK(web_contents_->GetController().RemoveEntryAtIndex(
519 navigation_entry_index_to_remove_));
520 navigation_entry_index_to_remove_ = -1;
524 void SafeBrowsingBlockingPage::OnGotHistoryCount(HistoryService::Handle handle,
525 bool success,
526 int num_visits,
527 base::Time first_visit) {
528 if (success)
529 num_visits_ = num_visits;
532 void SafeBrowsingBlockingPage::RecordUserAction(BlockingPageEvent event) {
533 // This enum is used for a histogram. Don't reorder, delete, or insert
534 // elements. New elements should be added before MAX_ACTION only.
535 enum {
536 MALWARE_SHOW = 0,
537 MALWARE_DONT_PROCEED,
538 MALWARE_FORCED_DONT_PROCEED,
539 MALWARE_PROCEED,
540 MULTIPLE_SHOW,
541 MULTIPLE_DONT_PROCEED,
542 MULTIPLE_FORCED_DONT_PROCEED,
543 MULTIPLE_PROCEED,
544 PHISHING_SHOW,
545 PHISHING_DONT_PROCEED,
546 PHISHING_FORCED_DONT_PROCEED,
547 PHISHING_PROCEED,
548 MALWARE_SHOW_ADVANCED,
549 MULTIPLE_SHOW_ADVANCED,
550 PHISHING_SHOW_ADVANCED,
551 MAX_ACTION
552 } histogram_action = MAX_ACTION;
554 switch (event) {
555 case SHOW:
556 switch (interstitial_type_) {
557 case TYPE_MALWARE_AND_PHISHING:
558 histogram_action = MULTIPLE_SHOW;
559 break;
560 case TYPE_MALWARE:
561 histogram_action = MALWARE_SHOW;
562 break;
563 case TYPE_PHISHING:
564 histogram_action = PHISHING_SHOW;
565 break;
567 break;
568 case PROCEED:
569 switch (interstitial_type_) {
570 case TYPE_MALWARE_AND_PHISHING:
571 histogram_action = MULTIPLE_PROCEED;
572 break;
573 case TYPE_MALWARE:
574 histogram_action = MALWARE_PROCEED;
575 break;
576 case TYPE_PHISHING:
577 histogram_action = PHISHING_PROCEED;
578 break;
580 break;
581 case DONT_PROCEED:
582 if (IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled)) {
583 switch (interstitial_type_) {
584 case TYPE_MALWARE_AND_PHISHING:
585 histogram_action = MULTIPLE_FORCED_DONT_PROCEED;
586 break;
587 case TYPE_MALWARE:
588 histogram_action = MALWARE_FORCED_DONT_PROCEED;
589 break;
590 case TYPE_PHISHING:
591 histogram_action = PHISHING_FORCED_DONT_PROCEED;
592 break;
594 } else {
595 switch (interstitial_type_) {
596 case TYPE_MALWARE_AND_PHISHING:
597 histogram_action = MULTIPLE_DONT_PROCEED;
598 break;
599 case TYPE_MALWARE:
600 histogram_action = MALWARE_DONT_PROCEED;
601 break;
602 case TYPE_PHISHING:
603 histogram_action = PHISHING_DONT_PROCEED;
604 break;
607 break;
608 case SHOW_ADVANCED:
609 switch (interstitial_type_) {
610 case TYPE_MALWARE_AND_PHISHING:
611 histogram_action = MULTIPLE_SHOW_ADVANCED;
612 break;
613 case TYPE_MALWARE:
614 histogram_action = MALWARE_SHOW_ADVANCED;
615 break;
616 case TYPE_PHISHING:
617 histogram_action = PHISHING_SHOW_ADVANCED;
618 break;
620 break;
621 default:
622 NOTREACHED() << "Unexpected event: " << event;
624 if (histogram_action == MAX_ACTION) {
625 NOTREACHED();
626 } else {
627 UMA_HISTOGRAM_ENUMERATION("SB2.InterstitialAction", histogram_action,
628 MAX_ACTION);
631 if (event == PROCEED || event == DONT_PROCEED) {
632 if (num_visits_ == 0 && interstitial_type_ != TYPE_MALWARE_AND_PHISHING) {
633 RecordDetailedUserAction((interstitial_type_ == TYPE_MALWARE) ?
634 MALWARE_SHOW_NEW_SITE : PHISHING_SHOW_NEW_SITE);
635 if (event == PROCEED) {
636 RecordDetailedUserAction((interstitial_type_ == TYPE_MALWARE) ?
637 MALWARE_PROCEED_NEW_SITE : PHISHING_PROCEED_NEW_SITE);
640 if (unsafe_resources_[0].is_subresource &&
641 interstitial_type_ != TYPE_MALWARE_AND_PHISHING) {
642 RecordDetailedUserAction((interstitial_type_ == TYPE_MALWARE) ?
643 MALWARE_SHOW_CROSS_SITE : PHISHING_SHOW_CROSS_SITE);
644 if (event == PROCEED) {
645 RecordDetailedUserAction((interstitial_type_ == TYPE_MALWARE) ?
646 MALWARE_PROCEED_CROSS_SITE : PHISHING_PROCEED_CROSS_SITE);
651 // TODO(felt): Get rid of the old interstitial histogram.
652 std::string action = "SBInterstitial";
653 switch (interstitial_type_) {
654 case TYPE_MALWARE_AND_PHISHING:
655 action.append("Multiple");
656 break;
657 case TYPE_MALWARE:
658 action.append("Malware");
659 break;
660 case TYPE_PHISHING:
661 action.append("Phishing");
662 break;
665 switch (event) {
666 case SHOW:
667 action.append("Show");
668 break;
669 case PROCEED:
670 action.append("Proceed");
671 break;
672 case DONT_PROCEED:
673 if (IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled))
674 action.append("ForcedDontProceed");
675 else
676 action.append("DontProceed");
677 break;
678 case SHOW_ADVANCED:
679 break;
680 default:
681 NOTREACHED() << "Unexpected event: " << event;
684 content::RecordComputedAction(action);
687 void SafeBrowsingBlockingPage::RecordUserReactionTime(
688 const std::string& command) {
689 if (interstitial_show_time_.is_null())
690 return; // We already reported the user reaction time.
691 base::TimeDelta dt = base::TimeTicks::Now() - interstitial_show_time_;
692 DVLOG(1) << "User reaction time for command:" << command
693 << " on interstitial_type_:" << interstitial_type_
694 << " warning took " << dt.InMilliseconds() << "ms";
695 bool recorded = true;
696 if (interstitial_type_ == TYPE_MALWARE ||
697 interstitial_type_ == TYPE_MALWARE_AND_PHISHING) {
698 // There are six ways in which the malware interstitial can go
699 // away. We handle all of them here but we group two together: closing the
700 // tag / browser window and clicking on the back button in the browser (not
701 // the big green button) are considered the same action.
702 if (command == kProceedCommand) {
703 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeProceed", dt);
704 } else if (command == kTakeMeBackCommand) {
705 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeTakeMeBack", dt);
706 } else if (command == kShowDiagnosticCommand) {
707 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeDiagnostic", dt);
708 } else if (command == kShowPrivacyCommand) {
709 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimePrivacyPolicy",
710 dt);
711 } else if (command == kLearnMoreCommand || command == kLearnMoreCommandV2) {
712 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialLearnMore",
713 dt);
714 } else if (command == kNavigatedAwayMetaCommand) {
715 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeClosed", dt);
716 } else if (command == kExpandedSeeMore) {
717 // Only record the expanded histogram once per display of the
718 // interstitial.
719 if (has_expanded_see_more_section_)
720 return;
721 RecordUserAction(SHOW_ADVANCED);
722 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeExpandedSeeMore",
723 dt);
724 has_expanded_see_more_section_ = true;
725 // Expanding the "See More" section doesn't finish the interstitial, so
726 // don't mark the reaction time as recorded.
727 recorded = false;
728 } else {
729 recorded = false;
731 } else {
732 // Same as above but for phishing warnings.
733 if (command == kProceedCommand) {
734 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeProceed", dt);
735 } else if (command == kTakeMeBackCommand) {
736 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeTakeMeBack", dt);
737 } else if (command == kShowDiagnosticCommand) {
738 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeReportError", dt);
739 } else if (command == kLearnMoreCommand || command == kLearnMoreCommandV2) {
740 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeLearnMore", dt);
741 } else if (command == kNavigatedAwayMetaCommand) {
742 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeClosed", dt);
743 } else if (command == kExpandedSeeMore) {
744 // Only record the expanded histogram once per display of the
745 // interstitial.
746 if (has_expanded_see_more_section_)
747 return;
748 RecordUserAction(SHOW_ADVANCED);
749 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeExpandedSeeMore",
750 dt);
751 has_expanded_see_more_section_ = true;
752 // Expanding the "See More" section doesn't finish the interstitial, so
753 // don't mark the reaction time as recorded.
754 recorded = false;
755 } else {
756 recorded = false;
759 if (recorded) // Making sure we don't double-count reaction times.
760 interstitial_show_time_ = base::TimeTicks(); // Resets the show time.
763 void SafeBrowsingBlockingPage::FinishMalwareDetails(int64 delay_ms) {
764 if (malware_details_.get() == NULL)
765 return; // Not all interstitials have malware details (eg phishing).
767 const bool enabled = IsPrefEnabled(prefs::kSafeBrowsingReportingEnabled);
768 UMA_HISTOGRAM_BOOLEAN("SB2.ReportingIsEnabled", enabled);
769 if (enabled) {
770 // Finish the malware details collection, send it over.
771 BrowserThread::PostDelayedTask(
772 BrowserThread::IO, FROM_HERE,
773 base::Bind(&MalwareDetails::FinishCollection, malware_details_.get()),
774 base::TimeDelta::FromMilliseconds(delay_ms));
778 bool SafeBrowsingBlockingPage::IsPrefEnabled(const char* pref) {
779 Profile* profile =
780 Profile::FromBrowserContext(web_contents_->GetBrowserContext());
781 return profile->GetPrefs()->GetBoolean(pref);
784 // static
785 void SafeBrowsingBlockingPage::NotifySafeBrowsingUIManager(
786 SafeBrowsingUIManager* ui_manager,
787 const UnsafeResourceList& unsafe_resources,
788 bool proceed) {
789 BrowserThread::PostTask(
790 BrowserThread::IO, FROM_HERE,
791 base::Bind(&SafeBrowsingUIManager::OnBlockingPageDone,
792 ui_manager, unsafe_resources, proceed));
795 // static
796 SafeBrowsingBlockingPage::UnsafeResourceMap*
797 SafeBrowsingBlockingPage::GetUnsafeResourcesMap() {
798 return g_unsafe_resource_map.Pointer();
801 // static
802 void SafeBrowsingBlockingPage::ShowBlockingPage(
803 SafeBrowsingUIManager* ui_manager,
804 const UnsafeResource& unsafe_resource) {
805 DVLOG(1) << __FUNCTION__ << " " << unsafe_resource.url.spec();
806 WebContents* web_contents = tab_util::GetWebContentsByID(
807 unsafe_resource.render_process_host_id, unsafe_resource.render_view_id);
809 InterstitialPage* interstitial =
810 InterstitialPage::GetInterstitialPage(web_contents);
811 if (interstitial && !unsafe_resource.is_subresource) {
812 // There is already an interstitial showing and we are about to display a
813 // new one for the main frame. Just hide the current one, it is now
814 // irrelevent
815 interstitial->DontProceed();
816 interstitial = NULL;
819 if (!interstitial) {
820 // There are no interstitial currently showing in that tab, go ahead and
821 // show this interstitial.
822 std::vector<UnsafeResource> resources;
823 resources.push_back(unsafe_resource);
824 // Set up the factory if this has not been done already (tests do that
825 // before this method is called).
826 if (!factory_)
827 factory_ = g_safe_browsing_blocking_page_factory_impl.Pointer();
828 SafeBrowsingBlockingPage* blocking_page =
829 factory_->CreateSafeBrowsingPage(ui_manager, web_contents, resources);
830 blocking_page->interstitial_page_->Show();
831 return;
834 // This is an interstitial for a page's resource, let's queue it.
835 UnsafeResourceMap* unsafe_resource_map = GetUnsafeResourcesMap();
836 (*unsafe_resource_map)[web_contents].push_back(unsafe_resource);
839 // static
840 bool SafeBrowsingBlockingPage::IsMainPageLoadBlocked(
841 const UnsafeResourceList& unsafe_resources) {
842 // Client-side phishing detection interstitials never block the main frame
843 // load, since they happen after the page is finished loading.
844 if (unsafe_resources[0].threat_type ==
845 SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL) {
846 return false;
849 // Otherwise, check the threat type.
850 return unsafe_resources.size() == 1 && !unsafe_resources[0].is_subresource;
853 SafeBrowsingBlockingPageV1::SafeBrowsingBlockingPageV1(
854 SafeBrowsingUIManager* ui_manager,
855 WebContents* web_contents,
856 const UnsafeResourceList& unsafe_resources)
857 : SafeBrowsingBlockingPage(ui_manager, web_contents, unsafe_resources) {
860 std::string SafeBrowsingBlockingPageV1::GetHTMLContents() {
861 // Load the HTML page and create the template components.
862 base::DictionaryValue strings;
863 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
864 std::string html;
866 if (unsafe_resources_.empty()) {
867 NOTREACHED();
868 return std::string();
871 DCHECK_GT(unsafe_resources_.size(), 1U);
872 PopulateMultipleThreatStringDictionary(&strings);
873 html = rb.GetRawDataResource(
874 IDR_SAFE_BROWSING_MULTIPLE_THREAT_BLOCK).as_string();
875 interstitial_show_time_ = base::TimeTicks::Now();
876 return webui::GetTemplatesHtml(html, &strings, "template_root");
879 void SafeBrowsingBlockingPageV1::PopulateStringDictionary(
880 base::DictionaryValue* strings,
881 const base::string16& title,
882 const base::string16& headline,
883 const base::string16& description1,
884 const base::string16& description2,
885 const base::string16& description3) {
886 strings->SetString("title", title);
887 strings->SetString("headLine", headline);
888 strings->SetString("description1", description1);
889 strings->SetString("description2", description2);
890 strings->SetString("description3", description3);
891 strings->SetBoolean("proceedDisabled",
892 IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled));
895 void SafeBrowsingBlockingPageV1::PopulateMultipleThreatStringDictionary(
896 base::DictionaryValue* strings) {
898 base::string16 malware_label =
899 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_LABEL);
900 base::string16 malware_link =
901 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_DIAGNOSTIC_PAGE);
902 base::string16 phishing_label =
903 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_LABEL);
904 base::string16 phishing_link =
905 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_REPORT_ERROR);
907 base::ListValue* error_strings = new base::ListValue;
908 for (UnsafeResourceList::const_iterator iter = unsafe_resources_.begin();
909 iter != unsafe_resources_.end(); ++iter) {
910 const UnsafeResource& resource = *iter;
911 SBThreatType threat_type = resource.threat_type;
912 base::DictionaryValue* current_error_strings = new base::DictionaryValue;
913 if (threat_type == SB_THREAT_TYPE_URL_MALWARE ||
914 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) {
915 current_error_strings->SetString("type", "malware");
916 current_error_strings->SetString("typeLabel", malware_label);
917 current_error_strings->SetString("errorLink", malware_link);
918 } else {
919 DCHECK(threat_type == SB_THREAT_TYPE_URL_PHISHING ||
920 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL);
921 current_error_strings->SetString("type", "phishing");
922 current_error_strings->SetString("typeLabel", phishing_label);
923 current_error_strings->SetString("errorLink", phishing_link);
925 current_error_strings->SetString("url", resource.url.spec());
926 error_strings->Append(current_error_strings);
928 strings->Set("errors", error_strings);
930 switch (interstitial_type_) {
931 case TYPE_MALWARE_AND_PHISHING:
932 PopulateStringDictionary(
933 strings,
934 // Use the malware headline, it is the scariest one.
935 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MULTI_THREAT_TITLE),
936 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_HEADLINE),
937 l10n_util::GetStringFUTF16(
938 IDS_SAFE_BROWSING_MULTI_THREAT_DESCRIPTION1,
939 base::UTF8ToUTF16(web_contents_->GetURL().host())),
940 l10n_util::GetStringUTF16(
941 IDS_SAFE_BROWSING_MULTI_THREAT_DESCRIPTION2),
942 base::string16());
943 break;
944 case TYPE_MALWARE:
945 PopulateStringDictionary(
946 strings,
947 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_TITLE),
948 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_HEADLINE),
949 l10n_util::GetStringFUTF16(
950 IDS_SAFE_BROWSING_MULTI_MALWARE_DESCRIPTION1,
951 base::UTF8ToUTF16(web_contents_->GetURL().host())),
952 l10n_util::GetStringUTF16(
953 IDS_SAFE_BROWSING_MULTI_MALWARE_DESCRIPTION2),
954 l10n_util::GetStringUTF16(
955 IDS_SAFE_BROWSING_MULTI_MALWARE_DESCRIPTION3));
956 break;
957 case TYPE_PHISHING:
958 PopulateStringDictionary(
959 strings,
960 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_TITLE),
961 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_HEADLINE),
962 l10n_util::GetStringFUTF16(
963 IDS_SAFE_BROWSING_MULTI_PHISHING_DESCRIPTION1,
964 base::UTF8ToUTF16(web_contents_->GetURL().host())),
965 base::string16(),
966 base::string16());
967 break;
970 strings->SetString("confirm_text",
971 l10n_util::GetStringUTF16(
972 IDS_SAFE_BROWSING_MULTI_MALWARE_DESCRIPTION_AGREE));
973 strings->SetString("continue_button",
974 l10n_util::GetStringUTF16(
975 IDS_SAFE_BROWSING_MULTI_MALWARE_PROCEED_BUTTON));
976 strings->SetString("back_button",
977 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_BACK_BUTTON));
978 strings->SetString("textdirection", base::i18n::IsRTL() ? "rtl" : "ltr");
981 void SafeBrowsingBlockingPageV1::PopulateMalwareStringDictionary(
982 base::DictionaryValue* strings) {
983 NOTREACHED();
986 void SafeBrowsingBlockingPageV1::PopulatePhishingStringDictionary(
987 base::DictionaryValue* strings) {
988 NOTREACHED();
991 SafeBrowsingBlockingPageV2::SafeBrowsingBlockingPageV2(
992 SafeBrowsingUIManager* ui_manager,
993 WebContents* web_contents,
994 const UnsafeResourceList& unsafe_resources)
995 : SafeBrowsingBlockingPage(ui_manager, web_contents, unsafe_resources) {
996 if (unsafe_resources_[0].threat_type == SB_THREAT_TYPE_URL_MALWARE ||
997 unsafe_resources_[0].threat_type ==
998 SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) {
999 trialCondition_ =
1000 base::FieldTrialList::FindFullName(kMalwareStudyName);
1001 } else if (unsafe_resources_[0].threat_type ==
1002 SB_THREAT_TYPE_URL_PHISHING ||
1003 unsafe_resources_[0].threat_type ==
1004 SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL) {
1005 trialCondition_ =
1006 base::FieldTrialList::FindFullName(kPhishingStudyName);
1010 std::string SafeBrowsingBlockingPageV2::GetHTMLContents() {
1011 // Load the HTML page and create the template components.
1012 base::DictionaryValue strings;
1013 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
1014 std::string html;
1016 if (unsafe_resources_.empty()) {
1017 NOTREACHED();
1018 return std::string();
1021 if (unsafe_resources_.size() > 1) {
1022 // TODO(felt): Implement new multi-threat interstitial and remove
1023 // SafeBrowsingBlockingPageV1 entirely. (http://crbug.com/160336)
1024 NOTREACHED();
1025 } else {
1026 SBThreatType threat_type = unsafe_resources_[0].threat_type;
1027 if (threat_type == SB_THREAT_TYPE_URL_MALWARE ||
1028 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) {
1029 PopulateMalwareStringDictionary(&strings);
1030 } else { // Phishing.
1031 DCHECK(threat_type == SB_THREAT_TYPE_URL_PHISHING ||
1032 threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL);
1033 PopulatePhishingStringDictionary(&strings);
1035 html = rb.GetRawDataResource(IDR_SAFE_BROWSING_MALWARE_BLOCK_V2).
1036 as_string();
1038 interstitial_show_time_ = base::TimeTicks::Now();
1039 return webui::GetTemplatesHtml(html, &strings, "template-root");
1042 void SafeBrowsingBlockingPageV2::PopulateStringDictionary(
1043 base::DictionaryValue* strings,
1044 const base::string16& title,
1045 const base::string16& headline,
1046 const base::string16& description1,
1047 const base::string16& description2,
1048 const base::string16& description3) {
1049 strings->SetString("title", title);
1050 strings->SetString("headLine", headline);
1051 strings->SetString("description1", description1);
1052 strings->SetString("description2", description2);
1053 strings->SetString("description3", description3);
1054 strings->SetBoolean("proceedDisabled",
1055 IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled));
1056 strings->SetBoolean("isMainFrame", is_main_frame_load_blocked_);
1057 strings->SetBoolean("isPhishing", interstitial_type_ == TYPE_PHISHING);
1059 strings->SetString("back_button",
1060 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_BACK_BUTTON));
1061 strings->SetString("seeMore", l10n_util::GetStringUTF16(
1062 IDS_SAFE_BROWSING_MALWARE_V2_SEE_MORE));
1063 strings->SetString("proceed",
1064 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_PROCEED_LINK));
1066 // Field trial
1067 strings->SetString("trialType", trialCondition_);
1068 if (trialCondition_ == kCond7MalwareFearMsg) {
1069 strings->SetString("headLine",
1070 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_FEAR_HEADLINE));
1071 } else if (trialCondition_ == kCond8PhishingFearMsg) {
1072 strings->SetString("headLine",
1073 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_FEAR_HEADLINE));
1074 } else if (trialCondition_ == kCond9MalwareCollabMsg) {
1075 strings->SetString("headLine",
1076 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_COLLAB_HEADLINE));
1077 } else if (trialCondition_ == kCond10PhishingCollabMsg) {
1078 strings->SetString("headLine",
1079 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_COLLAB_HEADLINE));
1080 } else if (trialCondition_ == kCond11MalwareQuestion) {
1081 strings->SetString("headLine",
1082 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_QUESTION_HEADLINE));
1083 } else if (trialCondition_ == kCond12PhishingQuestion) {
1084 strings->SetString("headLine",
1085 l10n_util::GetStringUTF16(
1086 IDS_SAFE_BROWSING_PHISHING_QUESTION_HEADLINE));
1087 } else if (trialCondition_ == kCond13MalwareGoBack) {
1088 strings->SetString("headLine",
1089 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_BACK_HEADLINE));
1090 } else if (trialCondition_ == kCond14PhishingGoBack) {
1091 strings->SetString("headLine",
1092 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_BACK_HEADLINE));
1095 webui::SetFontAndTextDirection(strings);
1098 void SafeBrowsingBlockingPageV2::PopulateMultipleThreatStringDictionary(
1099 base::DictionaryValue* strings) {
1100 NOTREACHED();
1103 void SafeBrowsingBlockingPageV2::PopulateMalwareStringDictionary(
1104 base::DictionaryValue* strings) {
1105 // Check to see if we're blocking the main page, or a sub-resource on the
1106 // main page.
1107 base::string16 headline, description1, description2, description3;
1110 description3 = l10n_util::GetStringUTF16(
1111 IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION3);
1112 if (is_main_frame_load_blocked_) {
1113 headline = l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_HEADLINE);
1114 description1 = l10n_util::GetStringFUTF16(
1115 IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION1,
1116 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
1117 base::UTF8ToUTF16(url_.host()));
1118 description2 = l10n_util::GetStringUTF16(
1119 IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION2);
1120 strings->SetString("details", l10n_util::GetStringUTF16(
1121 IDS_SAFE_BROWSING_MALWARE_V2_DETAILS));
1122 } else {
1123 headline = l10n_util::GetStringUTF16(
1124 IDS_SAFE_BROWSING_MALWARE_V2_HEADLINE_SUBRESOURCE);
1125 description1 = l10n_util::GetStringFUTF16(
1126 IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION1_SUBRESOURCE,
1127 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
1128 base::UTF8ToUTF16(web_contents_->GetURL().host()));
1129 description2 = l10n_util::GetStringFUTF16(
1130 IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION2_SUBRESOURCE,
1131 base::UTF8ToUTF16(url_.host()));
1132 strings->SetString("details", l10n_util::GetStringFUTF16(
1133 IDS_SAFE_BROWSING_MALWARE_V2_DETAILS_SUBRESOURCE,
1134 base::UTF8ToUTF16(url_.host())));
1137 PopulateStringDictionary(
1138 strings,
1139 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_TITLE),
1140 headline,
1141 description1,
1142 description2,
1143 description3);
1145 if (!CanShowMalwareDetailsOption()) {
1146 strings->SetBoolean(kDisplayCheckBox, false);
1147 strings->SetString("confirm_text", std::string());
1148 strings->SetString(kBoxChecked, std::string());
1149 } else {
1150 // Show the checkbox for sending malware details.
1151 strings->SetBoolean(kDisplayCheckBox, true);
1153 std::string privacy_link = base::StringPrintf(
1154 kPrivacyLinkHtml,
1155 l10n_util::GetStringUTF8(
1156 IDS_SAFE_BROWSING_PRIVACY_POLICY_PAGE_V2).c_str());
1158 strings->SetString("confirm_text",
1159 l10n_util::GetStringFUTF16(
1160 IDS_SAFE_BROWSING_MALWARE_V2_REPORTING_AGREE,
1161 base::UTF8ToUTF16(privacy_link)));
1162 if (IsPrefEnabled(prefs::kSafeBrowsingReportingEnabled))
1163 strings->SetString(kBoxChecked, "yes");
1164 else
1165 strings->SetString(kBoxChecked, std::string());
1168 strings->SetString("report_error", base::string16());
1169 strings->SetString("learnMore",
1170 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_LEARN_MORE));
1173 void SafeBrowsingBlockingPageV2::PopulatePhishingStringDictionary(
1174 base::DictionaryValue* strings) {
1175 PopulateStringDictionary(
1176 strings,
1177 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_V2_TITLE),
1178 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_V2_HEADLINE),
1179 l10n_util::GetStringFUTF16(IDS_SAFE_BROWSING_PHISHING_V2_DESCRIPTION1,
1180 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
1181 base::UTF8ToUTF16(url_.host())),
1182 base::string16(),
1183 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_V2_DESCRIPTION2));
1185 strings->SetString("details", std::string());
1186 strings->SetString("confirm_text", std::string());
1187 strings->SetString(kBoxChecked, std::string());
1188 strings->SetString(
1189 "report_error",
1190 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_V2_REPORT_ERROR));
1191 strings->SetBoolean(kDisplayCheckBox, false);
1192 strings->SetString("learnMore",
1193 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_LEARN_MORE));