Trick to Bill Interstitial Page

Add a Safe Browsing Interstitial Page for Trick to Bill.

Add a Trick to Bill enum to SBThreatType and
SBInterstitialReason.

Overview CL:
https://chromium-review.googlesource.com/c/chromium/src/+/1148598

Testing:
- SafeBrowsingBlockingPageTest.TrickToBillPage unit test

Bug: 867518
Change-Id: I0f5c342f419c2f326c7f25fa7e965d47ed242bbd
Reviewed-on: https://chromium-review.googlesource.com/1150917
Reviewed-by: Varun Khaneja <[email protected]>
Reviewed-by: Mustafa Emre Acer <[email protected]>
Commit-Queue: Sarah Chan <[email protected]>
Cr-Commit-Position: refs/heads/master@{#579442}
diff --git a/components/safe_browsing/base_blocking_page.cc b/components/safe_browsing/base_blocking_page.cc
index 1e84e464..8062424 100644
--- a/components/safe_browsing/base_blocking_page.cc
+++ b/components/safe_browsing/base_blocking_page.cc
@@ -239,6 +239,9 @@
       return primary_subresource ? "malware_subresource" : "malware";
     case BaseSafeBrowsingErrorUI::SB_REASON_HARMFUL:
       return primary_subresource ? "harmful_subresource" : "harmful";
+    case BaseSafeBrowsingErrorUI::SB_REASON_TRICK_TO_BILL:
+      return primary_subresource ? "trick_to_bill_subresource"
+                                 : "trick_to_bill";
     case BaseSafeBrowsingErrorUI::SB_REASON_PHISHING:
       ThreatPatternType threat_pattern_type =
           unsafe_resources[0].threat_metadata.threat_pattern_type;
@@ -291,10 +294,15 @@
        iter != unsafe_resources.end(); ++iter) {
     const BaseUIManager::UnsafeResource& resource = *iter;
     safe_browsing::SBThreatType threat_type = resource.threat_type;
+    if (threat_type == SB_THREAT_TYPE_TRICK_TO_BILL)
+      return BaseSafeBrowsingErrorUI::SB_REASON_TRICK_TO_BILL;
+
     if (threat_type == SB_THREAT_TYPE_URL_MALWARE ||
         threat_type == SB_THREAT_TYPE_URL_CLIENT_SIDE_MALWARE) {
       return BaseSafeBrowsingErrorUI::SB_REASON_MALWARE;
-    } else if (threat_type == SB_THREAT_TYPE_URL_UNWANTED) {
+    }
+
+    if (threat_type == SB_THREAT_TYPE_URL_UNWANTED) {
       harmful = true;
     } else {
       DCHECK(threat_type == SB_THREAT_TYPE_URL_PHISHING ||
diff --git a/components/safe_browsing/db/v4_protocol_manager_util.h b/components/safe_browsing/db/v4_protocol_manager_util.h
index e89a204..36004b92 100644
--- a/components/safe_browsing/db/v4_protocol_manager_util.h
+++ b/components/safe_browsing/db/v4_protocol_manager_util.h
@@ -140,6 +140,9 @@
 
   // Enterprise password reuse detected on low reputation page,
   SB_THREAT_TYPE_ENTERPRISE_PASSWORD_REUSE,
+
+  // Deceptive mobile billing practice detected.
+  SB_THREAT_TYPE_TRICK_TO_BILL,
 };
 
 using SBThreatTypeSet = base::flat_set<SBThreatType>;
diff --git a/components/security_interstitials/core/base_safe_browsing_error_ui.h b/components/security_interstitials/core/base_safe_browsing_error_ui.h
index a7faf19..ff74c5a 100644
--- a/components/security_interstitials/core/base_safe_browsing_error_ui.h
+++ b/components/security_interstitials/core/base_safe_browsing_error_ui.h
@@ -23,6 +23,7 @@
     SB_REASON_MALWARE,
     SB_REASON_HARMFUL,
     SB_REASON_PHISHING,
+    SB_REASON_TRICK_TO_BILL,
   };
 
   struct SBErrorDisplayOptions {
diff --git a/components/security_interstitials/core/browser/resources/extended_reporting.js b/components/security_interstitials/core/browser/resources/extended_reporting.js
index 8acc16a..96da18e 100644
--- a/components/security_interstitials/core/browser/resources/extended_reporting.js
+++ b/components/security_interstitials/core/browser/resources/extended_reporting.js
@@ -26,9 +26,14 @@
   $('opt-in-checkbox').checked = loadTimeData.getBoolean(SB_BOX_CHECKED);
   $('extended-reporting-opt-in').classList.remove('hidden');
 
-  var className = interstitialType == 'SAFEBROWSING' ?
-                  'safe-browsing-opt-in' :
-                  'ssl-opt-in';
+  var trickToBill = interstitialType == 'SAFEBROWSING' &&
+                    loadTimeData.getBoolean('trick_to_bill');
+
+  var className = 'ssl-opt-in';
+  if (interstitialType == 'SAFEBROWSING' && !trickToBill) {
+    className = 'safe-browsing-opt-in';
+  }
+
   $('extended-reporting-opt-in').classList.add(className);
 
   $('body').classList.add('extended-reporting-has-checkbox');
diff --git a/components/security_interstitials/core/browser/resources/interstitial_large.html b/components/security_interstitials/core/browser/resources/interstitial_large.html
index cdb7392a..d5c9989 100644
--- a/components/security_interstitials/core/browser/resources/interstitial_large.html
+++ b/components/security_interstitials/core/browser/resources/interstitial_large.html
@@ -47,6 +47,7 @@
     </div>
     <div class="nav-wrapper">
       <button id="primary-button">$i18n{primaryButtonText}</button>
+      <button id="proceed-button" class="small-link hidden"></button>
       <button id="details-button" class="small-link">
         $i18n{openDetails}
       </button>
diff --git a/components/security_interstitials/core/browser/resources/interstitial_large.js b/components/security_interstitials/core/browser/resources/interstitial_large.js
index d57ec694..ffa979b 100644
--- a/components/security_interstitials/core/browser/resources/interstitial_large.js
+++ b/components/security_interstitials/core/browser/resources/interstitial_large.js
@@ -68,6 +68,8 @@
   var ssl = interstitialType == 'SSL';
   var captivePortal = interstitialType == 'CAPTIVE_PORTAL';
   var badClock = ssl && loadTimeData.getBoolean('bad_clock');
+  var trickToBill = interstitialType == 'SAFEBROWSING' &&
+                    loadTimeData.getBoolean('trick_to_bill');
   var hidePrimaryButton = loadTimeData.getBoolean('hide_primary_button');
   var showRecurrentErrorParagraph = loadTimeData.getBoolean(
     'show_recurrent_error_paragraph');
@@ -78,6 +80,8 @@
     $('error-code').classList.remove(HIDDEN_CLASS);
   } else if (captivePortal) {
     $('body').classList.add('captive-portal');
+  } else if (trickToBill) {
+    $('body').classList.add('safe-browsing-trick-to-bill');
   } else {
     $('body').classList.add('safe-browsing');
     // Override the default theme color.
@@ -116,17 +120,23 @@
   }
 
   if (overridable) {
+    var overrideElement = trickToBill ? 'proceed-button' : 'proceed-link';
     // Captive portal page isn't overridable.
-    $('proceed-link').addEventListener('click', function(event) {
+    $(overrideElement).addEventListener('click', function(event) {
       sendCommand(SecurityInterstitialCommandId.CMD_PROCEED);
     });
+
+    if (ssl) {
+      $(overrideElement).classList.add('small-link');
+    } else if (trickToBill) {
+      $(overrideElement).classList.remove(HIDDEN_CLASS);
+      $(overrideElement).textContent =
+          loadTimeData.getString('proceedButtonText');
+    }
   } else if (!ssl) {
     $('final-paragraph').classList.add(HIDDEN_CLASS);
   }
 
-  if (ssl && overridable) {
-    $('proceed-link').classList.add('small-link');
-  }
 
   if (!ssl || !showRecurrentErrorParagraph) {
     $('recurrent-error-message').classList.add(HIDDEN_CLASS);
@@ -146,8 +156,8 @@
     });
   }
 
-  if (captivePortal) {
-    // Captive portal page doesn't have details button.
+  if (captivePortal || trickToBill) {
+    // Captive portal and trick-to-bill pages don't have details button.
     $('details-button').classList.add('hidden');
   } else {
     $('details-button').addEventListener('click', function(event) {
diff --git a/components/security_interstitials/core/browser/resources/interstitial_safebrowsing.css b/components/security_interstitials/core/browser/resources/interstitial_safebrowsing.css
index c274cd4..77d1e8e8 100644
--- a/components/security_interstitials/core/browser/resources/interstitial_safebrowsing.css
+++ b/components/security_interstitials/core/browser/resources/interstitial_safebrowsing.css
@@ -42,4 +42,22 @@
     background: rgb(206, 52, 38);
     box-shadow: 0 -22px 40px rgb(206, 52, 38);
   }
-}
\ No newline at end of file
+}
+
+.safe-browsing-trick-to-bill .small-link {
+  background-color: white;
+  border:none;
+  float: none;
+}
+
+.safe-browsing-trick-to-bill .small-link:hover {
+  box-shadow: none;
+}
+
+.safe-browsing-trick-to-bill .icon {
+  background-image: -webkit-image-set(
+      url(images/1x/triangle_red.png) 1x,
+      url(images/2x/triangle_red.png) 2x);
+}
+
+
diff --git a/components/security_interstitials/core/browser/resources/list_of_interstitials.html b/components/security_interstitials/core/browser/resources/list_of_interstitials.html
index 6da45f27..2826628 100644
--- a/components/security_interstitials/core/browser/resources/list_of_interstitials.html
+++ b/components/security_interstitials/core/browser/resources/list_of_interstitials.html
@@ -71,6 +71,9 @@
     <li>
       <a href="safebrowsing?type=clientside_phishing">Client Side Phishing</a>
     </li>
+    <li>
+      <a href="safebrowsing?type=trick_to_bill">Trick To Bill</a>
+    </li>
   </ul>
   <h4>Quiet (WebView)</h4>
   <ul>
diff --git a/components/security_interstitials/core/common/resources/interstitial_common.css b/components/security_interstitials/core/common/resources/interstitial_common.css
index 7fd721d..b624669 100644
--- a/components/security_interstitials/core/common/resources/interstitial_common.css
+++ b/components/security_interstitials/core/common/resources/interstitial_common.css
@@ -26,7 +26,8 @@
 .neterror button,
 .offline button,
 .pdf button,
-.ssl button {
+.ssl button,
+.safe-browsing-trick-to-bill button {
   background: rgb(66, 133, 244);
 }
 
diff --git a/components/security_interstitials/core/safe_browsing_loud_error_ui.cc b/components/security_interstitials/core/safe_browsing_loud_error_ui.cc
index 2003d5d..2251a97c 100644
--- a/components/security_interstitials/core/safe_browsing_loud_error_ui.cc
+++ b/components/security_interstitials/core/safe_browsing_loud_error_ui.cc
@@ -93,6 +93,10 @@
       "hide_primary_button",
       always_show_back_to_safety() ? false : !controller()->CanGoBack());
 
+  load_time_data->SetBoolean(
+      "trick_to_bill", interstitial_reason() ==
+                           BaseSafeBrowsingErrorUI::SB_REASON_TRICK_TO_BILL);
+
   switch (interstitial_reason()) {
     case BaseSafeBrowsingErrorUI::SB_REASON_MALWARE:
       PopulateMalwareLoadTimeData(load_time_data);
@@ -103,6 +107,9 @@
     case BaseSafeBrowsingErrorUI::SB_REASON_PHISHING:
       PopulatePhishingLoadTimeData(load_time_data);
       break;
+    case BaseSafeBrowsingErrorUI::SB_REASON_TRICK_TO_BILL:
+      PopulateTrickToBillLoadTimeData(load_time_data);
+      break;
   }
 
   // Not used by this interstitial.
@@ -309,6 +316,31 @@
                              is_extended_reporting_enabled());
 }
 
