0

[iOS] Adjust supervised user interstitial font size from iOS settings

This CL allows the "Ask your parent" interstitial to adjust to iOS system text size. "Zoom text..." from 3-dot menu will still work on
top of this.

Based on components/security_interstitials/.../interstitial_large.html

Bug: 405993406
Change-Id: I26c3e0135428fa38b8b692484198252ff97f7eb9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6395058
Commit-Queue: Duong Dac <ddac@chromium.org>
Reviewed-by: Carlos IL <carlosil@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1439803}
This commit is contained in:
Duong Dac 2025-03-28 17:33:21 -07:00 committed by Chromium LUCI CQ
parent 7e6217a4e8
commit 6b98302a77
15 changed files with 136 additions and 78 deletions

@ -5,6 +5,7 @@
#include "chrome/browser/ui/webui/interstitials/interstitial_ui.h"
#include <memory>
#include <optional>
#include <utility>
#include "base/atomic_sequence_num.h"
@ -734,5 +735,5 @@ std::string InterstitialHTMLSource::GetSupervisedUserInterstitialHTML(
allow_access_requests, first_custodian, second_custodian, reason,
g_browser_process->GetApplicationLocale(),
/*already_sent_remote_request=*/false,
/*is_main_frame=*/true);
/*is_main_frame=*/true, /*ios_font_size_multiplier=*/std::nullopt);
}

