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.
5 // Implementation of the SafeBrowsingBlockingPage class.
7 #include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h"
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
;
57 // For malware interstitial pages, we link the problematic URL to Google's
59 #if defined(GOOGLE_CHROME_BUILD)
60 const char* const kSbDiagnosticUrl
=
61 "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=%s&client=googlechrome";
63 const char* const kSbDiagnosticUrl
=
64 "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=%s&client=chromium";
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
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
,
143 void RecordDetailedUserAction(DetailedDecision decision
) {
144 UMA_HISTOGRAM_ENUMERATION("SB2.InterstitialActionDetails",
146 MAX_DETAILED_ACTION
);
152 SafeBrowsingBlockingPageFactory
* SafeBrowsingBlockingPage::factory_
= NULL
;
154 // The default SafeBrowsingBlockingPageFactory. Global, made a singleton so we
156 class SafeBrowsingBlockingPageFactoryImpl
157 : public SafeBrowsingBlockingPageFactory
{
159 virtual SafeBrowsingBlockingPage
* CreateSafeBrowsingPage(
160 SafeBrowsingUIManager
* ui_manager
,
161 WebContents
* web_contents
,
162 const SafeBrowsingBlockingPage::UnsafeResourceList
& unsafe_resources
)
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
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
,
177 return new SafeBrowsingBlockingPageV1(ui_manager
, web_contents
,
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
),
201 is_main_frame_load_blocked_(IsMainPageLoadBlocked(unsafe_resources
)),
202 unsafe_resources_(unsafe_resources
),
204 web_contents_(web_contents
),
205 url_(unsafe_resources
[0].url
),
206 has_expanded_see_more_section_(false),
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
) {
218 DCHECK(threat_type
== SB_THREAT_TYPE_URL_PHISHING
||
219 threat_type
== SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL
);
223 DCHECK(phishing
|| malware
);
224 if (malware
&& phishing
)
225 interstitial_type_
= TYPE_MALWARE_AND_PHISHING
;
227 interstitial_type_
= TYPE_MALWARE
;
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(
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();
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
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);
286 if (command
== kDontReportCommand
) {
287 SetReportingPreference(false);
291 if (command
== kLearnMoreCommand
) {
292 // User pressed "Learn more".
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
));
305 OpenURLParams
params(
306 url
, Referrer(), CURRENT_TAB
, content::PAGE_TRANSITION_LINK
, false);
307 web_contents_
->OpenURL(params
);
311 if (command
== kLearnMoreCommandV2
) {
312 // User pressed "Learn more".
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
));
325 OpenURLParams
params(
326 url
, Referrer(), CURRENT_TAB
, content::PAGE_TRANSITION_LINK
, false);
327 web_contents_
->OpenURL(params
);
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
);
340 bool proceed_blocked
= false;
341 if (command
== kProceedCommand
) {
342 if (IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled
)) {
343 proceed_blocked
= true;
345 interstitial_page_
->Proceed();
346 // |this| has been deleted after Proceed() returns.
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.
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();
365 web_contents_
->GetController().LoadURL(
366 GURL(chrome::kChromeUINewTabURL
),
368 content::PAGE_TRANSITION_AUTO_TOPLEVEL
,
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);
381 bool result
= base::StringToInt(base::StringPiece(command
.begin() +
385 command
= command
.substr(0, colon_index
);
387 element_index
= static_cast<size_t>(result_int
);
390 if (element_index
>= unsafe_resources_
.size()) {
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
);
404 safe_browsing_util::GeneratePhishingReportUrl(
405 kSbReportPhishingErrorUrl
,
407 threat_type
== SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL
);
408 OpenURLParams
params(
409 report_url
, Referrer(), CURRENT_TAB
, content::PAGE_TRANSITION_LINK
,
411 web_contents_
->OpenURL(params
);
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
,
429 web_contents_
->OpenURL(params
);
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
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() {
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_
,
477 unsafe_resource_map
->erase(iter
);
480 // Now that this interstitial is gone, we can show the new one.
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.
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
,
527 base::Time first_visit
) {
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.
537 MALWARE_DONT_PROCEED
,
538 MALWARE_FORCED_DONT_PROCEED
,
541 MULTIPLE_DONT_PROCEED
,
542 MULTIPLE_FORCED_DONT_PROCEED
,
545 PHISHING_DONT_PROCEED
,
546 PHISHING_FORCED_DONT_PROCEED
,
548 MALWARE_SHOW_ADVANCED
,
549 MULTIPLE_SHOW_ADVANCED
,
550 PHISHING_SHOW_ADVANCED
,
552 } histogram_action
= MAX_ACTION
;
556 switch (interstitial_type_
) {
557 case TYPE_MALWARE_AND_PHISHING
:
558 histogram_action
= MULTIPLE_SHOW
;
561 histogram_action
= MALWARE_SHOW
;
564 histogram_action
= PHISHING_SHOW
;
569 switch (interstitial_type_
) {
570 case TYPE_MALWARE_AND_PHISHING
:
571 histogram_action
= MULTIPLE_PROCEED
;
574 histogram_action
= MALWARE_PROCEED
;
577 histogram_action
= PHISHING_PROCEED
;
582 if (IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled
)) {
583 switch (interstitial_type_
) {
584 case TYPE_MALWARE_AND_PHISHING
:
585 histogram_action
= MULTIPLE_FORCED_DONT_PROCEED
;
588 histogram_action
= MALWARE_FORCED_DONT_PROCEED
;
591 histogram_action
= PHISHING_FORCED_DONT_PROCEED
;
595 switch (interstitial_type_
) {
596 case TYPE_MALWARE_AND_PHISHING
:
597 histogram_action
= MULTIPLE_DONT_PROCEED
;
600 histogram_action
= MALWARE_DONT_PROCEED
;
603 histogram_action
= PHISHING_DONT_PROCEED
;
609 switch (interstitial_type_
) {
610 case TYPE_MALWARE_AND_PHISHING
:
611 histogram_action
= MULTIPLE_SHOW_ADVANCED
;
614 histogram_action
= MALWARE_SHOW_ADVANCED
;
617 histogram_action
= PHISHING_SHOW_ADVANCED
;
622 NOTREACHED() << "Unexpected event: " << event
;
624 if (histogram_action
== MAX_ACTION
) {
627 UMA_HISTOGRAM_ENUMERATION("SB2.InterstitialAction", histogram_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");
658 action
.append("Malware");
661 action
.append("Phishing");
667 action
.append("Show");
670 action
.append("Proceed");
673 if (IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled
))
674 action
.append("ForcedDontProceed");
676 action
.append("DontProceed");
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",
711 } else if (command
== kLearnMoreCommand
|| command
== kLearnMoreCommandV2
) {
712 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialLearnMore",
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
719 if (has_expanded_see_more_section_
)
721 RecordUserAction(SHOW_ADVANCED
);
722 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeExpandedSeeMore",
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.
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
746 if (has_expanded_see_more_section_
)
748 RecordUserAction(SHOW_ADVANCED
);
749 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeExpandedSeeMore",
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.
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
);
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
) {
780 Profile::FromBrowserContext(web_contents_
->GetBrowserContext());
781 return profile
->GetPrefs()->GetBoolean(pref
);
785 void SafeBrowsingBlockingPage::NotifySafeBrowsingUIManager(
786 SafeBrowsingUIManager
* ui_manager
,
787 const UnsafeResourceList
& unsafe_resources
,
789 BrowserThread::PostTask(
790 BrowserThread::IO
, FROM_HERE
,
791 base::Bind(&SafeBrowsingUIManager::OnBlockingPageDone
,
792 ui_manager
, unsafe_resources
, proceed
));
796 SafeBrowsingBlockingPage::UnsafeResourceMap
*
797 SafeBrowsingBlockingPage::GetUnsafeResourcesMap() {
798 return g_unsafe_resource_map
.Pointer();
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
815 interstitial
->DontProceed();
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).
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();
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
);
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
) {
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();
866 if (unsafe_resources_
.empty()) {
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
);
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(
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
),
945 PopulateStringDictionary(
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
));
958 PopulateStringDictionary(
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())),
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
) {
986 void SafeBrowsingBlockingPageV1::PopulatePhishingStringDictionary(
987 base::DictionaryValue
* strings
) {
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
) {
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
) {
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();
1016 if (unsafe_resources_
.empty()) {
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)
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
).
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
));
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
) {
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
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
));
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(
1139 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_TITLE
),
1145 if (!CanShowMalwareDetailsOption()) {
1146 strings
->SetBoolean(kDisplayCheckBox
, false);
1147 strings
->SetString("confirm_text", std::string());
1148 strings
->SetString(kBoxChecked
, std::string());
1150 // Show the checkbox for sending malware details.
1151 strings
->SetBoolean(kDisplayCheckBox
, true);
1153 std::string privacy_link
= base::StringPrintf(
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");
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(
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())),
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());
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
));