+void SafeBrowsingLoudErrorUI::PopulateTrickToBillLoadTimeData(
+    base::DictionaryValue* load_time_data) {
+  load_time_data->SetBoolean("phishing", false);
+  load_time_data->SetBoolean("overridable", true);
+  load_time_data->SetBoolean("hide_primary_button", false);
+
+  load_time_data->SetString(
+      "heading", l10n_util::GetStringUTF16(IDS_TRICK_TO_BILL_HEADING));
+  load_time_data->SetString(
+      "primaryParagraph",
+      l10n_util::GetStringUTF16(IDS_TRICK_TO_BILL_PRIMARY_PARAGRAPH));
+
+  load_time_data->SetString(
+      "primaryButtonText",
+      l10n_util::GetStringUTF16(IDS_TRICK_TO_BILL_PRIMARY_BUTTON));
+  load_time_data->SetString(
+      "proceedButtonText",
+      l10n_util::GetStringUTF16(IDS_TRICK_TO_BILL_PROCEED_BUTTON));
+
+  load_time_data->SetString("openDetails", "");
+  load_time_data->SetString("closeDetails", "");
+  load_time_data->SetString("explanationParagraph", "");
+  load_time_data->SetString("finalParagraph", "");
+}
+
 int SafeBrowsingLoudErrorUI::GetHTMLTemplateId() const {
   return IDR_SECURITY_INTERSTITIAL_HTML;
 };