@ -36,6 +36,8 @@ static_library("core") {
"ssl_error_ui.h",
"urls.cc",
"urls.h",
"utils.cc",
"utils.h",
]
if (!is_ios) {

@ -0,0 +1,27 @@
// Copyright 2025 The Chromium Authors
// 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/utils.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
namespace security_interstitials {
void AdjustFontSize(base::Value::Dict& load_time_data,
float font_size_multiplier) {
std::string* value = load_time_data.FindString("fontsize");
CHECK(value);
std::string old_size = *value;
// `old_size` should be in form of "75%".
CHECK(old_size.size() > 1 && old_size.back() == '%');
double new_size = 75.0;
bool converted =
base::StringToDouble(old_size.substr(0, old_size.size() - 1), &new_size);
CHECK(converted);
new_size *= font_size_multiplier;
load_time_data.Set("fontsize", base::StringPrintf("%.0lf%%", new_size));
}
} // namespace security_interstitials

@ -0,0 +1,19 @@
// Copyright 2025 The Chromium Authors
// 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_UTILS_H_
#define COMPONENTS_SECURITY_INTERSTITIALS_CORE_UTILS_H_
#include "base/values.h"
namespace security_interstitials {
// Adjusts the interstitial page's template parameter "fontsize" by the font
// size multiplier.
void AdjustFontSize(base::Value::Dict& load_time_data,
float font_size_multiplier);
} // namespace security_interstitials
#endif // COMPONENTS_SECURITY_INTERSTITIALS_CORE_UTILS_H_

@ -10,6 +10,7 @@ include_rules = [
"+components/prefs",
"+components/pref_registry",
"+components/safe_search_api",
"+components/security_interstitials/core",
"+components/strings/grit",
"+components/signin",
"+components/sync",

@ -125,6 +125,7 @@ static_library("browser") {
"//components/google/core/common",
"//components/prefs",
"//components/resources:components_resources",
"//components/security_interstitials/core",
"//components/signin/internal/identity_manager",
"//components/signin/public/base",
"//components/signin/public/identity_manager",

@ -14,7 +14,7 @@
<script src="%ROOT_GEN_DIR%/components/supervised_user/core/browser/resources/minified/supervised_user_block_interstitial_v3.js"></script>
</if>
</head>
<body class="supervised-user-block">
<body class="supervised-user-block" <if expr="is_ios">style="font-size: $i18n{fontsize}"</if>>
<div class="frame-blocked" id="frame-blocked" tabindex="-1">
<div class="message-container">
<picture id="error-page-illustration">

@ -12,6 +12,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "components/grit/components_resources.h"
#include "components/security_interstitials/core/utils.h"
#include "components/signin/public/base/avatar_icon_util.h"
#include "components/strings/grit/components_strings.h"
#include "components/supervised_user/core/browser/supervised_user_service.h"
@ -78,50 +79,54 @@ std::string BuildErrorPageHtml(bool allow_access_requests,
FilteringBehaviorReason reason,
const std::string& app_locale,
bool already_sent_remote_request,
bool is_main_frame) {
base::Value::Dict strings;
strings.Set("blockPageTitle",
l10n_util::GetStringUTF8(IDS_BLOCK_INTERSTITIAL_TITLE));
strings.Set("allowAccessRequests", allow_access_requests);
bool is_main_frame,
std::optional<float> ios_font_size_multiplier) {
base::Value::Dict load_time_data;
load_time_data.Set("blockPageTitle",
l10n_util::GetStringUTF8(IDS_BLOCK_INTERSTITIAL_TITLE));
load_time_data.Set("allowAccessRequests", allow_access_requests);
if (custodian.has_value()) {
strings.Set("custodianName", custodian->GetName());
strings.Set("custodianEmail", custodian->GetEmailAddress());
strings.Set(
load_time_data.Set("custodianName", custodian->GetName());
load_time_data.Set("custodianEmail", custodian->GetEmailAddress());
load_time_data.Set(
"avatarURL1x",
BuildAvatarImageUrl(custodian->GetProfileImageUrl(), kAvatarSize1x));
strings.Set(
load_time_data.Set(
"avatarURL2x",
BuildAvatarImageUrl(custodian->GetProfileImageUrl(), kAvatarSize2x));
} else {
// empty custodianName denotes no custodian, see
// components/supervised_user/core/browser/resources/supervised_user_block_interstitial_v2.js
strings.Set("custodianName", "");
load_time_data.Set("custodianName", "");
}
if (second_custodian.has_value()) {
strings.Set("secondCustodianName", second_custodian->GetName());
strings.Set("secondCustodianEmail", second_custodian->GetEmailAddress());
strings.Set("secondAvatarURL1x",
BuildAvatarImageUrl(second_custodian->GetProfileImageUrl(),
kAvatarSize1x));
strings.Set("secondAvatarURL2x",
BuildAvatarImageUrl(second_custodian->GetProfileImageUrl(),
kAvatarSize2x));
load_time_data.Set("secondCustodianName", second_custodian->GetName());
load_time_data.Set("secondCustodianEmail",
second_custodian->GetEmailAddress());
load_time_data.Set(
"secondAvatarURL1x",
BuildAvatarImageUrl(second_custodian->GetProfileImageUrl(),
kAvatarSize1x));
load_time_data.Set(
"secondAvatarURL2x",
BuildAvatarImageUrl(second_custodian->GetProfileImageUrl(),
kAvatarSize2x));
} else {
// empty secondCustodianName denotes no second custodian, see
// components/supervised_user/core/browser/resources/supervised_user_block_interstitial_v2.js
strings.Set("secondCustodianName", "");
load_time_data.Set("secondCustodianName", "");
}
strings.Set("alreadySentRemoteRequest", already_sent_remote_request);
strings.Set("isMainFrame", is_main_frame);
load_time_data.Set("alreadySentRemoteRequest", already_sent_remote_request);
load_time_data.Set("isMainFrame", is_main_frame);
bool local_web_approvals_enabled =
(is_main_frame && supervised_user::IsLocalWebApprovalsEnabled()) ||
(!is_main_frame &&
supervised_user::IsLocalWebApprovalsEnabledForSubframes());
strings.Set("isLocalWebApprovalsEnabled", local_web_approvals_enabled);
load_time_data.Set("isLocalWebApprovalsEnabled", local_web_approvals_enabled);
std::string block_page_header;
std::string block_page_message;
@ -135,36 +140,41 @@ std::string BuildErrorPageHtml(bool allow_access_requests,
IDS_BLOCK_INTERSTITIAL_HEADER_ACCESS_REQUESTS_DISABLED);
}
strings.Set("blockPageHeader", block_page_header);
strings.Set("blockPageMessage", block_page_message);
load_time_data.Set("blockPageHeader", block_page_header);
load_time_data.Set("blockPageMessage", block_page_message);
if (!supervised_user::IsBlockInterstitialV3Enabled()) {
// For the V2 interstitial, the filtering reason is displayed in a
// separate UI component.
strings.Set("blockReasonMessage",
l10n_util::GetStringUTF8(GetBlockMessageID(
reason, /*single_parent=*/!second_custodian.has_value())));
strings.Set("blockReasonHeader",
l10n_util::GetStringUTF8(IDS_SUPERVISED_USER_BLOCK_HEADER));
strings.Set("siteBlockHeader",
l10n_util::GetStringUTF8(IDS_GENERIC_SITE_BLOCK_HEADER));
strings.Set("showDetailsLink",
l10n_util::GetStringUTF8(IDS_BLOCK_INTERSTITIAL_SHOW_DETAILS));
strings.Set("hideDetailsLink",
l10n_util::GetStringUTF8(IDS_BLOCK_INTERSTITIAL_HIDE_DETAILS));
load_time_data.Set(
"blockReasonMessage",
l10n_util::GetStringUTF8(GetBlockMessageID(
reason, /*single_parent=*/!second_custodian.has_value())));
load_time_data.Set(
"blockReasonHeader",
l10n_util::GetStringUTF8(IDS_SUPERVISED_USER_BLOCK_HEADER));
load_time_data.Set("siteBlockHeader",
l10n_util::GetStringUTF8(IDS_GENERIC_SITE_BLOCK_HEADER));
load_time_data.Set(
"showDetailsLink",
l10n_util::GetStringUTF8(IDS_BLOCK_INTERSTITIAL_SHOW_DETAILS));
load_time_data.Set(
"hideDetailsLink",
l10n_util::GetStringUTF8(IDS_BLOCK_INTERSTITIAL_HIDE_DETAILS));
}
strings.Set(
load_time_data.Set(
"remoteApprovalsButton",
l10n_util::GetStringUTF8(IDS_BLOCK_INTERSTITIAL_ASK_IN_A_MESSAGE_BUTTON));
strings.Set("backButton", l10n_util::GetStringUTF8(IDS_REQUEST_SENT_OK));
load_time_data.Set("backButton",
l10n_util::GetStringUTF8(IDS_REQUEST_SENT_OK));
strings.Set(
load_time_data.Set(
"localApprovalsButton",
l10n_util::GetStringUTF8(IDS_BLOCK_INTERSTITIAL_ASK_IN_PERSON_BUTTON));
strings.Set("localApprovalsRemoteRequestSentButton",
l10n_util::GetStringUTF8(
IDS_BLOCK_INTERSTITIAL_ASK_IN_PERSON_INSTEAD_BUTTON));
load_time_data.Set("localApprovalsRemoteRequestSentButton",
l10n_util::GetStringUTF8(
IDS_BLOCK_INTERSTITIAL_ASK_IN_PERSON_INSTEAD_BUTTON));
std::string request_sent_message;
std::string request_failed_message;
@ -180,17 +190,24 @@ std::string BuildErrorPageHtml(bool allow_access_requests,
? IDS_CHILD_BLOCK_INTERSTITIAL_REQUEST_FAILED_MESSAGE_SINGLE_PARENT
: IDS_CHILD_BLOCK_INTERSTITIAL_REQUEST_FAILED_MESSAGE_MULTI_PARENT);
strings.Set("requestSentMessage", std::move(request_sent_message));
strings.Set("requestSentDescription", std::move(request_sent_description));
strings.Set("requestFailedMessage", std::move(request_failed_message));
webui::SetLoadTimeDataDefaults(app_locale, &strings);
load_time_data.Set("requestSentMessage", std::move(request_sent_message));
load_time_data.Set("requestSentDescription",
std::move(request_sent_description));
load_time_data.Set("requestFailedMessage", std::move(request_failed_message));
webui::SetLoadTimeDataDefaults(app_locale, &load_time_data);
if (ios_font_size_multiplier) {
security_interstitials::AdjustFontSize(load_time_data,
ios_font_size_multiplier.value());
}
std::string html =
ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(
supervised_user::IsBlockInterstitialV3Enabled()
? IDR_SUPERVISED_USER_BLOCK_INTERSTITIAL_V3_HTML
: IDR_SUPERVISED_USER_BLOCK_INTERSTITIAL_V2_HTML);
webui::AppendWebUiCssTextDefaults(&html);
std::string error_html = webui::GetI18nTemplateHtml(html, strings);
std::string error_html = webui::GetI18nTemplateHtml(html, load_time_data);
return error_html;
}

@ -22,7 +22,8 @@ std::string BuildErrorPageHtml(bool allow_access_requests,
FilteringBehaviorReason reason,
const std::string& app_locale,
bool already_sent_remote_request,
bool is_main_frame);
bool is_main_frame,
std::optional<float> ios_font_size_multiplier);
} // namespace supervised_user

@ -4,6 +4,8 @@
#include "components/supervised_user/core/browser/supervised_user_error_page.h"
#include <optional>
#include "base/memory/raw_ptr_exclusion.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_feature_list.h"
@ -195,7 +197,8 @@ TEST_P(SupervisedUserErrorPageTest_BuildHtml, BuildHtml) {
param.allow_access_requests, param.custodian, param.second_custodian,
param.reason,
/*app_locale=*/"",
/*already_sent_remote_request=*/false, /*is_main_frame=*/true);
/*already_sent_remote_request=*/false, /*is_main_frame=*/true,
/*ios_font_size_multiplier=*/std::nullopt);
VerifyCustodianInfo();

@ -21,6 +21,7 @@
#include "base/values.h"
#include "build/build_config.h"
#include "components/prefs/pref_service.h"
#include "components/supervised_user/core/browser/supervised_user_error_page.h"
#include "components/supervised_user/core/browser/supervised_user_service.h"
#include "components/supervised_user/core/browser/supervised_user_utils.h"
#include "components/supervised_user/core/browser/web_content_handler.h"
@ -75,16 +76,15 @@ std::string SupervisedUserInterstitial::GetHTMLContents(
FilteringBehaviorReason reason,
bool already_sent_request,
bool is_main_frame,
const std::string& application_locale) {
const std::string& application_locale,
std::optional<float> ios_font_size_multiplier) {
bool allow_access_requests =
supervised_user_service->remote_web_approvals_manager()
.AreApprovalRequestsEnabled();
return BuildErrorPageHtml(
allow_access_requests, supervised_user_service->GetCustodian(),
supervised_user_service->GetSecondCustodian(), reason, application_locale,
already_sent_request, is_main_frame);
already_sent_request, is_main_frame, ios_font_size_multiplier);
}
void SupervisedUserInterstitial::GoBack() {

@ -10,7 +10,7 @@
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ref.h"
#include "components/supervised_user/core/browser/supervised_user_error_page.h"
#include "components/supervised_user/core/browser/supervised_user_utils.h"
#include "url/gurl.h"
class PrefService;
@ -75,13 +75,15 @@ class SupervisedUserInterstitial {
const std::u16string& supervised_user_name,
FilteringBehaviorReason reason);
// Returns the HTML contents of the error page.
static std::string GetHTMLContents(
SupervisedUserService* supervised_user_service,
PrefService* pref_service,
FilteringBehaviorReason reason,
bool already_sent_request,
bool is_main_frame,
const std::string& application_locale);
const std::string& application_locale,
std::optional<float> font_size_multiplier = std::nullopt);
void GoBack();
void RequestUrlAccessRemote(base::OnceCallback<void(bool)> callback);

@ -326,6 +326,7 @@ source_set("web_internal") {
"//ios/components/security_interstitials/https_only_mode:feature",
"//ios/components/security_interstitials/lookalikes",
"//ios/components/security_interstitials/safe_browsing",
"//ios/components/ui_util",
"//ios/components/webui:url_constants",
"//ios/net",
"//ios/public/provider/chrome/browser/additional_features:additional_features_api",

@ -94,6 +94,7 @@
#import "ios/components/security_interstitials/lookalikes/lookalike_url_error.h"
#import "ios/components/security_interstitials/safe_browsing/safe_browsing_error.h"
#import "ios/components/security_interstitials/safe_browsing/safe_browsing_unsafe_resource_container.h"
#import "ios/components/ui_util/dynamic_type_util.h"
#import "ios/components/webui/web_ui_url_constants.h"
#import "ios/net/protocol_handler_util.h"
#import "ios/public/provider/chrome/browser/url_rewriters/url_rewriters_api.h"
@ -213,7 +214,8 @@ NSString* GetSupervisedUserErrorPageHTML(web::WebState* web_state,
profile->GetPrefs(), error_info->filtering_behavior_reason(),
container->IsRemoteApprovalPendingForUrl(url),
error_info->is_main_frame(),
GetApplicationContext()->GetApplicationLocale());
GetApplicationContext()->GetApplicationLocale(),
ui_util::SystemSuggestedFontSizeMultiplier());
security_interstitials::IOSBlockingPageTabHelper::FromWebState(web_state)
->AssociateBlockingPage(navigation_id, std::move(page));

@ -7,10 +7,9 @@
#import "base/check.h"
#import "base/feature_list.h"
#import "base/metrics/histogram_macros.h"
#import "base/strings/string_number_conversions.h"
#import "base/strings/stringprintf.h"
#import "components/grit/components_resources.h"
#import "components/security_interstitials/core/common_string_util.h"
#import "components/security_interstitials/core/utils.h"
#import "ios/components/security_interstitials/ios_blocking_page_controller_client.h"
#import "ios/components/ui_util/dynamic_type_util.h"
#import "ios/web/common/features.h"
@ -20,24 +19,6 @@
namespace security_interstitials {
namespace {
// Adjusts the interstitial page's template parameter "fontsize" by system font
// size multiplier.
void AdjustFontSize(base::Value::Dict& load_time_data) {
std::string* value = load_time_data.FindString("fontsize");
DCHECK(value);
std::string old_size = *value;
// `old_size` should be in form of "75%".
DCHECK(old_size.size() > 1 && old_size.back() == '%');
double new_size = 75.0;
bool converted =
base::StringToDouble(old_size.substr(0, old_size.size() - 1), &new_size);
DCHECK(converted);
new_size *= ui_util::SystemSuggestedFontSizeMultiplier();
load_time_data.Set("fontsize", base::StringPrintf("%.0lf%%", new_size));
}
} // namespace
IOSSecurityInterstitialPage::IOSSecurityInterstitialPage(
web::WebState* web_state,
const GURL& request_url,
@ -55,7 +36,7 @@ std::string IOSSecurityInterstitialPage::GetHtmlContents() const {
PopulateInterstitialStrings(load_time_data);
webui::SetLoadTimeDataDefaults(client_->GetApplicationLocale(),
&load_time_data);
AdjustFontSize(load_time_data);
AdjustFontSize(load_time_data, ui_util::SystemSuggestedFontSizeMultiplier());
std::string html =
ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(
IDR_SECURITY_INTERSTITIAL_HTML);