diff --git a/app/src/main/java/org/mozilla/fenix/AppRequestInterceptor.kt b/app/src/main/java/org/mozilla/fenix/AppRequestInterceptor.kt
index fc5b87e665..dca2e40bd7 100644
--- a/app/src/main/java/org/mozilla/fenix/AppRequestInterceptor.kt
+++ b/app/src/main/java/org/mozilla/fenix/AppRequestInterceptor.kt
@@ -22,6 +22,71 @@ class AppRequestInterceptor(private val context: Context) : RequestInterceptor {
errorType: ErrorType,
uri: String?
): RequestInterceptor.ErrorResponse? {
- return RequestInterceptor.ErrorResponse(ErrorPages.createErrorPage(context, errorType))
+
+ val riskLevel = getRiskLevel(errorType)
+ val htmlResource = getPageForRiskLevel(riskLevel)
+ val cssResource = getStyleForRiskLevel(riskLevel)
+
+ return RequestInterceptor.ErrorResponse(ErrorPages
+ .createErrorPage(context, errorType, uri = uri, htmlResource = htmlResource, cssResource = cssResource))
+ }
+
+ private fun getPageForRiskLevel(riskLevel: RiskLevel): Int {
+ return when (riskLevel) {
+ RiskLevel.Low -> R.raw.low_risk_error_pages
+ RiskLevel.Medium -> R.raw.medium_and_high_risk_error_pages
+ RiskLevel.High -> R.raw.medium_and_high_risk_error_pages
+ }
+ }
+
+ private fun getStyleForRiskLevel(riskLevel: RiskLevel): Int {
+ return when (riskLevel) {
+ RiskLevel.Low -> R.raw.low_and_medium_risk_error_style
+ RiskLevel.Medium -> R.raw.low_and_medium_risk_error_style
+ RiskLevel.High -> R.raw.high_risk_error_style
+ }
+ }
+
+ @Suppress("ComplexMethod")
+ private fun getRiskLevel(errorType: ErrorType): RiskLevel {
+ return when (errorType) {
+ // Low risk errors
+ ErrorType.UNKNOWN -> RiskLevel.Low
+ ErrorType.ERROR_NET_INTERRUPT -> RiskLevel.Low
+ ErrorType.ERROR_NET_TIMEOUT -> RiskLevel.Low
+ ErrorType.ERROR_CONNECTION_REFUSED -> RiskLevel.Low
+ ErrorType.ERROR_UNKNOWN_SOCKET_TYPE -> RiskLevel.Low
+ ErrorType.ERROR_REDIRECT_LOOP -> RiskLevel.Low
+ ErrorType.ERROR_OFFLINE -> RiskLevel.Low
+ ErrorType.ERROR_NET_RESET -> RiskLevel.Low
+ ErrorType.ERROR_UNSAFE_CONTENT_TYPE -> RiskLevel.Low
+ ErrorType.ERROR_CORRUPTED_CONTENT -> RiskLevel.Low
+ ErrorType.ERROR_CONTENT_CRASHED -> RiskLevel.Low
+ ErrorType.ERROR_INVALID_CONTENT_ENCODING -> RiskLevel.Low
+ ErrorType.ERROR_UNKNOWN_HOST -> RiskLevel.Low
+ ErrorType.ERROR_MALFORMED_URI -> RiskLevel.Low
+ ErrorType.ERROR_FILE_NOT_FOUND -> RiskLevel.Low
+ ErrorType.ERROR_FILE_ACCESS_DENIED -> RiskLevel.Low
+ ErrorType.ERROR_PROXY_CONNECTION_REFUSED -> RiskLevel.Low
+ ErrorType.ERROR_UNKNOWN_PROXY_HOST -> RiskLevel.Low
+ ErrorType.ERROR_UNKNOWN_PROTOCOL -> RiskLevel.Low
+
+ // Medium risk errors
+ ErrorType.ERROR_SECURITY_BAD_CERT -> RiskLevel.Medium
+ ErrorType.ERROR_SECURITY_SSL -> RiskLevel.Medium
+ ErrorType.ERROR_PORT_BLOCKED -> RiskLevel.Medium
+
+ // High risk errors
+ ErrorType.ERROR_SAFEBROWSING_HARMFUL_URI -> RiskLevel.High
+ ErrorType.ERROR_SAFEBROWSING_MALWARE_URI -> RiskLevel.High
+ ErrorType.ERROR_SAFEBROWSING_PHISHING_URI -> RiskLevel.High
+ ErrorType.ERROR_SAFEBROWSING_UNWANTED_URI -> RiskLevel.High
+ }
+ }
+
+ sealed class RiskLevel {
+ object Low : RiskLevel()
+ object Medium : RiskLevel()
+ object High : RiskLevel()
}
}
diff --git a/app/src/main/res/raw/high_risk_error_style.css b/app/src/main/res/raw/high_risk_error_style.css
new file mode 100644
index 0000000000..eb7014453a
--- /dev/null
+++ b/app/src/main/res/raw/high_risk_error_style.css
@@ -0,0 +1,224 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+html,
+body {
+ margin: 0;
+ padding: 0;
+ height: 100%;
+ --moz-vertical-spacing: 10px;
+ --moz-background-height: 32px;
+}
+
+body {
+ background-size: 64px var(--moz-background-height);
+ /* background-size: 64px 32px; */
+ background-repeat: repeat-x;
+ background-color: #c50042;
+ color: #ffffff;
+ padding: 0 40px;
+ font-size: 14px;
+ -moz-text-size-adjust: none;
+ font-family: sharp-sans;
+}
+
+ul {
+ /* Shove the list indicator so that its left aligned, but use outside so that text
+ * doesn't don't wrap the text around it */
+ padding: 0 1em;
+ margin: 0;
+ list-style-type: disc;
+}
+
+#errorShortDesc,
+li:not(:last-of-type) {
+ /* Margins between the li and buttons below it won't be collapsed. Remove the bottom margin here. */
+ margin: var(--moz-vertical-spacing) 0;
+}
+
+li > button {
+ /* Removing the normal padding on the li so this stretched edge to edge. */
+ margin-left: -1em;
+ margin-right: -1em;
+ width: calc(100% + 2em);
+}
+
+/* Push the #ignoreWarningButton to the bottom on the blocked site page */
+.blockedsite > #errorPageContainer > #errorLongContent {
+ flex: 1;
+}
+
+h1 {
+ margin: 0;
+ padding: 0;
+ margin: var(--moz-vertical-spacing) 0;
+ color: #ffffff;
+ font-family: sharp-sans;
+ font-weight: bold;
+ font-size: 20px;
+ line-height: 24px;
+}
+
+p {
+ line-height: 20px;
+ margin: var(--moz-vertical-spacing) 0;
+ color: #ffffff;
+}
+
+button {
+ /* Force buttons to display: block here to try and enforce collapsing margins */
+ display: block;
+ height: 36px;
+ width: 100%;
+ border-radius: 5px;
+ border-color: #e3e3e7;
+ font-family: sharp-sans;
+ background-color: #e6e6eb;
+ color: #2f2c61;
+ font-size: 14px;
+ font-weight: bold;
+ position: fixed;
+ bottom: 80px;
+ text-aligned:center;
+ vertical-aligned:center;
+ background-image: none;
+}
+
+button.inProgress {
+ background-image: linear-gradient(-45deg, #dfe8ee, #dfe8ee 33%,
+ #ecf0f3 33%, #ecf0f3 66%,
+ #dfe8ee 66%, #dfe8ee);
+ background-size: 37px 5px;
+ background-repeat: repeat-x;
+ animation: progress 6s linear infinite;
+}
+
+@keyframes progress {
+ from { background-position: 0 100%; }
+ to { background-position: 100% 100%; }
+}
+
+.certerror {
+ background-image: linear-gradient(-45deg, #f0d000, #f0d000 33%,
+ #fedc00 33%, #fedc00 66%,
+ #f0d000 66%, #f0d000);
+}
+
+.blockedsite {
+ background-image: linear-gradient(-45deg, #9b2e2e, #9b2e2e 33%,
+ #a83232 33%, #a83232 66%,
+ #9b2e2e 66%, #9b2e2e);
+ background-color: #b14646;
+ color: white;
+}
+
+#errorPageContainer {
+ /* If the page is greater than 550px center the content.
+ * This number should be kept in sync with the media query for tablets below */
+ max-width: 550px;
+ margin: 0 auto;
+ transform: translateY(var(--moz-background-height));
+ padding-bottom: var(--moz-vertical-spacing);
+
+ min-height: calc(100% - var(--moz-background-height) - var(--moz-vertical-spacing));
+ display: flex;
+ flex-direction: column;
+}
+
+/* Expanders have a structure of
+ *
+ *
Title
+ *
Content
+ *
+ *
+ * This shows an arrow to the right of the h2 element, and hides the content when collapsed="true". */
+.expander {
+ margin: var(--moz-vertical-spacing) 0;
+ background-image: url("chrome://browser/skin/images/dropmarker.svg");
+ background-repeat: no-repeat;
+ /* dropmarker.svg is 10x7. Ensure that its centered in the middle of an 18x18 box */
+ background-position: 3px 5.5px;
+ background-size: 10px 7px;
+ padding-left: 18px;
+}
+
+div[collapsed="true"] > .expander {
+ background-image: url("chrome://browser/skin/images/dropmarker-right.svg");
+ /* dropmarker.svg is 7x10. Ensure that its centered in the middle of an 18x18 box */
+ background-size: 7px 10px;
+ background-position: 5.5px 4px;
+}
+
+div[hidden] > .expander,
+div[hidden] > .expander + *,
+div[collapsed="true"] > .expander + * {
+ display: none;
+}
+
+.blockedsite h1 {
+ border-bottom-color: #9b2e2e;
+}
+
+.blockedsite button {
+ background-color: #9b2e2e;
+ color: white;
+}
+
+/* Style warning button to look like a small text link in the
+ bottom. This is preferable to just using a text link
+ since there is already a mechanism in browser.js for trapping
+ oncommand events from unprivileged chrome pages (ErrorPageEventHandler).*/
+#ignoreWarningButton {
+ width: calc(100% + 40px);
+ -moz-appearance: none;
+ background: #b14646;
+ border: none;
+ text-decoration: underline;
+ margin: 0;
+ margin-inline-start: -20px;
+ font-size: smaller;
+ border-radius: 0;
+}
+
+/* On large screen devices (hopefully a 7+ inch tablet, we already center content (see #errorPageContainer above).
+ Apply tablet specific styles here */
+@media (min-width: 550px) {
+ button {
+ min-width: 160px;
+ width: auto;
+ }
+
+ /* If the tablet is tall as well, add some padding to make content feel a bit more centered */
+ @media (min-height: 550px) {
+ #errorPageContainer {
+ padding-top: 64px;
+ min-height: calc(100% - 64px);
+ }
+ }
+}
+
+#searchbox {
+ padding: 0;
+ display: flex;
+ margin: var(--moz-vertical-spacing) -1em;
+}
+
+#searchbox > input {
+ flex: 3;
+ padding: 0em 3em 0em 1em;
+ width: 100%;
+ border: none;
+ font-family: sans-serif;
+ background-image: none;
+ background-color: white;
+ border-radius-top-right: none;
+ border-radius-bottom-right: none;
+}
+
+#searchbox > button {
+ flex: 1;
+ margin: 0;
+ width: auto;
+}
+
diff --git a/app/src/main/res/raw/low_and_medium_risk_error_style.css b/app/src/main/res/raw/low_and_medium_risk_error_style.css
new file mode 100644
index 0000000000..a9441b94bd
--- /dev/null
+++ b/app/src/main/res/raw/low_and_medium_risk_error_style.css
@@ -0,0 +1,224 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+html,
+body {
+ margin: 0;
+ padding: 0;
+ height: 100%;
+ --moz-vertical-spacing: 10px;
+ --moz-background-height: 32px;
+}
+
+body {
+ background-size: 64px var(--moz-background-height);
+ /* background-size: 64px 32px; */
+ background-repeat: repeat-x;
+ background-color: #f9f9fb;
+ color: #15141A;
+ padding: 0 40px;
+ font-size: 14px;
+ -moz-text-size-adjust: none;
+ font-family: sharp-sans;
+}
+
+ul {
+ /* Shove the list indicator so that its left aligned, but use outside so that text
+ * doesn't don't wrap the text around it */
+ padding: 0 1em;
+ margin: 0;
+ list-style-type: disc;
+}
+
+#errorShortDesc,
+li:not(:last-of-type) {
+ /* Margins between the li and buttons below it won't be collapsed. Remove the bottom margin here. */
+ margin: var(--moz-vertical-spacing) 0;
+}
+
+li > button {
+ /* Removing the normal padding on the li so this stretched edge to edge. */
+ margin-left: -1em;
+ margin-right: -1em;
+ width: calc(100% + 2em);
+}
+
+/* Push the #ignoreWarningButton to the bottom on the blocked site page */
+.blockedsite > #errorPageContainer > #errorLongContent {
+ flex: 1;
+}
+
+h1 {
+ margin: 0;
+ padding: 0;
+ margin: var(--moz-vertical-spacing) 0;
+ color: #312a65;
+ font-family: sharp-sans;
+ font-weight: bold;
+ font-size: 20px;
+ line-height: 24px;
+}
+
+p {
+ line-height: 20px;
+ margin: var(--moz-vertical-spacing) 0;
+}
+
+button {
+ /* Force buttons to display: block here to try and enforce collapsing margins */
+ display: block;
+ height: 36px;
+ width: 100%;
+ border-radius: 5px;
+ border-color: #312a65;
+ font-family: sharp-sans;
+ background-color: #312a65;
+ color: #FFFFFF;
+ line-height:16px;
+ font-size: 14px;
+ font-weight: bold;
+ position: fixed;
+ bottom: 80px;
+ text-aligned:center;
+ vertical-aligned:center;
+ background-image: none;
+}
+
+button.inProgress {
+ background-image: linear-gradient(-45deg, #dfe8ee, #dfe8ee 33%,
+ #ecf0f3 33%, #ecf0f3 66%,
+ #dfe8ee 66%, #dfe8ee);
+ background-size: 37px 5px;
+ background-repeat: repeat-x;
+ animation: progress 6s linear infinite;
+}
+
+@keyframes progress {
+ from { background-position: 0 100%; }
+ to { background-position: 100% 100%; }
+}
+
+.certerror {
+ background-image: linear-gradient(-45deg, #f0d000, #f0d000 33%,
+ #fedc00 33%, #fedc00 66%,
+ #f0d000 66%, #f0d000);
+}
+
+.blockedsite {
+ background-image: linear-gradient(-45deg, #9b2e2e, #9b2e2e 33%,
+ #a83232 33%, #a83232 66%,
+ #9b2e2e 66%, #9b2e2e);
+ background-color: #b14646;
+ color: white;
+}
+
+#errorPageContainer {
+ /* If the page is greater than 550px center the content.
+ * This number should be kept in sync with the media query for tablets below */
+ max-width: 550px;
+ margin: 0 auto;
+ transform: translateY(var(--moz-background-height));
+ padding-bottom: var(--moz-vertical-spacing);
+
+ min-height: calc(100% - var(--moz-background-height) - var(--moz-vertical-spacing));
+ display: flex;
+ flex-direction: column;
+}
+
+/* Expanders have a structure of
+ *
+ *
Title
+ *
Content
+ *
+ *
+ * This shows an arrow to the right of the h2 element, and hides the content when collapsed="true". */
+.expander {
+ margin: var(--moz-vertical-spacing) 0;
+ background-image: url("chrome://browser/skin/images/dropmarker.svg");
+ background-repeat: no-repeat;
+ /* dropmarker.svg is 10x7. Ensure that its centered in the middle of an 18x18 box */
+ background-position: 3px 5.5px;
+ background-size: 10px 7px;
+ padding-left: 18px;
+}
+
+div[collapsed="true"] > .expander {
+ background-image: url("chrome://browser/skin/images/dropmarker-right.svg");
+ /* dropmarker.svg is 7x10. Ensure that its centered in the middle of an 18x18 box */
+ background-size: 7px 10px;
+ background-position: 5.5px 4px;
+}
+
+div[hidden] > .expander,
+div[hidden] > .expander + *,
+div[collapsed="true"] > .expander + * {
+ display: none;
+}
+
+.blockedsite h1 {
+ border-bottom-color: #9b2e2e;
+}
+
+.blockedsite button {
+ background-color: #9b2e2e;
+ color: white;
+}
+
+/* Style warning button to look like a small text link in the
+ bottom. This is preferable to just using a text link
+ since there is already a mechanism in browser.js for trapping
+ oncommand events from unprivileged chrome pages (ErrorPageEventHandler).*/
+#ignoreWarningButton {
+ width: calc(100% + 40px);
+ -moz-appearance: none;
+ background: #b14646;
+ border: none;
+ text-decoration: underline;
+ margin: 0;
+ margin-inline-start: -20px;
+ font-size: smaller;
+ border-radius: 0;
+}
+
+/* On large screen devices (hopefully a 7+ inch tablet, we already center content (see #errorPageContainer above).
+ Apply tablet specific styles here */
+@media (min-width: 550px) {
+ button {
+ min-width: 160px;
+ width: auto;
+ }
+
+ /* If the tablet is tall as well, add some padding to make content feel a bit more centered */
+ @media (min-height: 550px) {
+ #errorPageContainer {
+ padding-top: 64px;
+ min-height: calc(100% - 64px);
+ }
+ }
+}
+
+#searchbox {
+ padding: 0;
+ display: flex;
+ margin: var(--moz-vertical-spacing) -1em;
+}
+
+#searchbox > input {
+ flex: 3;
+ padding: 0em 3em 0em 1em;
+ width: 100%;
+ border: none;
+ font-family: sans-serif;
+ background-image: none;
+ background-color: white;
+ border-radius-top-right: none;
+ border-radius-bottom-right: none;
+}
+
+#searchbox > button {
+ flex: 1;
+ margin: 0;
+ width: auto;
+}
+
diff --git a/app/src/main/res/raw/low_risk_error_pages.html b/app/src/main/res/raw/low_risk_error_pages.html
new file mode 100644
index 0000000000..13652d719b
--- /dev/null
+++ b/app/src/main/res/raw/low_risk_error_pages.html
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+ %pageTitle%
+
+
+
+
+
+
+
+
+
+
%messageShort%
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/raw/medium_and_high_risk_error_pages.html b/app/src/main/res/raw/medium_and_high_risk_error_pages.html
new file mode 100644
index 0000000000..0fb2d097b1
--- /dev/null
+++ b/app/src/main/res/raw/medium_and_high_risk_error_pages.html
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+ %pageTitle%
+
+
+
+
+
+
+
+
+
+
%messageShort%
+
+
+
+
+
+
+
+
+
+