diff --git a/components/security_interstitials/core/safe_browsing_loud_error_ui.h b/components/security_interstitials/core/safe_browsing_loud_error_ui.h
index db4cdbf..46e92ac 100644
--- a/components/security_interstitials/core/safe_browsing_loud_error_ui.h
+++ b/components/security_interstitials/core/safe_browsing_loud_error_ui.h
@@ -47,6 +47,7 @@
   void PopulateMalwareLoadTimeData(base::DictionaryValue* load_time_data);
   void PopulateHarmfulLoadTimeData(base::DictionaryValue* load_time_data);
   void PopulatePhishingLoadTimeData(base::DictionaryValue* load_time_data);
+  void PopulateTrickToBillLoadTimeData(base::DictionaryValue* load_time_data);
 
   DISALLOW_COPY_AND_ASSIGN(SafeBrowsingLoudErrorUI);
 };
diff --git a/components/security_interstitials_strings.grdp b/components/security_interstitials_strings.grdp
index c372493..96bc094 100644
--- a/components/security_interstitials_strings.grdp
+++ b/components/security_interstitials_strings.grdp
@@ -381,4 +381,18 @@
       &lt;/ol&gt;
     </message>
   </if>
+
+  <!-- Trick to Bill interstitial -->
+  <message name="IDS_TRICK_TO_BILL_HEADING" desc="The large heading at the top of the trick to bill interstitial.">
+    The page ahead may try to charge you money
+  </message>
+  <message name="IDS_TRICK_TO_BILL_PRIMARY_PARAGRAPH" desc="The primary explanatory paragraph for the trick to bill interstitial.">
+    These charges could be one-time or recurring and may not be obvious.
+  </message>
+  <message name="IDS_TRICK_TO_BILL_PRIMARY_BUTTON" desc="The text for the trick to bill interstitial primary button.">
+    Go Back
+  </message>
+  <message name="IDS_TRICK_TO_BILL_PROCEED_BUTTON" desc="The text for the trick to bill interstitial proceed button.">
+    Proceed
+  </message>
 </grit-part>
