Add quiet safe browsing interstitial for WebView
BUG=716095
Review-Url: https://codereview.chromium.org/2854263003
Cr-Commit-Position: refs/heads/master@{#473150}
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page.h b/chrome/browser/safe_browsing/safe_browsing_blocking_page.h
index 1854a5f..63a28fe 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page.h
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page.h
@@ -83,6 +83,8 @@
protected:
friend class SafeBrowsingBlockingPageFactoryImpl;
friend class SafeBrowsingBlockingPageTest;
+ friend class SafeBrowsingBlockingQuietPageFactoryImpl;
+ friend class SafeBrowsingBlockingQuietPageTest;
FRIEND_TEST_ALL_PREFIXES(SafeBrowsingBlockingPageTest,
ProceedThenDontProceed);
FRIEND_TEST_ALL_PREFIXES(SafeBrowsingBlockingPageTest,
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc
index 3c988fb..be37db8 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc
@@ -14,9 +14,12 @@
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
+#include "components/grit/components_resources.h"
#include "components/prefs/pref_service.h"
#include "components/safe_browsing/browser/threat_details.h"
#include "components/safe_browsing/common/safe_browsing_prefs.h"
+#include "components/security_interstitials/core/safe_browsing_quiet_error_ui.h"
+#include "components/strings/grit/components_strings.h"
#include "content/public/browser/interstitial_page.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_process_host.h"
@@ -24,6 +27,10 @@
#include "content/public/test/web_contents_tester.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/base/webui/jstemplate_builder.h"
+#include "ui/base/webui/web_ui_util.h"
using content::InterstitialPage;
using content::NavigationEntry;
@@ -101,6 +108,79 @@
MOCK_CONST_METHOD0(IsOffTheRecord, bool());
};
+class TestSafeBrowsingBlockingPageQuiet : public SafeBrowsingBlockingPage {
+ public:
+ TestSafeBrowsingBlockingPageQuiet(
+ BaseUIManager* manager,
+ WebContents* web_contents,
+ const GURL& main_frame_url,
+ const UnsafeResourceList& unsafe_resources,
+ const BaseSafeBrowsingErrorUI::SBErrorDisplayOptions& display_options)
+ : SafeBrowsingBlockingPage(manager,
+ web_contents,
+ main_frame_url,
+ unsafe_resources,
+ display_options),
+ sb_error_ui_(unsafe_resources[0].url,
+ main_frame_url,
+ GetInterstitialReason(unsafe_resources),
+ display_options,
+ manager->app_locale(),
+ base::Time::NowFromSystemTime(),
+ controller(),
+ false) {
+ // Don't delay details at all for the unittest.
+ SetThreatDetailsProceedDelayForTesting(0);
+ DontCreateViewForTesting();
+ }
+
+ // Manually specify that the WebView extends beyond viewing bounds.
+ void SetGiantWebView() { sb_error_ui_.SetGiantWebViewForTesting(true); }
+
+ base::DictionaryValue GetUIStrings() {
+ base::DictionaryValue load_time_data;
+ sb_error_ui_.PopulateStringsForHtml(&load_time_data);
+ webui::SetLoadTimeDataDefaults(controller()->GetApplicationLocale(),
+ &load_time_data);
+ return load_time_data;
+ }
+
+ security_interstitials::SafeBrowsingQuietErrorUI sb_error_ui_;
+};
+
+// TODO(edwardjung): Refactor into TestSafeBrowsingBlockingPageFactory.
+class TestSafeBrowsingBlockingQuietPageFactory
+ : public SafeBrowsingBlockingPageFactory {
+ public:
+ TestSafeBrowsingBlockingQuietPageFactory() {}
+ ~TestSafeBrowsingBlockingQuietPageFactory() override {}
+
+ SafeBrowsingBlockingPage* CreateSafeBrowsingPage(
+ BaseUIManager* manager,
+ WebContents* web_contents,
+ const GURL& main_frame_url,
+ const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources)
+ override {
+ PrefService* prefs =
+ Profile::FromBrowserContext(web_contents->GetBrowserContext())
+ ->GetPrefs();
+ bool is_extended_reporting_opt_in_allowed =
+ prefs->GetBoolean(prefs::kSafeBrowsingExtendedReportingOptInAllowed);
+ bool is_proceed_anyway_disabled =
+ prefs->GetBoolean(prefs::kSafeBrowsingProceedAnywayDisabled);
+ BaseSafeBrowsingErrorUI::SBErrorDisplayOptions display_options(
+ BaseBlockingPage::IsMainPageLoadBlocked(unsafe_resources),
+ is_extended_reporting_opt_in_allowed,
+ web_contents->GetBrowserContext()->IsOffTheRecord(),
+ IsExtendedReportingEnabled(*prefs), IsScout(*prefs),
+ is_proceed_anyway_disabled,
+ BaseBlockingPage::IsMainPageLoadBlocked(unsafe_resources));
+ return new TestSafeBrowsingBlockingPageQuiet(
+ manager, web_contents, main_frame_url, unsafe_resources,
+ display_options);
+ }
+};
+
} // namespace
class SafeBrowsingBlockingPageTest : public ChromeRenderViewHostTestHarness {
@@ -795,4 +875,162 @@
ui_manager_->GetThreatDetails()->clear();
}
+class SafeBrowsingBlockingQuietPageTest
+ : public ChromeRenderViewHostTestHarness {
+ public:
+ // The decision the user made.
+ enum UserResponse { PENDING, OK, CANCEL };
+
+ SafeBrowsingBlockingQuietPageTest() {
+ // The safe browsing UI manager does not need a service for this test.
+ ui_manager_ = new TestSafeBrowsingUIManager(NULL);
+ }
+
+ void SetUp() override {
+ ChromeRenderViewHostTestHarness::SetUp();
+
+ SafeBrowsingBlockingPage::RegisterFactory(&factory_);
+ SafeBrowsingUIManager::CreateWhitelistForTesting(web_contents());
+
+ safe_browsing::TestSafeBrowsingServiceFactory sb_service_factory;
+ sb_service_factory.SetTestUIManager(ui_manager_.get());
+ auto* safe_browsing_service =
+ sb_service_factory.CreateSafeBrowsingService();
+ // A profile was created already but SafeBrowsingService wasn't around to
+ // get notified of it, so include that notification now.
+ safe_browsing_service->AddPrefService(
+ Profile::FromBrowserContext(web_contents()->GetBrowserContext())
+ ->GetPrefs());
+ TestingBrowserProcess::GetGlobal()->SetSafeBrowsingService(
+ safe_browsing_service);
+ g_browser_process->safe_browsing_service()->Initialize();
+ }
+
+ void TearDown() override {
+ // Release the UI manager before the BrowserThreads are destroyed.
+ ui_manager_ = NULL;
+ TestingBrowserProcess::GetGlobal()->safe_browsing_service()->ShutDown();
+ TestingBrowserProcess::GetGlobal()->SetSafeBrowsingService(nullptr);
+ SafeBrowsingBlockingPage::RegisterFactory(NULL);
+ // Clean up singleton reference (crbug.com/110594).
+ ThreatDetails::RegisterFactory(NULL);
+ ChromeRenderViewHostTestHarness::TearDown();
+ }
+
+ void OnBlockingPageComplete(bool proceed) {
+ if (proceed)
+ user_response_ = OK;
+ else
+ user_response_ = CANCEL;
+ }
+
+ void ShowInterstitial(bool is_subresource,
+ const char* url,
+ SBThreatType type) {
+ security_interstitials::UnsafeResource resource;
+ InitResource(&resource, is_subresource, GURL(url), type);
+ SafeBrowsingBlockingPage::ShowBlockingPage(ui_manager_.get(), resource);
+ }
+
+ // Returns the SafeBrowsingBlockingPage currently showing or NULL if none is
+ // showing.
+ TestSafeBrowsingBlockingPageQuiet* GetSafeBrowsingBlockingPage() {
+ InterstitialPage* interstitial =
+ InterstitialPage::GetInterstitialPage(web_contents());
+ if (!interstitial)
+ return NULL;
+ return static_cast<TestSafeBrowsingBlockingPageQuiet*>(
+ interstitial->GetDelegateForTesting());
+ }
+
+ scoped_refptr<TestSafeBrowsingUIManager> ui_manager_;
+
+ // Owned by TestSafeBrowsingBlockingQuietPage.
+ MockTestingProfile* mock_profile_;
+
+ private:
+ void InitResource(security_interstitials::UnsafeResource* resource,
+ bool is_subresource,
+ const GURL& url,
+ SBThreatType type) {
+ resource->callback =
+ base::Bind(&SafeBrowsingBlockingQuietPageTest::OnBlockingPageComplete,
+ base::Unretained(this));
+ resource->callback_thread = content::BrowserThread::GetTaskRunnerForThread(
+ content::BrowserThread::IO);
+ resource->url = url;
+ resource->is_subresource = is_subresource;
+ resource->threat_type = type;
+ resource->web_contents_getter =
+ security_interstitials::UnsafeResource::GetWebContentsGetter(
+ web_contents()->GetRenderProcessHost()->GetID(),
+ web_contents()->GetMainFrame()->GetRoutingID());
+ resource->threat_source = safe_browsing::ThreatSource::LOCAL_PVER3;
+ }
+
+ UserResponse user_response_;
+ TestSafeBrowsingBlockingQuietPageFactory factory_;
+};
+
+// Tests showing a quiet blocking page for a malware page.
+TEST_F(SafeBrowsingBlockingQuietPageTest, MalwarePage) {
+ // Start a load.
+ controller().LoadURL(GURL(kBadURL), content::Referrer(),
+ ui::PAGE_TRANSITION_TYPED, std::string());
+
+ // Simulate the load causing a safe browsing interstitial to be shown.
+ ShowInterstitial(false, kBadURL, SB_THREAT_TYPE_URL_MALWARE);
+ TestSafeBrowsingBlockingPageQuiet* sb_interstitial =
+ GetSafeBrowsingBlockingPage();
+ ASSERT_TRUE(sb_interstitial);
+
+ base::DictionaryValue load_time_data = sb_interstitial->GetUIStrings();
+ base::string16 str;
+ load_time_data.GetString("heading", &str);
+ EXPECT_EQ(str, l10n_util::GetStringUTF16(IDS_MALWARE_WEBVIEW_HEADING));
+ bool is_giant;
+ load_time_data.GetBoolean("is_giant", &is_giant);
+ EXPECT_FALSE(is_giant);
+}
+
+// Tests showing a quiet blocking page for a phishing page.
+TEST_F(SafeBrowsingBlockingQuietPageTest, PhishingPage) {
+ // Start a load.
+ controller().LoadURL(GURL(kBadURL), content::Referrer(),
+ ui::PAGE_TRANSITION_TYPED, std::string());
+
+ // Simulate the load causing a safe browsing interstitial to be shown.
+ ShowInterstitial(false, kBadURL, SB_THREAT_TYPE_URL_PHISHING);
+ TestSafeBrowsingBlockingPageQuiet* sb_interstitial =
+ GetSafeBrowsingBlockingPage();
+ ASSERT_TRUE(sb_interstitial);
+
+ base::DictionaryValue load_time_data = sb_interstitial->GetUIStrings();
+ base::string16 str;
+ load_time_data.GetString("heading", &str);
+ EXPECT_EQ(str, l10n_util::GetStringUTF16(IDS_PHISHING_WEBVIEW_HEADING));
+ bool is_giant;
+ load_time_data.GetBoolean("is_giant", &is_giant);
+ EXPECT_FALSE(is_giant);
+}
+
+// Tests showing a quiet blocking page in a giant webview.
+TEST_F(SafeBrowsingBlockingQuietPageTest, GiantWebView) {
+ // Start a load.
+ controller().LoadURL(GURL(kBadURL), content::Referrer(),
+ ui::PAGE_TRANSITION_TYPED, std::string());
+
+ // Simulate the load causing a safe browsing interstitial to be shown.
+ ShowInterstitial(false, kBadURL, SB_THREAT_TYPE_URL_MALWARE);
+ TestSafeBrowsingBlockingPageQuiet* sb_interstitial =
+ GetSafeBrowsingBlockingPage();
+ EXPECT_TRUE(sb_interstitial);
+
+ sb_interstitial->SetGiantWebView();
+ base::DictionaryValue load_time_data = sb_interstitial->GetUIStrings();
+ bool is_giant;
+ load_time_data.GetBoolean("is_giant", &is_giant);
+ EXPECT_TRUE(is_giant);
+}
+
} // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.h b/chrome/browser/safe_browsing/safe_browsing_service.h
index c98e36b..262facf 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service.h
+++ b/chrome/browser/safe_browsing/safe_browsing_service.h
@@ -234,6 +234,7 @@
content::BrowserThread::UI>;
friend class base::DeleteHelper<SafeBrowsingService>;
friend class SafeBrowsingBlockingPageTest;
+ friend class SafeBrowsingBlockingQuietPageTest;
friend class SafeBrowsingServerTest;
friend class SafeBrowsingServiceTest;
friend class SafeBrowsingURLRequestContextGetter;
diff --git a/components/OWNERS b/components/OWNERS
index 00b920b..08e4a212 100644
--- a/components/OWNERS
+++ b/components/OWNERS
@@ -21,6 +21,7 @@
per-file [email protected]
per-file physical_web_ui_strings.grdp=file://components/physical_web/OWNERS
per-file policy_strings.grdp=file://components/policy/OWNERS
+per-file security_interstitials_resources.grdp=file://components/security_interstitials/OWNERS
per-file security_interstitials_strings.grdp=file://components/security_interstitials/OWNERS
per-file security_state_strings.grdp=file://components/security_state/OWNERS
per-file ssl_errors_strings.grdp=file://components/ssl_errors/OWNERS
diff --git a/components/neterror/resources/neterror.html b/components/neterror/resources/neterror.html
index e3c3032..3851e4fe 100644
--- a/components/neterror/resources/neterror.html
+++ b/components/neterror/resources/neterror.html
@@ -5,6 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0,
maximum-scale=1.0, user-scalable=no">
<title i18n-content="title"></title>
+ <link rel="stylesheet" href="../../../components/security_interstitials/core/browser/resources/interstitial_common.css">
<link rel="stylesheet" href="../../../components/security_interstitials/core/browser/resources/interstitial_v2.css">
<link rel="stylesheet" href="neterror.css">
<script src="../../../components/security_interstitials/core/browser/resources/interstitial_v2_mobile.js"></script>
diff --git a/components/resources/security_interstitials_resources.grdp b/components/resources/security_interstitials_resources.grdp
index 907ef5fe..2fb0f05c 100644
--- a/components/resources/security_interstitials_resources.grdp
+++ b/components/resources/security_interstitials_resources.grdp
@@ -2,4 +2,5 @@
<grit-part>
<include name="IDR_SECURITY_INTERSTITIAL_UI_HTML" file="../security_interstitials/core/browser/resources/interstitial_ui.html" flattenhtml="true" type="BINDATA" />
<include name="IDR_SECURITY_INTERSTITIAL_HTML" file="../security_interstitials/core/browser/resources/interstitial_v2.html" flattenhtml="true" type="BINDATA" />
+ <include name="IDR_SECURITY_INTERSTITIAL_QUIET_HTML" file="../security_interstitials/core/browser/resources/interstitial_webview_quiet.html" flattenhtml="true" type="BINDATA" />
</grit-part>
\ No newline at end of file
diff --git a/components/safe_browsing/base_blocking_page.cc b/components/safe_browsing/base_blocking_page.cc
index b1b57c6b..6c1272f 100644
--- a/components/safe_browsing/base_blocking_page.cc
+++ b/components/safe_browsing/base_blocking_page.cc
@@ -208,7 +208,7 @@
void BaseBlockingPage::PopulateInterstitialStrings(
base::DictionaryValue* load_time_data) {
- sb_error_ui_->PopulateStringsForHTML(load_time_data);
+ sb_error_ui_->PopulateStringsForHtml(load_time_data);
}
void BaseBlockingPage::FinishThreatDetails(const base::TimeDelta& delay,
diff --git a/components/security_interstitials/core/BUILD.gn b/components/security_interstitials/core/BUILD.gn
index f29f158c..b63c920 100644
--- a/components/security_interstitials/core/BUILD.gn
+++ b/components/security_interstitials/core/BUILD.gn
@@ -16,6 +16,8 @@
"metrics_helper.h",
"safe_browsing_loud_error_ui.cc",
"safe_browsing_loud_error_ui.h",
+ "safe_browsing_quiet_error_ui.cc",
+ "safe_browsing_quiet_error_ui.h",
"ssl_error_ui.cc",
"ssl_error_ui.h",
]
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 02d2517..bd7cf52a 100644
--- a/components/security_interstitials/core/base_safe_browsing_error_ui.h
+++ b/components/security_interstitials/core/base_safe_browsing_error_ui.h
@@ -123,7 +123,7 @@
GURL request_url() const { return request_url_; }
GURL main_frame_url() const { return main_frame_url_; }
- virtual void PopulateStringsForHTML(
+ virtual void PopulateStringsForHtml(
base::DictionaryValue* load_time_data) = 0;
virtual void HandleCommand(SecurityInterstitialCommands command) = 0;
diff --git a/components/security_interstitials/core/browser/resources/extended_reporting.js b/components/security_interstitials/core/browser/resources/extended_reporting.js
index 5a72ad1..6ebec2c 100644
--- a/components/security_interstitials/core/browser/resources/extended_reporting.js
+++ b/components/security_interstitials/core/browser/resources/extended_reporting.js
@@ -41,7 +41,7 @@
$('opt-in-checkbox').addEventListener('click', function() {
sendCommand($('opt-in-checkbox').checked ?
- CMD_DO_REPORT :
- CMD_DONT_REPORT);
+ SecurityInterstitialCommandId.CMD_DO_REPORT :
+ SecurityInterstitialCommandId.CMD_DONT_REPORT);
});
}
diff --git a/components/security_interstitials/core/browser/resources/images/blocked.svg b/components/security_interstitials/core/browser/resources/images/blocked.svg
new file mode 100644
index 0000000..102d2b0
--- /dev/null
+++ b/components/security_interstitials/core/browser/resources/images/blocked.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="20px" height="16px" viewBox="0 0 20 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g transform="translate(-2.000000, -4.000000)">
+ <g>
+ <polygon points="0 0 24 0 24 24 0 24"></polygon>
+ <path d="M20,4 C21,4 22,5 22,6 L22,18 C22,19 21,20 20,20 L4,20 C2.9,20 2,19.1 2,18 L2,6 C2,5 3,4 4,4 L20,4 Z M14.3923033,15.4598278 L15.4949742,14.3581062 L13.1207639,11.9859397 L15.5,9.60774749 L14.3973291,8.50602582 L12.0170879,10.8842181 L9.63182079,8.5 L8.52914991,9.60172166 L10.9154222,11.9859397 L8.5,14.3982783 L9.60267088,15.5 L12.0170879,13.0866571 L14.3923033,15.4598278 Z" fill-opacity="0.2" fill="#000000"></path>
+ </g>
+ </g>
+ </g>
+</svg>
\ No newline at end of file
diff --git a/components/security_interstitials/core/browser/resources/interstitial_common.css b/components/security_interstitials/core/browser/resources/interstitial_common.css
new file mode 100644
index 0000000..32a27b9
--- /dev/null
+++ b/components/security_interstitials/core/browser/resources/interstitial_common.css
@@ -0,0 +1,35 @@
+/* Copyright 2017 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file. */
+
+a {
+ color: rgb(88, 88, 88);
+}
+
+body {
+ background-color: rgb(247, 247, 247);
+ color: rgb(100, 100, 100);
+}
+
+#details-button {
+ background: inherit;
+ border: 0;
+ float: none;
+ margin: 0;
+ padding: 10px 0;
+ text-transform: uppercase;
+}
+
+.hidden {
+ display: none;
+}
+
+html {
+ -webkit-text-size-adjust: 100%;
+ font-size: 125%;
+}
+
+.icon {
+ background-repeat: no-repeat;
+ background-size: 100%;
+}
\ No newline at end of file
diff --git a/components/security_interstitials/core/browser/resources/interstitial_common.js b/components/security_interstitials/core/browser/resources/interstitial_common.js
new file mode 100644
index 0000000..e826a149
--- /dev/null
+++ b/components/security_interstitials/core/browser/resources/interstitial_common.js
@@ -0,0 +1,46 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This is the shared code for security interstitials. It is used for both SSL
+// interstitials and Safe Browsing interstitials.
+
+// Should match security_interstitials::SecurityInterstitialCommands
+/** @enum| {string} */
+var SecurityInterstitialCommandId = {
+ CMD_DONT_PROCEED: 0,
+ CMD_PROCEED: 1,
+ // Ways for user to get more information
+ CMD_SHOW_MORE_SECTION: 2,
+ CMD_OPEN_HELP_CENTER: 3,
+ CMD_OPEN_DIAGNOSTIC: 4,
+ // Primary button actions
+ CMD_RELOAD: 5,
+ CMD_OPEN_DATE_SETTINGS: 6,
+ CMD_OPEN_LOGIN: 7,
+ // Safe Browsing Extended Reporting
+ CMD_DO_REPORT: 8,
+ CMD_DONT_REPORT: 9,
+ CMD_OPEN_REPORTING_PRIVACY: 10,
+ CMD_OPEN_WHITEPAPER: 11,
+ // Report a phishing error.
+ CMD_REPORT_PHISHING_ERROR: 12
+};
+
+/**
+ * A convenience method for sending commands to the parent page.
+ * @param {string} cmd The command to send.
+ */
+function sendCommand(cmd) {
+// <if expr="not is_ios">
+ window.domAutomationController.setAutomationId(1);
+ window.domAutomationController.send(cmd);
+// </if>
+// <if expr="is_ios">
+ // TODO(crbug.com/565877): Revisit message passing for WKWebView.
+ var iframe = document.createElement('IFRAME');
+ iframe.setAttribute('src', 'js-command:' + cmd);
+ document.documentElement.appendChild(iframe);
+ iframe.parentNode.removeChild(iframe);
+// </if>
+}
\ No newline at end of file
diff --git a/components/security_interstitials/core/browser/resources/interstitial_v2.css b/components/security_interstitials/core/browser/resources/interstitial_v2.css
index d82e6bd..5af309a 100644
--- a/components/security_interstitials/core/browser/resources/interstitial_v2.css
+++ b/components/security_interstitials/core/browser/resources/interstitial_v2.css
@@ -2,21 +2,12 @@
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. */
-a {
- color: #585858;
-}
-
.bad-clock .icon {
background-image: -webkit-image-set(
url(images/1x/clock.png) 1x,
url(images/2x/clock.png) 2x);
}
-body {
- background-color: #f7f7f7;
- color: #646464;
-}
-
body.safe-browsing {
background-color: rgb(206, 52, 38);
color: white;
@@ -81,15 +72,6 @@
margin-top: 20px;
}
-#details-button {
- background: inherit;
- border: 0;
- float: none;
- margin: 0;
- padding: 10px 0;
- text-transform: uppercase;
-}
-
#details-button:hover {
box-shadow: inherit;
text-decoration: underline;
@@ -118,18 +100,7 @@
font-weight: normal;
}
-.hidden {
- display: none;
-}
-
-html {
- -webkit-text-size-adjust: 100%;
- font-size: 125%;
-}
-
.icon {
- background-repeat: no-repeat;
- background-size: 100%;
height: 72px;
margin: 0 0 40px;
width: 72px;
diff --git a/components/security_interstitials/core/browser/resources/interstitial_v2.html b/components/security_interstitials/core/browser/resources/interstitial_v2.html
index 9a3ad69..f382689f 100644
--- a/components/security_interstitials/core/browser/resources/interstitial_v2.html
+++ b/components/security_interstitials/core/browser/resources/interstitial_v2.html
@@ -1,16 +1,18 @@
<!doctype html>
-<html i18n-values="dir:textdirection;lang:language">
+<html dir="$i18n{textdirection}" lang="$i18n{language}">
<head>
<meta charset="utf-8">
<meta name="viewport"
content="initial-scale=1, minimum-scale=1, width=device-width">
<title i18n-content="tabTitle"></title>
+ <link rel="stylesheet" href="interstitial_common.css">
<link rel="stylesheet" href="interstitial_v2.css">
<script src="../../../../../ui/webui/resources/js/util.js"></script>
<script src="captive_portal.js"></script>
<script src="ssl.js"></script>
<script src="extended_reporting.js"></script>
<script src="interstitial_v2_mobile.js"></script>
+ <script src="interstitial_common.js"></script>
<script src="interstitial_v2.js"></script>
</head>
<body id="body">
@@ -18,7 +20,7 @@
<div id="main-content">
<div class="icon" id="icon"></div>
<div id="main-message">
- <h1 i18n-content="heading"></h1>
+ <h1>$i18n{heading}</h1>
<p i18n-values=".innerHTML:primaryParagraph"></p>
<div id="debugging">
<div id="error-code" class="error-code"></div>
@@ -36,9 +38,8 @@
</div>
</div>
<div class="nav-wrapper">
- <button i18n-content="primaryButtonText" id="primary-button"></button>
- <button id="details-button" class="small-link"
- i18n-content="openDetails"></button>
+ <button id="primary-button">$i18n{primaryButtonText}</button>
+ <button id="details-button" class="small-link">$i18n{openDetails}</button>
</div>
<div id="details" class="hidden">
<p i18n-values=".innerHTML:explanationParagraph"></p>
diff --git a/components/security_interstitials/core/browser/resources/interstitial_v2.js b/components/security_interstitials/core/browser/resources/interstitial_v2.js
index 88ad830e..c570798 100644
--- a/components/security_interstitials/core/browser/resources/interstitial_v2.js
+++ b/components/security_interstitials/core/browser/resources/interstitial_v2.js
@@ -8,43 +8,6 @@
var expandedDetails = false;
var keyPressState = 0;
-// Should match security_interstitials::SecurityInterstitialCommands
-var CMD_DONT_PROCEED = 0;
-var CMD_PROCEED = 1;
-// Ways for user to get more information
-var CMD_SHOW_MORE_SECTION = 2;
-var CMD_OPEN_HELP_CENTER = 3;
-var CMD_OPEN_DIAGNOSTIC = 4;
-// Primary button actions
-var CMD_RELOAD = 5;
-var CMD_OPEN_DATE_SETTINGS = 6;
-var CMD_OPEN_LOGIN = 7;
-// Safe Browsing Extended Reporting
-var CMD_DO_REPORT = 8;
-var CMD_DONT_REPORT = 9;
-var CMD_OPEN_REPORTING_PRIVACY = 10;
-var CMD_OPEN_WHITEPAPER = 11;
-// Report a phishing error.
-var CMD_REPORT_PHISHING_ERROR = 12;
-
-/**
- * A convenience method for sending commands to the parent page.
- * @param {string} cmd The command to send.
- */
-function sendCommand(cmd) {
-// <if expr="not is_ios">
- window.domAutomationController.setAutomationId(1);
- window.domAutomationController.send(cmd);
-// </if>
-// <if expr="is_ios">
- // TODO(crbug.com/565877): Revisit message passing for WKWebView.
- var iframe = document.createElement('IFRAME');
- iframe.setAttribute('src', 'js-command:' + cmd);
- document.documentElement.appendChild(iframe);
- iframe.parentNode.removeChild(iframe);
-// </if>
-}
-
/**
* This allows errors to be skippped by typing a secret phrase into the page.
* @param {string} e The key that was just pressed.
@@ -54,7 +17,7 @@
if (BYPASS_SEQUENCE.charCodeAt(keyPressState) == e.keyCode) {
keyPressState++;
if (keyPressState == BYPASS_SEQUENCE.length) {
- sendCommand(CMD_PROCEED);
+ sendCommand(SecurityInterstitialCommandId.CMD_PROCEED);
keyPressState = 0;
}
} else {
@@ -122,20 +85,20 @@
$('primary-button').addEventListener('click', function() {
switch (interstitialType) {
case 'CAPTIVE_PORTAL':
- sendCommand(CMD_OPEN_LOGIN);
+ sendCommand(SecurityInterstitialCommandId.CMD_OPEN_LOGIN);
break;
case 'SSL':
if (badClock)
- sendCommand(CMD_OPEN_DATE_SETTINGS);
+ sendCommand(SecurityInterstitialCommandId.CMD_OPEN_DATE_SETTINGS);
else if (overridable)
- sendCommand(CMD_DONT_PROCEED);
+ sendCommand(SecurityInterstitialCommandId.CMD_DONT_PROCEED);
else
- sendCommand(CMD_RELOAD);
+ sendCommand(SecurityInterstitialCommandId.CMD_RELOAD);
break;
case 'SAFEBROWSING':
- sendCommand(CMD_DONT_PROCEED);
+ sendCommand(SecurityInterstitialCommandId.CMD_DONT_PROCEED);
break;
default:
@@ -147,7 +110,7 @@
if (overridable) {
// Captive portal page isn't overridable.
$('proceed-link').addEventListener('click', function(event) {
- sendCommand(CMD_PROCEED);
+ sendCommand(SecurityInterstitialCommandId.CMD_PROCEED);
});
} else if (!ssl) {
$('final-paragraph').classList.add('hidden');
@@ -159,13 +122,13 @@
if ($('diagnostic-link')) {
$('diagnostic-link').addEventListener('click', function(event) {
- sendCommand(CMD_OPEN_DIAGNOSTIC);
+ sendCommand(SecurityInterstitialCommandId.CMD_OPEN_DIAGNOSTIC);
});
}
if ($('learn-more-link')) {
$('learn-more-link').addEventListener('click', function(event) {
- sendCommand(CMD_OPEN_HELP_CENTER);
+ sendCommand(SecurityInterstitialCommandId.CMD_OPEN_HELP_CENTER);
});
}
@@ -188,7 +151,7 @@
loadTimeData.getString('closeDetails');
if (!expandedDetails) {
// Record a histogram entry only the first time that details is opened.
- sendCommand(CMD_SHOW_MORE_SECTION);
+ sendCommand(SecurityInterstitialCommandId.CMD_SHOW_MORE_SECTION);
expandedDetails = true;
}
});
@@ -199,7 +162,7 @@
if (interstitialType == 'SAFEBROWSING' &&
loadTimeData.getBoolean('phishing') && $('report-error-link')) {
$('report-error-link').addEventListener('click', function(event) {
- sendCommand(CMD_REPORT_PHISHING_ERROR);
+ sendCommand(SecurityInterstitialCommandId.CMD_REPORT_PHISHING_ERROR);
});
}
diff --git a/components/security_interstitials/core/browser/resources/interstitial_webview_quiet.css b/components/security_interstitials/core/browser/resources/interstitial_webview_quiet.css
new file mode 100644
index 0000000..80a87648c
--- /dev/null
+++ b/components/security_interstitials/core/browser/resources/interstitial_webview_quiet.css
@@ -0,0 +1,112 @@
+/* Copyright 2017 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file. */
+
+body {
+ margin: 0;
+}
+
+#details {
+ box-sizing: border-box;
+ height: auto;
+ line-height: 1.48em;
+ margin: 0;
+ opacity: 1;
+ transition: opacity 250ms cubic-bezier(0.4, 0, 0.2, 1);
+}
+
+#details.hidden {
+ display: block;
+ height: 0;
+ opacity: 0;
+ overflow: hidden;
+ padding-bottom: 0;
+ transition: none;
+}
+
+#details-link {
+ color: rgba(0,0,0,.38);
+ /* For V1, the details link is hidden. */
+ display: none;
+ text-decoration: underline;
+ text-transform: none;
+}
+
+h1 {
+ color: rgba(0,0,0,.38);
+ font-size: 1.037037em;
+ line-height: 1.4em;
+ margin: 8px 0 8px;
+}
+
+.giant .icon {
+ bottom: 0;
+ left: 0;
+ margin: auto;
+ position: fixed;
+ right: 0;
+ top: 0;
+}
+
+.giant #details,
+.giant #main-message {
+ display: none;
+}
+
+.icon {
+ background-image: url(images/blocked.svg);
+ height: 20vh;
+ margin: 0 auto;
+ max-height: 36px;
+ max-width: 36px;
+ min-height: 18px;
+ min-width: 18px;
+ opacity: .54;
+ width: 20vh;
+}
+
+.interstitial-wrapper {
+ align-items: center;
+ box-sizing: border-box;
+ display: flex;
+ flex-direction: column;
+ font-size: 0.9em;
+ height: 100vh;
+ justify-content: center;
+ line-height: 1.6em;
+ margin: 0 auto;
+ max-width: 640px;
+ padding: 16px;
+ width: 100%;
+}
+
+#main-content {
+ align-self: auto;
+ color: rgba(0, 0, 0, .54);
+ flex: 0 1 auto;
+ text-align: center;
+}
+
+@media (max-height:2em), (max-width:2em) {
+ .icon {
+ display: none;
+ }
+}
+
+@media (min-height:25em) and (min-width:37.5em),
+ (min-height:37.5em) and (min-width:25em) {
+ .icon {
+ height: 36px;
+ width: 36px;
+ }
+}
+
+/* Views that don't fit the details text. */
+@media (max-height:11.25em) and (max-width:18.75em),
+ (max-height:18.75em) and (max-width:11.25em),
+ (max-height:5em), (max-width:5em) {
+ #details,
+ #main-message {
+ display: none;
+ }
+}
diff --git a/components/security_interstitials/core/browser/resources/interstitial_webview_quiet.html b/components/security_interstitials/core/browser/resources/interstitial_webview_quiet.html
new file mode 100644
index 0000000..63de889
--- /dev/null
+++ b/components/security_interstitials/core/browser/resources/interstitial_webview_quiet.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<html dir="$i18n{textdirection}" lang="$i18n{language}">
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport"
+ content="initial-scale=1, minimum-scale=1, width=device-width">
+ <title>$i18n{tabTitle}</title>
+ <link rel="stylesheet" href="interstitial_common.css">
+ <link rel="stylesheet" href="interstitial_webview_quiet.css">
+ <script src="../../../../../ui/webui/resources/js/util.js"></script>
+ <script src="interstitial_webview_quiet.js"></script>
+</head>
+<body id="body">
+ <div class="interstitial-wrapper">
+ <div id="main-content">
+ <div class="icon"></div>
+ <div id="main-message">
+ <h1>
+ <span>$i18n{heading}</span>
+ <a id="details-link">$i18n{openDetails}</a>
+ </h1>
+ </div>
+ </div>
+ <div id="details" class="hidden">
+ <p>
+ $i18Raw{explanationParagraph}
+ </p>
+ </div>
+ </div>
+</body>
+</html>
diff --git a/components/security_interstitials/core/browser/resources/interstitial_webview_quiet.js b/components/security_interstitials/core/browser/resources/interstitial_webview_quiet.js
new file mode 100644
index 0000000..cb189d7
--- /dev/null
+++ b/components/security_interstitials/core/browser/resources/interstitial_webview_quiet.js
@@ -0,0 +1,10 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function initPage() {
+ var isGiantWebView = loadTimeData.getBoolean('is_giant');
+ document.body.className = isGiantWebView ? 'giant' : '';
+}
+
+document.addEventListener('DOMContentLoaded', initPage);
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 8c0df9a..96207898 100644
--- a/components/security_interstitials/core/safe_browsing_loud_error_ui.cc
+++ b/components/security_interstitials/core/safe_browsing_loud_error_ui.cc
@@ -78,7 +78,7 @@
controller()->metrics_helper()->RecordShutdownMetrics();
}
-void SafeBrowsingLoudErrorUI::PopulateStringsForHTML(
+void SafeBrowsingLoudErrorUI::PopulateStringsForHtml(
base::DictionaryValue* load_time_data) {
DCHECK(load_time_data);
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 c90391a..76efa5a63 100644
--- a/components/security_interstitials/core/safe_browsing_loud_error_ui.h
+++ b/components/security_interstitials/core/safe_browsing_loud_error_ui.h
@@ -35,7 +35,7 @@
~SafeBrowsingLoudErrorUI() override;
// Implement BaseSafeBrowsingErrorUI.
- void PopulateStringsForHTML(base::DictionaryValue* load_time_data) override;
+ void PopulateStringsForHtml(base::DictionaryValue* load_time_data) override;
void HandleCommand(SecurityInterstitialCommands command) override;
private:
diff --git a/components/security_interstitials/core/safe_browsing_quiet_error_ui.cc b/components/security_interstitials/core/safe_browsing_quiet_error_ui.cc
new file mode 100644
index 0000000..0167025
--- /dev/null
+++ b/components/security_interstitials/core/safe_browsing_quiet_error_ui.cc
@@ -0,0 +1,95 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/security_interstitials/core/safe_browsing_quiet_error_ui.h"
+
+#include "base/i18n/time_formatting.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/strings/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/google/core/browser/google_util.h"
+#include "components/security_interstitials/core/common_string_util.h"
+#include "components/security_interstitials/core/metrics_helper.h"
+#include "components/strings/grit/components_strings.h"
+#include "net/base/escape.h"
+#include "ui/base/l10n/l10n_util.h"
+
+namespace security_interstitials {
+
+SafeBrowsingQuietErrorUI::SafeBrowsingQuietErrorUI(
+ const GURL& request_url,
+ const GURL& main_frame_url,
+ BaseSafeBrowsingErrorUI::SBInterstitialReason reason,
+ const BaseSafeBrowsingErrorUI::SBErrorDisplayOptions& display_options,
+ const std::string& app_locale,
+ const base::Time& time_triggered,
+ ControllerClient* controller,
+ const bool is_giant_webview)
+ : BaseSafeBrowsingErrorUI(request_url,
+ main_frame_url,
+ reason,
+ display_options,
+ app_locale,
+ time_triggered,
+ controller),
+ is_giant_webview_(is_giant_webview) {
+ controller->metrics_helper()->RecordUserDecision(MetricsHelper::SHOW);
+ controller->metrics_helper()->RecordUserInteraction(
+ MetricsHelper::TOTAL_VISITS);
+ if (is_proceed_anyway_disabled()) {
+ controller->metrics_helper()->RecordUserDecision(
+ security_interstitials::MetricsHelper::PROCEEDING_DISABLED);
+ }
+}
+
+SafeBrowsingQuietErrorUI::~SafeBrowsingQuietErrorUI() {
+ controller()->metrics_helper()->RecordShutdownMetrics();
+}
+
+void SafeBrowsingQuietErrorUI::PopulateStringsForHtml(
+ base::DictionaryValue* load_time_data) {
+ DCHECK(load_time_data);
+
+ load_time_data->SetString("type", "SAFEBROWSING");
+ load_time_data->SetString(
+ "tabTitle", l10n_util::GetStringUTF16(IDS_SAFEBROWSING_V3_TITLE));
+ load_time_data->SetBoolean("overridable", !is_proceed_anyway_disabled());
+ load_time_data->SetString(
+ "openDetails",
+ l10n_util::GetStringUTF16(IDS_SAFEBROWSING_V3_OPEN_DETAILS_BUTTON));
+ load_time_data->SetBoolean("is_giant", is_giant_webview_);
+
+ bool phishing =
+ interstitial_reason() == BaseSafeBrowsingErrorUI::SB_REASON_PHISHING;
+ load_time_data->SetBoolean("phishing", phishing);
+ load_time_data->SetString(
+ "heading", phishing
+ ? l10n_util::GetStringUTF16(IDS_PHISHING_WEBVIEW_HEADING)
+ : l10n_util::GetStringUTF16(IDS_MALWARE_WEBVIEW_HEADING));
+
+ int explanation_ids = -1;
+ if (phishing)
+ explanation_ids = IDS_PHISHING_WEBVIEW_EXPLANATION_PARAGRAPH;
+ else if (interstitial_reason() == BaseSafeBrowsingErrorUI::SB_REASON_MALWARE)
+ explanation_ids = IDS_MALWARE_WEBVIEW_EXPLANATION_PARAGRAPH;
+
+ if (explanation_ids > -1) {
+ load_time_data->SetString("explanationParagraph",
+ l10n_util::GetStringUTF16(explanation_ids));
+ } else {
+ NOTREACHED();
+ }
+}
+
+void SafeBrowsingQuietErrorUI::SetGiantWebViewForTesting(
+ bool is_giant_webview) {
+ is_giant_webview_ = is_giant_webview;
+}
+
+void SafeBrowsingQuietErrorUI::HandleCommand(
+ SecurityInterstitialCommands command) {
+ NOTREACHED();
+}
+
+} // security_interstitials
diff --git a/components/security_interstitials/core/safe_browsing_quiet_error_ui.h b/components/security_interstitials/core/safe_browsing_quiet_error_ui.h
new file mode 100644
index 0000000..948a8d66
--- /dev/null
+++ b/components/security_interstitials/core/safe_browsing_quiet_error_ui.h
@@ -0,0 +1,55 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SECURITY_INTERSTITIALS_CORE_SAFE_BROWSING_QUIET_ERROR_UI_H_
+#define COMPONENTS_SECURITY_INTERSTITIALS_CORE_SAFE_BROWSING_QUIET_ERROR_UI_H_
+
+#include "base/macros.h"
+#include "base/time/time.h"
+#include "base/values.h"
+#include "components/security_interstitials/core/base_safe_browsing_error_ui.h"
+#include "components/security_interstitials/core/controller_client.h"
+#include "url/gurl.h"
+
+namespace security_interstitials {
+
+// Quiet version of the safe browsing interstitial. This is the small screen
+// version of the interstitial selectively used in parts of WebView.
+// This class displays a quiet UI for Safe Browsing errors that block page loads
+// specifically for WebView. This class is purely about visual display; it does
+// not do any error-handling logic to determine what type of error should be
+// displayed when.
+class SafeBrowsingQuietErrorUI
+ : public security_interstitials::BaseSafeBrowsingErrorUI {
+ public:
+ SafeBrowsingQuietErrorUI(
+ const GURL& request_url,
+ const GURL& main_frame_url,
+ BaseSafeBrowsingErrorUI::SBInterstitialReason reason,
+ const BaseSafeBrowsingErrorUI::SBErrorDisplayOptions& display_options,
+ const std::string& app_locale,
+ const base::Time& time_triggered,
+ ControllerClient* controller,
+ const bool is_giant_webview);
+ ~SafeBrowsingQuietErrorUI() override;
+
+ // Fills the passed dictionary with the values to be passed to the template
+ // when creating the HTML.
+ void PopulateStringsForHtml(base::DictionaryValue* load_time_data) override;
+
+ void HandleCommand(SecurityInterstitialCommands command) override;
+
+ // Manually set whether displaying in a giant WebView. Specifially used in
+ // tests.
+ void SetGiantWebViewForTesting(bool is_giant_webview);
+
+ private:
+ bool is_giant_webview_;
+
+ DISALLOW_COPY_AND_ASSIGN(SafeBrowsingQuietErrorUI);
+};
+
+} // security_interstitials
+
+#endif // COMPONENTS_SECURITY_INTERSTITIALS_CORE_SAFE_BROWSING_QUIET_ERROR_UI_H_
diff --git a/components/security_interstitials_strings.grdp b/components/security_interstitials_strings.grdp
index 51b64d82..6693485eb 100644
--- a/components/security_interstitials_strings.grdp
+++ b/components/security_interstitials_strings.grdp
@@ -186,4 +186,18 @@
You can <ph name="BEGIN_ERROR_LINK"><a href="#" id="report-error-link"></ph>report a detection problem<ph name="END_ERROR_LINK"></a></ph> or, if you understand the risks to your security, <ph name="BEGIN_LINK"><a href="#" id="proceed-link"></ph>visit this unsafe site<ph name="END_LINK"></a></ph>.
</message>
+ <!-- WebView Safe Browsing quiet interstitals medium sized -->
+ <message name="IDS_MALWARE_WEBVIEW_HEADING" desc="The heading of the malware interstitial on medium sized Webview.">
+ Dangerous content blocked
+ </message>
+ <message name="IDS_MALWARE_WEBVIEW_EXPLANATION_PARAGRAPH" desc="The explanation of why Safe Browsing has blocked the page. Allows the user to proceed using a link.">
+ This content might try to install dangerous software on your device that steals or deletes your information. <ph name="BEGIN_LINK"><a href="#" id="proceed-link"></ph>Show anyway<ph name="END_LINK"></a></ph>.
+ </message>
+ <message name="IDS_PHISHING_WEBVIEW_HEADING" desc="The heading of the phishing interstitial on medium sized Webview.">
+ Deceptive content blocked
+ </message>
+ <message name="IDS_PHISHING_WEBVIEW_EXPLANATION_PARAGRAPH" desc="The explanation of why Safe Browsing has blocked the page. Allows the user to proceed using a link.">
+ This content might try to trick you into installing software or revealing personal information. <ph name="BEGIN_LINK"><a href="#" id="proceed-link"></ph>Show anyway<ph name="END_LINK"></a></ph>.
+ </message>
+
</grit-part>