| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 // Implementation of the SafeBrowsingBlockingPage class. | 5 // Implementation of the SafeBrowsingBlockingPage class. |
| 6 | 6 |
| 7 #include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h" | 7 #include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h" |
| 8 | 8 |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 | 64 |
| 65 static const char* const kSbReportPhishingErrorUrl = | 65 static const char* const kSbReportPhishingErrorUrl = |
| 66 "http://www.google.com/safebrowsing/report_error/"; | 66 "http://www.google.com/safebrowsing/report_error/"; |
| 67 | 67 |
| 68 // URL for the "Learn more" link on the multi threat malware blocking page. | 68 // URL for the "Learn more" link on the multi threat malware blocking page. |
| 69 static const char* const kLearnMoreMalwareUrl = | 69 static const char* const kLearnMoreMalwareUrl = |
| 70 "https://www.google.com/support/bin/answer.py?answer=45449&topic=360" | 70 "https://www.google.com/support/bin/answer.py?answer=45449&topic=360" |
| 71 "&sa=X&oi=malwarewarninglink&resnum=1&ct=help"; | 71 "&sa=X&oi=malwarewarninglink&resnum=1&ct=help"; |
| 72 static const char* const kLearnMoreMalwareUrlV2 = | 72 static const char* const kLearnMoreMalwareUrlV2 = |
| 73 "https://www.google.com/goodtoknow/online-safety/malware/"; | 73 "https://www.google.com/goodtoknow/online-safety/malware/"; |
| 74 static const char* const kLearnMorePhishingUrlV2 = |
| 75 "https://www.google.com/goodtoknow/online-safety/phishing/"; |
| 74 | 76 |
| 75 // URL for the "Learn more" link on the phishing blocking page. | 77 // URL for the "Learn more" link on the phishing blocking page. |
| 76 static const char* const kLearnMorePhishingUrl = | 78 static const char* const kLearnMorePhishingUrl = |
| 77 "https://www.google.com/support/bin/answer.py?answer=106318"; | 79 "https://www.google.com/support/bin/answer.py?answer=106318"; |
| 78 | 80 |
| 79 static const char* const kSbDiagnosticHtml = | 81 static const char* const kSbDiagnosticHtml = |
| 80 "<a href=\"\" onclick=\"sendCommand('showDiagnostic'); return false;\" " | 82 "<a href=\"\" onclick=\"sendCommand('showDiagnostic'); return false;\" " |
| 81 "onmousedown=\"return false;\">%s</a>"; | 83 "onmousedown=\"return false;\">%s</a>"; |
| 82 | 84 |
| 83 static const char* const kPLinkHtml = | 85 static const char* const kPLinkHtml = |
| 84 "<a href=\"\" onclick=\"sendCommand('proceed'); return false;\" " | 86 "<a href=\"\" onclick=\"sendCommand('proceed'); return false;\" " |
| 85 "onmousedown=\"return false;\">%s</a>"; | 87 "onmousedown=\"return false;\">%s</a>"; |
| 86 | 88 |
| 87 static const char* const kPrivacyLinkHtml = | 89 static const char* const kPrivacyLinkHtml = |
| 88 "<a href=\"\" onclick=\"sendCommand('showPrivacy'); return false;\" " | 90 "<a id=\"privacy-link\" href=\"\" onclick=\"sendCommand('showPrivacy'); " |
| 89 "onmousedown=\"return false;\">%s</a>"; | 91 "return false;\" onmousedown=\"return false;\">%s</a>"; |
| 90 | 92 |
| 91 // After a malware interstitial where the user opted-in to the report | 93 // After a malware interstitial where the user opted-in to the report |
| 92 // but clicked "proceed anyway", we delay the call to | 94 // but clicked "proceed anyway", we delay the call to |
| 93 // MalwareDetails::FinishCollection() by this much time (in | 95 // MalwareDetails::FinishCollection() by this much time (in |
| 94 // milliseconds). | 96 // milliseconds). |
| 95 static const int64 kMalwareDetailsProceedDelayMilliSeconds = 3000; | 97 static const int64 kMalwareDetailsProceedDelayMilliSeconds = 3000; |
| 96 | 98 |
| 97 // The commands returned by the page when the user performs an action. | 99 // The commands returned by the page when the user performs an action. |
| 98 static const char* const kShowDiagnosticCommand = "showDiagnostic"; | 100 static const char* const kShowDiagnosticCommand = "showDiagnostic"; |
| 99 static const char* const kReportErrorCommand = "reportError"; | 101 static const char* const kReportErrorCommand = "reportError"; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 120 | 122 |
| 121 // The default SafeBrowsingBlockingPageFactory. Global, made a singleton so we | 123 // The default SafeBrowsingBlockingPageFactory. Global, made a singleton so we |
| 122 // don't leak it. | 124 // don't leak it. |
| 123 class SafeBrowsingBlockingPageFactoryImpl | 125 class SafeBrowsingBlockingPageFactoryImpl |
| 124 : public SafeBrowsingBlockingPageFactory { | 126 : public SafeBrowsingBlockingPageFactory { |
| 125 public: | 127 public: |
| 126 SafeBrowsingBlockingPage* CreateSafeBrowsingPage( | 128 SafeBrowsingBlockingPage* CreateSafeBrowsingPage( |
| 127 SafeBrowsingService* service, | 129 SafeBrowsingService* service, |
| 128 WebContents* web_contents, | 130 WebContents* web_contents, |
| 129 const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources) { | 131 const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources) { |
| 130 // Only do the trial if the interstitial is for a single malware resource, | 132 // Only do the trial if the interstitial is for a single malware or |
| 131 // the other types of interstitials have not been updated to V2 yet. | 133 // phishing resource, the multi-threat interstitial has not been updated to |
| 134 // V2 yet. |
| 132 if (unsafe_resources.size() == 1 && | 135 if (unsafe_resources.size() == 1 && |
| 133 unsafe_resources[0].threat_type == SafeBrowsingService::URL_MALWARE) { | 136 (unsafe_resources[0].threat_type == SafeBrowsingService::URL_MALWARE || |
| 137 unsafe_resources[0].threat_type == |
| 138 SafeBrowsingService::URL_PHISHING)) { |
| 134 if (base::FieldTrialList::FindFullName("SBInterstitial") == "V2") { | 139 if (base::FieldTrialList::FindFullName("SBInterstitial") == "V2") { |
| 135 DVLOG(1) << "In V2 group."; | 140 DVLOG(1) << "In V2 group."; |
| 136 return new SafeBrowsingBlockingPageV2(service, web_contents, | 141 return new SafeBrowsingBlockingPageV2(service, web_contents, |
| 137 unsafe_resources); | 142 unsafe_resources); |
| 138 } | 143 } |
| 139 DVLOG(1) << "In V1 group."; | 144 DVLOG(1) << "In V1 group."; |
| 140 } | 145 } |
| 141 return new SafeBrowsingBlockingPageV1(service, web_contents, | 146 return new SafeBrowsingBlockingPageV1(service, web_contents, |
| 142 unsafe_resources); | 147 unsafe_resources); |
| 143 } | 148 } |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 return; | 264 return; |
| 260 } | 265 } |
| 261 | 266 |
| 262 if (command == kLearnMoreCommandV2) { | 267 if (command == kLearnMoreCommandV2) { |
| 263 // User pressed "Learn more". | 268 // User pressed "Learn more". |
| 264 GURL url; | 269 GURL url; |
| 265 SafeBrowsingService::UrlCheckResult threat_type = | 270 SafeBrowsingService::UrlCheckResult threat_type = |
| 266 unsafe_resources_[0].threat_type; | 271 unsafe_resources_[0].threat_type; |
| 267 if (threat_type == SafeBrowsingService::URL_MALWARE) { | 272 if (threat_type == SafeBrowsingService::URL_MALWARE) { |
| 268 url = google_util::AppendGoogleLocaleParam(GURL(kLearnMoreMalwareUrlV2)); | 273 url = google_util::AppendGoogleLocaleParam(GURL(kLearnMoreMalwareUrlV2)); |
| 274 } else if (threat_type == SafeBrowsingService::URL_PHISHING || |
| 275 threat_type == SafeBrowsingService::CLIENT_SIDE_PHISHING_URL) { |
| 276 url = google_util::AppendGoogleLocaleParam(GURL(kLearnMorePhishingUrlV2)); |
| 269 } else { | 277 } else { |
| 270 NOTREACHED(); | 278 NOTREACHED(); |
| 271 } | 279 } |
| 272 | 280 |
| 273 OpenURLParams params( | 281 OpenURLParams params( |
| 274 url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK, false); | 282 url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK, false); |
| 275 web_contents_->OpenURL(params); | 283 web_contents_->OpenURL(params); |
| 276 return; | 284 return; |
| 277 } | 285 } |
| 278 | 286 |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 633 "SB2.MalwareInterstitialLearnMore", "SBInterstitial"), dt); | 641 "SB2.MalwareInterstitialLearnMore", "SBInterstitial"), dt); |
| 634 } else if (command == kNavigatedAwayMetaCommand) { | 642 } else if (command == kNavigatedAwayMetaCommand) { |
| 635 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeClosed", dt); | 643 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeClosed", dt); |
| 636 UMA_HISTOGRAM_MEDIUM_TIMES(base::FieldTrial::MakeName( | 644 UMA_HISTOGRAM_MEDIUM_TIMES(base::FieldTrial::MakeName( |
| 637 "SB2.MalwareInterstitialTimeClosed", "SBInterstitial"), dt); | 645 "SB2.MalwareInterstitialTimeClosed", "SBInterstitial"), dt); |
| 638 } else if (command == kExpandedSeeMore) { | 646 } else if (command == kExpandedSeeMore) { |
| 639 // Only record the expanded histogram once per display of the | 647 // Only record the expanded histogram once per display of the |
| 640 // interstitial. | 648 // interstitial. |
| 641 if (has_expanded_see_more_section_) | 649 if (has_expanded_see_more_section_) |
| 642 return; | 650 return; |
| 651 |
| 643 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeExpandedSeeMore", | 652 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeExpandedSeeMore", |
| 644 dt); | 653 dt); |
| 645 has_expanded_see_more_section_ = true; | 654 has_expanded_see_more_section_ = true; |
| 646 // Expanding the "See More" section doesn't finish the interstitial, so | 655 // Expanding the "See More" section doesn't finish the interstitial, so |
| 647 // don't mark the reaction time as recorded. | 656 // don't mark the reaction time as recorded. |
| 648 recorded = false; | 657 recorded = false; |
| 649 } else { | 658 } else { |
| 650 recorded = false; | 659 recorded = false; |
| 651 } | 660 } |
| 652 } else { | 661 } else { |
| 653 // Same as above but for phishing warnings. | 662 // Same as above but for phishing warnings. |
| 654 if (command == kProceedCommand) { | 663 if (command == kProceedCommand) { |
| 655 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeProceed", dt); | 664 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeProceed", dt); |
| 656 } else if (command == kTakeMeBackCommand) { | 665 } else if (command == kTakeMeBackCommand) { |
| 657 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeTakeMeBack", dt); | 666 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeTakeMeBack", dt); |
| 658 } else if (command == kShowDiagnosticCommand) { | 667 } else if (command == kShowDiagnosticCommand) { |
| 659 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeReportError", dt); | 668 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeReportError", dt); |
| 660 } else if (command == kLearnMoreCommand || command == kLearnMoreCommandV2) { | 669 } else if (command == kLearnMoreCommand || command == kLearnMoreCommandV2) { |
| 661 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeLearnMore", dt); | 670 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeLearnMore", dt); |
| 662 } else if (command == kNavigatedAwayMetaCommand) { | 671 } else if (command == kNavigatedAwayMetaCommand) { |
| 663 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeClosed", dt); | 672 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeClosed", dt); |
| 664 } else if (command == kExpandedSeeMore) { | 673 } else if (command == kExpandedSeeMore) { |
| 665 // TODO(mattm): Add histogram for this when we implement V2 of the | 674 // Only record the expanded histogram once per display of the |
| 666 // phishing interstitial. | 675 // interstitial. |
| 667 NOTREACHED(); | 676 if (has_expanded_see_more_section_) |
| 677 return; |
| 678 |
| 679 UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeExpandedSeeMore", |
| 680 dt); |
| 681 has_expanded_see_more_section_ = true; |
| 682 // Expanding the "See More" section doesn't finish the interstitial, so |
| 683 // don't mark the reaction time as recorded. |
| 668 recorded = false; | 684 recorded = false; |
| 669 } else { | 685 } else { |
| 670 recorded = false; | 686 recorded = false; |
| 671 } | 687 } |
| 672 } | 688 } |
| 673 if (recorded) // Making sure we don't double-count reaction times. | 689 if (recorded) // Making sure we don't double-count reaction times. |
| 674 interstitial_show_time_ = base::TimeTicks(); // Resets the show time. | 690 interstitial_show_time_ = base::TimeTicks(); // Resets the show time. |
| 675 } | 691 } |
| 676 | 692 |
| 677 void SafeBrowsingBlockingPage::FinishMalwareDetails(int64 delay_ms) { | 693 void SafeBrowsingBlockingPage::FinishMalwareDetails(int64 delay_ms) { |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1020 return std::string(); | 1036 return std::string(); |
| 1021 } | 1037 } |
| 1022 | 1038 |
| 1023 if (unsafe_resources_.size() > 1) { | 1039 if (unsafe_resources_.size() > 1) { |
| 1024 NOTREACHED(); | 1040 NOTREACHED(); |
| 1025 } else { | 1041 } else { |
| 1026 SafeBrowsingService::UrlCheckResult threat_type = | 1042 SafeBrowsingService::UrlCheckResult threat_type = |
| 1027 unsafe_resources_[0].threat_type; | 1043 unsafe_resources_[0].threat_type; |
| 1028 if (threat_type == SafeBrowsingService::URL_MALWARE) { | 1044 if (threat_type == SafeBrowsingService::URL_MALWARE) { |
| 1029 PopulateMalwareStringDictionary(&strings); | 1045 PopulateMalwareStringDictionary(&strings); |
| 1030 html = rb.GetRawDataResource( | |
| 1031 IDR_SAFE_BROWSING_MALWARE_BLOCK_V2, | |
| 1032 ui::SCALE_FACTOR_NONE).as_string(); | |
| 1033 } else { // Phishing. | 1046 } else { // Phishing. |
| 1034 DCHECK(threat_type == SafeBrowsingService::URL_PHISHING || | 1047 DCHECK(threat_type == SafeBrowsingService::URL_PHISHING || |
| 1035 threat_type == SafeBrowsingService::CLIENT_SIDE_PHISHING_URL); | 1048 threat_type == SafeBrowsingService::CLIENT_SIDE_PHISHING_URL); |
| 1036 NOTREACHED(); | 1049 PopulatePhishingStringDictionary(&strings); |
| 1037 } | 1050 } |
| 1051 html = rb.GetRawDataResource(IDR_SAFE_BROWSING_MALWARE_BLOCK_V2, |
| 1052 ui::SCALE_FACTOR_NONE).as_string(); |
| 1038 } | 1053 } |
| 1039 interstitial_show_time_ = base::TimeTicks::Now(); | 1054 interstitial_show_time_ = base::TimeTicks::Now(); |
| 1040 return jstemplate_builder::GetTemplatesHtml(html, &strings, "template-root"); | 1055 return jstemplate_builder::GetTemplatesHtml(html, &strings, "template-root"); |
| 1041 } | 1056 } |
| 1042 | 1057 |
| 1043 void SafeBrowsingBlockingPageV2::PopulateStringDictionary( | 1058 void SafeBrowsingBlockingPageV2::PopulateStringDictionary( |
| 1044 DictionaryValue* strings, | 1059 DictionaryValue* strings, |
| 1045 const string16& title, | 1060 const string16& title, |
| 1046 const string16& headline, | 1061 const string16& headline, |
| 1047 const string16& description1, | 1062 const string16& description1, |
| 1048 const string16& description2, | 1063 const string16& description2, |
| 1049 const string16& description3) { | 1064 const string16& description3) { |
| 1050 strings->SetString("title", title); | 1065 strings->SetString("title", title); |
| 1051 strings->SetString("headLine", headline); | 1066 strings->SetString("headLine", headline); |
| 1052 strings->SetString("description1", description1); | 1067 strings->SetString("description1", description1); |
| 1053 strings->SetString("description2", description2); | 1068 strings->SetString("description2", description2); |
| 1054 strings->SetString("description3", description3); | 1069 strings->SetString("description3", description3); |
| 1055 strings->SetBoolean("proceedDisabled", | 1070 strings->SetBoolean("proceedDisabled", |
| 1056 IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled)); | 1071 IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled)); |
| 1057 strings->SetBoolean("isMainFrame", is_main_frame_load_blocked_); | 1072 strings->SetBoolean("isMainFrame", is_main_frame_load_blocked_); |
| 1073 strings->SetBoolean("isPhishing", interstitial_type_ == TYPE_PHISHING); |
| 1058 | 1074 |
| 1059 strings->SetString("back_button", | 1075 strings->SetString("back_button", |
| 1060 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_BACK_BUTTON)); | 1076 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_BACK_BUTTON)); |
| 1061 strings->SetString("seeMore", l10n_util::GetStringUTF16( | 1077 strings->SetString("seeMore", l10n_util::GetStringUTF16( |
| 1062 IDS_SAFE_BROWSING_MALWARE_V2_SEE_MORE)); | 1078 IDS_SAFE_BROWSING_MALWARE_V2_SEE_MORE)); |
| 1079 strings->SetString("proceed", |
| 1080 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_PROCEED_LINK)); |
| 1063 | 1081 |
| 1064 ChromeURLDataManager::DataSource::SetFontAndTextDirection(strings); | 1082 ChromeURLDataManager::DataSource::SetFontAndTextDirection(strings); |
| 1065 } | 1083 } |
| 1066 | 1084 |
| 1067 void SafeBrowsingBlockingPageV2::PopulateMultipleThreatStringDictionary( | 1085 void SafeBrowsingBlockingPageV2::PopulateMultipleThreatStringDictionary( |
| 1068 DictionaryValue* strings) { | 1086 DictionaryValue* strings) { |
| 1069 NOTREACHED(); | 1087 NOTREACHED(); |
| 1070 } | 1088 } |
| 1071 | 1089 |
| 1072 void SafeBrowsingBlockingPageV2::PopulateMalwareStringDictionary( | 1090 void SafeBrowsingBlockingPageV2::PopulateMalwareStringDictionary( |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1131 strings->SetString("confirm_text", | 1149 strings->SetString("confirm_text", |
| 1132 l10n_util::GetStringFUTF16( | 1150 l10n_util::GetStringFUTF16( |
| 1133 IDS_SAFE_BROWSING_MALWARE_V2_REPORTING_AGREE, | 1151 IDS_SAFE_BROWSING_MALWARE_V2_REPORTING_AGREE, |
| 1134 UTF8ToUTF16(privacy_link))); | 1152 UTF8ToUTF16(privacy_link))); |
| 1135 if (IsPrefEnabled(prefs::kSafeBrowsingReportingEnabled)) | 1153 if (IsPrefEnabled(prefs::kSafeBrowsingReportingEnabled)) |
| 1136 strings->SetString(kBoxChecked, "yes"); | 1154 strings->SetString(kBoxChecked, "yes"); |
| 1137 else | 1155 else |
| 1138 strings->SetString(kBoxChecked, ""); | 1156 strings->SetString(kBoxChecked, ""); |
| 1139 } | 1157 } |
| 1140 | 1158 |
| 1141 strings->SetString("proceed", | 1159 strings->SetString("report_error", string16()); |
| 1142 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_PROCEED_LINK)); | |
| 1143 strings->SetString("learnMore", | 1160 strings->SetString("learnMore", |
| 1144 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_LEARN_MORE)); | 1161 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_LEARN_MORE)); |
| 1145 } | 1162 } |
| 1146 | 1163 |
| 1147 void SafeBrowsingBlockingPageV2::PopulatePhishingStringDictionary( | 1164 void SafeBrowsingBlockingPageV2::PopulatePhishingStringDictionary( |
| 1148 DictionaryValue* strings) { | 1165 DictionaryValue* strings) { |
| 1149 NOTREACHED(); | 1166 PopulateStringDictionary( |
| 1167 strings, |
| 1168 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_V2_TITLE), |
| 1169 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_V2_HEADLINE), |
| 1170 l10n_util::GetStringFUTF16(IDS_SAFE_BROWSING_PHISHING_V2_DESCRIPTION1, |
| 1171 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), |
| 1172 UTF8ToUTF16(url_.host())), |
| 1173 string16(), |
| 1174 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_V2_DESCRIPTION2)); |
| 1175 |
| 1176 strings->SetString("details", ""); |
| 1177 strings->SetString("confirm_text", ""); |
| 1178 strings->SetString(kBoxChecked, ""); |
| 1179 strings->SetString("report_error", |
| 1180 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_V2_REPORT_ERROR)); |
| 1181 strings->SetBoolean(kDisplayCheckBox, false); |
| 1182 strings->SetString("learnMore", |
| 1183 l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_LEARN_MORE)); |
| 1150 } | 1184 } |
| OLD | NEW |