diff --git a/components/security_interstitials_strings_grdp/IDS_TRICK_TO_BILL_HEADING.png.sha1 b/components/security_interstitials_strings_grdp/IDS_TRICK_TO_BILL_HEADING.png.sha1
new file mode 100644
index 0000000..840018ae
--- /dev/null
+++ b/components/security_interstitials_strings_grdp/IDS_TRICK_TO_BILL_HEADING.png.sha1
@@ -0,0 +1 @@
+daf13e4d1d9d61fd9c357af7b52e3fb52c02e7f8
\ No newline at end of file
diff --git a/components/security_interstitials_strings_grdp/IDS_TRICK_TO_BILL_PRIMARY_BUTTON.png.sha1 b/components/security_interstitials_strings_grdp/IDS_TRICK_TO_BILL_PRIMARY_BUTTON.png.sha1
new file mode 100644
index 0000000..840018ae
--- /dev/null
+++ b/components/security_interstitials_strings_grdp/IDS_TRICK_TO_BILL_PRIMARY_BUTTON.png.sha1
@@ -0,0 +1 @@
+daf13e4d1d9d61fd9c357af7b52e3fb52c02e7f8
\ No newline at end of file
diff --git a/components/security_interstitials_strings_grdp/IDS_TRICK_TO_BILL_PRIMARY_PARAGRAPH.png.sha1 b/components/security_interstitials_strings_grdp/IDS_TRICK_TO_BILL_PRIMARY_PARAGRAPH.png.sha1
new file mode 100644
index 0000000..840018ae
--- /dev/null
+++ b/components/security_interstitials_strings_grdp/IDS_TRICK_TO_BILL_PRIMARY_PARAGRAPH.png.sha1
@@ -0,0 +1 @@
+daf13e4d1d9d61fd9c357af7b52e3fb52c02e7f8
\ No newline at end of file
diff --git a/components/security_interstitials_strings_grdp/IDS_TRICK_TO_BILL_PROCEED_BUTTON.png.sha1 b/components/security_interstitials_strings_grdp/IDS_TRICK_TO_BILL_PROCEED_BUTTON.png.sha1
new file mode 100644
index 0000000..840018ae
--- /dev/null
+++ b/components/security_interstitials_strings_grdp/IDS_TRICK_TO_BILL_PROCEED_BUTTON.png.sha1
@@ -0,0 +1 @@
+daf13e4d1d9d61fd9c357af7b52e3fb52c02e7f8
\ No newline at end of file