summaryrefslogtreecommitdiffstats
path: root/chromium/chrome/browser/ui/webui/settings
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-07-16 11:45:35 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-07-17 08:59:23 +0000
commit552906b0f222c5d5dd11b9fd73829d510980461a (patch)
tree3a11e6ed0538a81dd83b20cf3a4783e297f26d91 /chromium/chrome/browser/ui/webui/settings
parent1b05827804eaf047779b597718c03e7d38344261 (diff)
BASELINE: Update Chromium to 83.0.4103.122
Change-Id: Ie3a82f5bb0076eec2a7c6a6162326b4301ee291e Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/chrome/browser/ui/webui/settings')
-rw-r--r--chromium/chrome/browser/ui/webui/settings/OWNERS5
-rw-r--r--chromium/chrome/browser/ui/webui/settings/about_handler.cc105
-rw-r--r--chromium/chrome/browser/ui/webui/settings/about_handler.h13
-rw-r--r--chromium/chrome/browser/ui/webui/settings/browser_lifetime_handler.cc9
-rw-r--r--chromium/chrome/browser/ui/webui/settings/change_password_handler.cc81
-rw-r--r--chromium/chrome/browser/ui/webui/settings/change_password_handler.h51
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/DEPS4
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/OWNERS4
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc85
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h28
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler_unittest.cc103
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc29
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.h3
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.cc32
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.h39
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.cc393
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.h296
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator_test_api.h156
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc5
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h2
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc335
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.h42
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc120
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h24
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/date_time_handler.cc4
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc46
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler_unittest.cc68
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc312
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.h57
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler_browsertest.cc322
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc520
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h169
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler_unittest.cc516
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.cc8
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/internet_handler.cc6
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/internet_strings_provider.cc252
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/internet_strings_provider.h59
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h2
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.cc2136
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.h91
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_factory.cc66
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_factory.h47
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_unittest.cc104
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_per_page_strings_provider.cc32
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_per_page_strings_provider.h73
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc350
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.h47
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.cc33
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.h4
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/pref_names.cc20
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/pref_names.h18
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/quick_unlock_handler.cc38
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/quick_unlock_handler.h42
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/BUILD.gn17
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/OWNERS7
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/search.mojom33
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/search_concept.h62
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc107
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.h77
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_factory.cc61
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_factory.h45
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc78
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/search_result_icon.mojom14
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker.cc131
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker.h74
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker_unittest.cc176
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/user_action_recorder.mojom28
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/server_printer_url_util.cc73
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/server_printer_url_util.h30
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/server_printer_url_util_unittest.cc89
-rw-r--r--chromium/chrome/browser/ui/webui/settings/font_handler.cc77
-rw-r--r--chromium/chrome/browser/ui/webui/settings/font_handler.h31
-rw-r--r--chromium/chrome/browser/ui/webui/settings/hats_handler.cc37
-rw-r--r--chromium/chrome/browser/ui/webui/settings/hats_handler.h39
-rw-r--r--chromium/chrome/browser/ui/webui/settings/hats_handler_unittest.cc65
-rw-r--r--chromium/chrome/browser/ui/webui/settings/import_data_handler.cc (renamed from chromium/chrome/browser/ui/webui/settings/settings_import_data_handler.cc)103
-rw-r--r--chromium/chrome/browser/ui/webui/settings/import_data_handler.h (renamed from chromium/chrome/browser/ui/webui/settings/settings_import_data_handler.h)22
-rw-r--r--chromium/chrome/browser/ui/webui/settings/people_handler.cc137
-rw-r--r--chromium/chrome/browser/ui/webui/settings/people_handler.h29
-rw-r--r--chromium/chrome/browser/ui/webui/settings/people_handler_unittest.cc266
-rw-r--r--chromium/chrome/browser/ui/webui/settings/profile_info_handler.cc5
-rw-r--r--chromium/chrome/browser/ui/webui/settings/safe_browsing_handler.cc130
-rw-r--r--chromium/chrome/browser/ui/webui/settings/safe_browsing_handler.h62
-rw-r--r--chromium/chrome/browser/ui/webui/settings/safe_browsing_handler_unittest.cc248
-rw-r--r--chromium/chrome/browser/ui/webui/settings/safety_check_handler.cc600
-rw-r--r--chromium/chrome/browser/ui/webui/settings/safety_check_handler.h179
-rw-r--r--chromium/chrome/browser/ui/webui/settings/safety_check_handler_unittest.cc1055
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc121
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h21
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler_browsertest.cc110
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc2470
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_localized_strings_provider.h14
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc314
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler.h89
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler_browsertest.cc609
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_security_key_handler.cc7
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_ui.cc378
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_ui.h33
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_ui_browsertest.cc14
-rw-r--r--chromium/chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.cc243
-rw-r--r--chromium/chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.h36
-rw-r--r--chromium/chrome/browser/ui/webui/settings/site_settings_handler.cc396
-rw-r--r--chromium/chrome/browser/ui/webui/settings/site_settings_handler.h38
-rw-r--r--chromium/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc388
104 files changed, 13049 insertions, 3825 deletions
diff --git a/chromium/chrome/browser/ui/webui/settings/OWNERS b/chromium/chrome/browser/ui/webui/settings/OWNERS
index 93f7d799e7d..b19cbb7cc52 100644
--- a/chromium/chrome/browser/ui/webui/settings/OWNERS
+++ b/chromium/chrome/browser/ui/webui/settings/OWNERS
@@ -2,4 +2,9 @@ file://chrome/browser/resources/settings/OWNERS
per-file people_handler*=tangltom@chromium.org
+per-file safe_browsing_handler*=msramek@chromium.org
+per-file safe_browsing_handler*=sauski@google.com
+per-file site_settings_handler*=msramek@chromium.org
+per-file site_settings_handler*=sauski@google.com
+
# COMPONENT: UI>Settings
diff --git a/chromium/chrome/browser/ui/webui/settings/about_handler.cc b/chromium/chrome/browser/ui/webui/settings/about_handler.cc
index 21c3de52e0d..bcc0134af2f 100644
--- a/chromium/chrome/browser/ui/webui/settings/about_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/about_handler.cc
@@ -22,7 +22,9 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/system/sys_info.h"
#include "base/task/post_task.h"
+#include "base/task/thread_pool.h"
#include "base/time/time.h"
#include "base/values.h"
#include "build/branding_buildflags.h"
@@ -56,6 +58,7 @@
#if defined(OS_CHROMEOS)
#include "base/i18n/time_formatting.h"
+#include "chrome/browser/chromeos/arc/arc_util.h"
#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h"
#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h"
#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
@@ -71,6 +74,7 @@
#include "chromeos/constants/chromeos_switches.h"
#include "chromeos/dbus/power/power_manager_client.h"
#include "chromeos/dbus/update_engine_client.h"
+#include "chromeos/dbus/util/version_loader.h"
#include "chromeos/network/network_state.h"
#include "chromeos/network/network_state_handler.h"
#include "chromeos/system/statistics_provider.h"
@@ -227,6 +231,19 @@ std::string ReadRegulatoryLabelText(const base::FilePath& label_dir_path) {
return std::string();
}
+std::unique_ptr<base::DictionaryValue> GetVersionInfo() {
+ std::unique_ptr<base::DictionaryValue> version_info(
+ new base::DictionaryValue);
+ version_info->SetString("osVersion",
+ chromeos::version_loader::GetVersion(
+ chromeos::version_loader::VERSION_FULL));
+ version_info->SetString("arcVersion",
+ chromeos::version_loader::GetARCVersion());
+ version_info->SetString("osFirmware",
+ chromeos::version_loader::GetFirmware());
+ return version_info;
+}
+
#endif // defined(OS_CHROMEOS)
std::string UpdateStatusToString(VersionUpdater::Status status) {
@@ -335,16 +352,21 @@ AboutHandler* AboutHandler::Create(content::WebUIDataSource* html_source,
base::string16 os_with_linux_license = l10n_util::GetStringFUTF16(
IDS_ABOUT_CROS_WITH_LINUX_VERSION_LICENSE,
base::ASCIIToUTF16(chrome::kChromeUIOSCreditsURL),
- base::ASCIIToUTF16(chrome::kChromeUILinuxCreditsURL));
+ base::ASCIIToUTF16(chrome::kChromeUICrostiniCreditsURL));
html_source->AddString("aboutProductOsWithLinuxLicense",
os_with_linux_license);
html_source->AddBoolean("aboutEnterpriseManaged", IsEnterpriseManaged());
-
- html_source->AddString("endOfLifeMessage", l10n_util::GetStringFUTF16(
- IDS_EOL_NOTIFICATION_EOL,
- ui::GetChromeOSDeviceName()));
- html_source->AddString("endOfLifeLearnMoreURL",
- base::ASCIIToUTF16(chrome::kEolNotificationURL));
+ html_source->AddBoolean("aboutIsArcEnabled",
+ arc::IsArcPlayStoreEnabledForProfile(profile));
+ html_source->AddBoolean("aboutIsDeveloperMode",
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ chromeos::switches::kSystemDevMode));
+
+ html_source->AddString("endOfLifeMessage",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_ABOUT_PAGE_LAST_UPDATE_MESSAGE,
+ ui::GetChromeOSDeviceName(),
+ base::ASCIIToUTF16(chrome::kEolNotificationURL)));
#endif
return new AboutHandler();
@@ -380,6 +402,9 @@ void AboutHandler::RegisterMessages() {
base::BindRepeating(&AboutHandler::HandleRequestUpdateOverCellular,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
+ "getVersionInfo", base::BindRepeating(&AboutHandler::HandleGetVersionInfo,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
"getRegulatoryInfo",
base::BindRepeating(&AboutHandler::HandleGetRegulatoryInfo,
base::Unretained(this)));
@@ -387,6 +412,10 @@ void AboutHandler::RegisterMessages() {
"getChannelInfo", base::BindRepeating(&AboutHandler::HandleGetChannelInfo,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
+ "canChangeChannel",
+ base::BindRepeating(&AboutHandler::HandleCanChangeChannel,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
"refreshTPMFirmwareUpdateStatus",
base::BindRepeating(&AboutHandler::HandleRefreshTPMFirmwareUpdateStatus,
base::Unretained(this)));
@@ -572,17 +601,33 @@ void AboutHandler::HandleSetChannel(const base::ListValue* args) {
}
}
+void AboutHandler::HandleGetVersionInfo(const base::ListValue* args) {
+ CHECK_EQ(1U, args->GetSize());
+ std::string callback_id;
+ CHECK(args->GetString(0, &callback_id));
+ base::ThreadPool::PostTaskAndReplyWithResult(
+ FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE},
+ base::BindOnce(&GetVersionInfo),
+ base::BindOnce(&AboutHandler::OnGetVersionInfoReady,
+ weak_factory_.GetWeakPtr(), callback_id));
+}
+
+void AboutHandler::OnGetVersionInfoReady(
+ std::string callback_id,
+ std::unique_ptr<base::DictionaryValue> version_info) {
+ ResolveJavascriptCallback(base::Value(callback_id), *version_info);
+}
+
void AboutHandler::HandleGetRegulatoryInfo(const base::ListValue* args) {
CHECK_EQ(1U, args->GetSize());
std::string callback_id;
CHECK(args->GetString(0, &callback_id));
- base::PostTaskAndReplyWithResult(
- FROM_HERE,
- {base::ThreadPool(), base::MayBlock(), base::TaskPriority::USER_VISIBLE},
- base::Bind(&FindRegulatoryLabelDir),
- base::Bind(&AboutHandler::OnRegulatoryLabelDirFound,
- weak_factory_.GetWeakPtr(), callback_id));
+ base::ThreadPool::PostTaskAndReplyWithResult(
+ FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE},
+ base::BindOnce(&FindRegulatoryLabelDir),
+ base::BindOnce(&AboutHandler::OnRegulatoryLabelDirFound,
+ weak_factory_.GetWeakPtr(), callback_id));
}
void AboutHandler::HandleGetChannelInfo(const base::ListValue* args) {
@@ -595,6 +640,15 @@ void AboutHandler::HandleGetChannelInfo(const base::ListValue* args) {
callback_id));
}
+void AboutHandler::HandleCanChangeChannel(const base::ListValue* args) {
+ CHECK_EQ(1U, args->GetSize());
+ std::string callback_id;
+ CHECK(args->GetString(0, &callback_id));
+ ResolveJavascriptCallback(
+ base::Value(callback_id),
+ base::Value(CanChangeChannel(Profile::FromWebUI(web_ui()))));
+}
+
void AboutHandler::OnGetCurrentChannel(std::string callback_id,
const std::string& current_channel) {
version_updater_->GetChannel(
@@ -610,8 +664,6 @@ void AboutHandler::OnGetTargetChannel(std::string callback_id,
new base::DictionaryValue);
channel_info->SetString("currentChannel", current_channel);
channel_info->SetString("targetChannel", target_channel);
- channel_info->SetBoolean("canChangeChannel",
- CanChangeChannel(Profile::FromWebUI(web_ui())));
ResolveJavascriptCallback(base::Value(callback_id), *channel_info);
}
@@ -672,10 +724,14 @@ void AboutHandler::OnGetEndOfLifeInfo(
base::Value response(base::Value::Type::DICTIONARY);
if (!eol_info.eol_date.is_null()) {
response.SetBoolKey("hasEndOfLife", eol_info.eol_date <= base::Time::Now());
- response.SetStringKey("aboutPageEndOfLifeMessage",
- l10n_util::GetStringFUTF16(
- IDS_SETTINGS_ABOUT_PAGE_END_OF_LIFE_MESSAGE,
- base::TimeFormatMonthAndYear(eol_info.eol_date)));
+ int eol_string_id = eol_info.eol_date <= base::Time::Now()
+ ? IDS_SETTINGS_ABOUT_PAGE_END_OF_LIFE_MESSAGE_PAST
+ : IDS_SETTINGS_ABOUT_PAGE_END_OF_LIFE_MESSAGE_FUTURE;
+ response.SetStringKey(
+ "aboutPageEndOfLifeMessage",
+ l10n_util::GetStringFUTF16(
+ eol_string_id, base::TimeFormatMonthAndYear(eol_info.eol_date),
+ base::ASCIIToUTF16(chrome::kEolNotificationURL)));
} else {
response.SetBoolKey("hasEndOfLife", false);
response.SetStringKey("aboutPageEndOfLifeMessage", "");
@@ -765,12 +821,11 @@ void AboutHandler::OnRegulatoryLabelDirFound(
return;
}
- base::PostTaskAndReplyWithResult(
- FROM_HERE,
- {base::ThreadPool(), base::MayBlock(), base::TaskPriority::USER_VISIBLE},
- base::Bind(&ReadRegulatoryLabelText, label_dir_path),
- base::Bind(&AboutHandler::OnRegulatoryLabelTextRead,
- weak_factory_.GetWeakPtr(), callback_id, label_dir_path));
+ base::ThreadPool::PostTaskAndReplyWithResult(
+ FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE},
+ base::BindOnce(&ReadRegulatoryLabelText, label_dir_path),
+ base::BindOnce(&AboutHandler::OnRegulatoryLabelTextRead,
+ weak_factory_.GetWeakPtr(), callback_id, label_dir_path));
}
void AboutHandler::OnRegulatoryLabelTextRead(
diff --git a/chromium/chrome/browser/ui/webui/settings/about_handler.h b/chromium/chrome/browser/ui/webui/settings/about_handler.h
index 679bad2fa37..e69de9f2d82 100644
--- a/chromium/chrome/browser/ui/webui/settings/about_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/about_handler.h
@@ -25,6 +25,7 @@
#endif // defined(OS_CHROMEOS)
namespace base {
+class DictionaryValue;
class FilePath;
class ListValue;
}
@@ -99,8 +100,18 @@ class AboutHandler : public settings::SettingsPageUIHandler,
// Sets the release track version.
void HandleSetChannel(const base::ListValue* args);
- // Retrieves combined channel info.
+ // Retrieves OS, ARC and firmware versions.
+ void HandleGetVersionInfo(const base::ListValue* args);
+ void OnGetVersionInfoReady(
+ std::string callback_id,
+ std::unique_ptr<base::DictionaryValue> version_info);
+
+ // Retrieves channel info.
void HandleGetChannelInfo(const base::ListValue* args);
+
+ // Checks whether we can change the current channel.
+ void HandleCanChangeChannel(const base::ListValue* args);
+
// Callbacks for version_updater_->GetChannel calls.
void OnGetCurrentChannel(std::string callback_id,
const std::string& current_channel);
diff --git a/chromium/chrome/browser/ui/webui/settings/browser_lifetime_handler.cc b/chromium/chrome/browser/ui/webui/settings/browser_lifetime_handler.cc
index 6c11c87a3f5..8a02491acd6 100644
--- a/chromium/chrome/browser/ui/webui/settings/browser_lifetime_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/browser_lifetime_handler.cc
@@ -19,10 +19,6 @@
#include "components/user_manager/user_manager.h"
#endif // defined(OS_CHROMEOS)
-#if defined(OS_MACOSX)
-#include "chrome/browser/first_run/upgrade_util_mac.h"
-#endif
-
namespace settings {
namespace {
@@ -86,11 +82,6 @@ void BrowserLifetimeHandler::HandleRestart(
void BrowserLifetimeHandler::HandleRelaunch(
const base::ListValue* args) {
-#if defined(OS_MACOSX)
- if (!upgrade_util::ShouldContinueToRelaunchForUpgrade())
- return;
-#endif // OS_MACOSX
-
chrome::AttemptRelaunch();
}
diff --git a/chromium/chrome/browser/ui/webui/settings/change_password_handler.cc b/chromium/chrome/browser/ui/webui/settings/change_password_handler.cc
deleted file mode 100644
index b34815f9c76..00000000000
--- a/chromium/chrome/browser/ui/webui/settings/change_password_handler.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-// 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 "chrome/browser/ui/webui/settings/change_password_handler.h"
-
-#include "base/bind.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/safe_browsing/chrome_password_protection_service.h"
-#include "components/prefs/pref_service.h"
-#include "components/safe_browsing/password_protection/metrics_util.h"
-#include "components/safe_browsing/proto/csd.pb.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_ui.h"
-
-namespace settings {
-
-using password_manager::metrics_util::PasswordType;
-using safe_browsing::ChromePasswordProtectionService;
-using safe_browsing::LoginReputationClientResponse;
-using safe_browsing::RequestOutcome;
-
-ChangePasswordHandler::ChangePasswordHandler(
- Profile* profile,
- safe_browsing::ChromePasswordProtectionService* service)
- : profile_(profile), service_(service) {
- DCHECK(service_);
-}
-
-ChangePasswordHandler::~ChangePasswordHandler() {}
-
-void ChangePasswordHandler::RegisterMessages() {
- web_ui()->RegisterMessageCallback(
- "initializeChangePasswordHandler",
- base::BindRepeating(&ChangePasswordHandler::HandleInitialize,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback(
- "changePassword",
- base::BindRepeating(&ChangePasswordHandler::HandleChangePassword,
- base::Unretained(this)));
-}
-
-void ChangePasswordHandler::OnJavascriptAllowed() {
- pref_registrar_.Init(profile_->GetPrefs());
- pref_registrar_.Add(
- prefs::kSafeBrowsingUnhandledGaiaPasswordReuses,
- base::Bind(&ChangePasswordHandler::UpdateChangePasswordCardVisibility,
- base::Unretained(this)));
-}
-
-void ChangePasswordHandler::OnJavascriptDisallowed() {
- pref_registrar_.RemoveAll();
-}
-
-void ChangePasswordHandler::HandleInitialize(const base::ListValue* args) {
- AllowJavascript();
- UpdateChangePasswordCardVisibility();
-}
-
-void ChangePasswordHandler::HandleChangePassword(const base::ListValue* args) {
- service_->OnUserAction(
- web_ui()->GetWebContents(),
- service_->reused_password_account_type_for_last_shown_warning(),
- RequestOutcome::UNKNOWN,
- LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, "unused_token",
- safe_browsing::WarningUIType::CHROME_SETTINGS,
- safe_browsing::WarningAction::CHANGE_PASSWORD);
-}
-
-void ChangePasswordHandler::UpdateChangePasswordCardVisibility() {
- FireWebUIListener(
- "change-password-visibility",
- base::Value(
- service_->IsWarningEnabled(
- service_
- ->reused_password_account_type_for_last_shown_warning()) &&
- safe_browsing::ChromePasswordProtectionService::
- ShouldShowChangePasswordSettingUI(profile_)));
-}
-
-} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/change_password_handler.h b/chromium/chrome/browser/ui/webui/settings/change_password_handler.h
deleted file mode 100644
index f1ea3806473..00000000000
--- a/chromium/chrome/browser/ui/webui/settings/change_password_handler.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHANGE_PASSWORD_HANDLER_H_
-#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHANGE_PASSWORD_HANDLER_H_
-
-#include "base/macros.h"
-#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
-#include "components/prefs/pref_change_registrar.h"
-
-class Profile;
-
-namespace safe_browsing {
-class ChromePasswordProtectionService;
-}
-
-namespace settings {
-
-// Chrome "Change Password" settings page UI handler.
-class ChangePasswordHandler : public SettingsPageUIHandler {
- public:
- explicit ChangePasswordHandler(
- Profile* profile,
- safe_browsing::ChromePasswordProtectionService* service);
- ~ChangePasswordHandler() override;
-
- // settings::SettingsPageUIHandler:
- void RegisterMessages() override;
- void OnJavascriptAllowed() override;
- void OnJavascriptDisallowed() override;
-
- private:
- void HandleInitialize(const base::ListValue* args);
-
- void HandleChangePassword(const base::ListValue* args);
-
- void UpdateChangePasswordCardVisibility();
-
- Profile* profile_;
-
- PrefChangeRegistrar pref_registrar_;
-
- safe_browsing::ChromePasswordProtectionService* service_;
-
- DISALLOW_COPY_AND_ASSIGN(ChangePasswordHandler);
-};
-
-} // namespace settings
-
-#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHANGE_PASSWORD_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/DEPS b/chromium/chrome/browser/ui/webui/settings/chromeos/DEPS
new file mode 100644
index 00000000000..eb3c6b1fa0c
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+ "+chrome/services/local_search_service",
+ "+device/udev_linux/fake_udev_loader.h", # For keyboard unit test.
+]
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/OWNERS b/chromium/chrome/browser/ui/webui/settings/chromeos/OWNERS
index f42990c5d35..ff0d48d0403 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/OWNERS
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/OWNERS
@@ -1,3 +1,5 @@
+file://chrome/browser/resources/settings/chromeos/OWNERS
+
per-file multidevice_handler*=file://chromeos/components/multidevice/OWNERS
-# COMPONENT: UI>Settings
+# COMPONENT: OS>Systems>Settings
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc
index 34dbb5b6fac..e1d62743ff2 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc
@@ -4,8 +4,10 @@
#include "chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h"
+#include "ash/public/cpp/tablet_mode.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/metrics/histogram_functions.h"
#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/profiles/profile.h"
@@ -18,11 +20,24 @@
namespace chromeos {
namespace settings {
-AccessibilityHandler::AccessibilityHandler(content::WebUI* webui)
- : profile_(Profile::FromWebUI(webui)) {
+namespace {
+
+void RecordShowShelfNavigationButtonsValueChange(bool enabled) {
+ base::UmaHistogramBoolean(
+ "Accessibility.CrosShelfNavigationButtonsInTabletModeChanged."
+ "OsSettings",
+ enabled);
}
-AccessibilityHandler::~AccessibilityHandler() {}
+} // namespace
+
+AccessibilityHandler::AccessibilityHandler(Profile* profile)
+ : profile_(profile) {}
+
+AccessibilityHandler::~AccessibilityHandler() {
+ if (a11y_nav_buttons_toggle_metrics_reporter_timer_.IsRunning())
+ a11y_nav_buttons_toggle_metrics_reporter_timer_.FireNow();
+}
void AccessibilityHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(
@@ -35,13 +50,21 @@ void AccessibilityHandler::RegisterMessages() {
&AccessibilityHandler::HandleShowSelectToSpeakSettings,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
- "getStartupSoundEnabled",
- base::BindRepeating(&AccessibilityHandler::HandleGetStartupSoundEnabled,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback(
"setStartupSoundEnabled",
base::BindRepeating(&AccessibilityHandler::HandleSetStartupSoundEnabled,
base::Unretained(this)));
+
+ web_ui()->RegisterMessageCallback(
+ "recordSelectedShowShelfNavigationButtonValue",
+ base::BindRepeating(
+ &AccessibilityHandler::
+ HandleRecordSelectedShowShelfNavigationButtonsValue,
+ base::Unretained(this)));
+
+ web_ui()->RegisterMessageCallback(
+ "manageA11yPageReady",
+ base::BindRepeating(&AccessibilityHandler::HandleManageA11yPageReady,
+ base::Unretained(this)));
}
void AccessibilityHandler::HandleShowChromeVoxSettings(
@@ -54,20 +77,54 @@ void AccessibilityHandler::HandleShowSelectToSpeakSettings(
OpenExtensionOptionsPage(extension_misc::kSelectToSpeakExtensionId);
}
-void AccessibilityHandler::HandleGetStartupSoundEnabled(
+void AccessibilityHandler::HandleSetStartupSoundEnabled(
const base::ListValue* args) {
- AllowJavascript();
- FireWebUIListener(
- "startup-sound-enabled-updated",
- base::Value(AccessibilityManager::Get()->GetStartupSoundEnabled()));
+ DCHECK_EQ(1U, args->GetSize());
+ bool enabled;
+ args->GetBoolean(0, &enabled);
+ AccessibilityManager::Get()->SetStartupSoundEnabled(enabled);
}
-void AccessibilityHandler::HandleSetStartupSoundEnabled(
+void AccessibilityHandler::HandleRecordSelectedShowShelfNavigationButtonsValue(
const base::ListValue* args) {
DCHECK_EQ(1U, args->GetSize());
bool enabled;
args->GetBoolean(0, &enabled);
- AccessibilityManager::Get()->SetStartupSoundEnabled(enabled);
+
+ a11y_nav_buttons_toggle_metrics_reporter_timer_.Start(
+ FROM_HERE, base::TimeDelta::FromSeconds(10),
+ base::BindOnce(&RecordShowShelfNavigationButtonsValueChange, enabled));
+}
+
+void AccessibilityHandler::HandleManageA11yPageReady(
+ const base::ListValue* args) {
+ AllowJavascript();
+
+ // When tablet mode is active we can return early since tablet mode
+ // is supported.
+ if (ash::TabletMode::Get()->InTabletMode()) {
+ FireWebUIListener(
+ "initial-data-ready",
+ base::Value(AccessibilityManager::Get()->GetStartupSoundEnabled()),
+ base::Value(true /* tablet_mode_supported */));
+ return;
+ }
+
+ PowerManagerClient::Get()->GetSwitchStates(
+ base::BindOnce(&AccessibilityHandler::OnReceivedSwitchStates,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void AccessibilityHandler::OnReceivedSwitchStates(
+ base::Optional<PowerManagerClient::SwitchStates> switch_states) {
+ bool tablet_mode_supported =
+ switch_states.has_value() &&
+ switch_states->tablet_mode != PowerManagerClient::TabletMode::UNSUPPORTED;
+
+ FireWebUIListener(
+ "initial-data-ready",
+ base::Value(AccessibilityManager::Get()->GetStartupSoundEnabled()),
+ base::Value(tablet_mode_supported));
}
void AccessibilityHandler::OpenExtensionOptionsPage(const char extension_id[]) {
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h
index 80d735832cb..54290f81dd8 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h
@@ -6,16 +6,14 @@
#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_ACCESSIBILITY_HANDLER_H_
#include "base/macros.h"
+#include "base/timer/timer.h"
#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+#include "chromeos/dbus/power/power_manager_client.h"
namespace base {
class ListValue;
}
-namespace content {
-class WebUI;
-}
-
class Profile;
namespace chromeos {
@@ -23,7 +21,7 @@ namespace settings {
class AccessibilityHandler : public ::settings::SettingsPageUIHandler {
public:
- explicit AccessibilityHandler(content::WebUI* webui);
+ explicit AccessibilityHandler(Profile* profile);
~AccessibilityHandler() override;
// SettingsPageUIHandler implementation.
@@ -31,18 +29,36 @@ class AccessibilityHandler : public ::settings::SettingsPageUIHandler {
void OnJavascriptAllowed() override {}
void OnJavascriptDisallowed() override {}
+ // Callback which updates if startup sound is enabled and if tablet
+ // mode is supported. Visible for testing.
+ void HandleManageA11yPageReady(const base::ListValue* args);
+
private:
// Callback for the messages to show settings for ChromeVox or
// Select To Speak.
void HandleShowChromeVoxSettings(const base::ListValue* args);
void HandleShowSelectToSpeakSettings(const base::ListValue* args);
- void HandleGetStartupSoundEnabled(const base::ListValue* args);
void HandleSetStartupSoundEnabled(const base::ListValue* args);
+ void HandleRecordSelectedShowShelfNavigationButtonsValue(
+ const base::ListValue* args);
+
+ // Callback which updates visibility for the shelf navigation buttons
+ // accessibility setting, depending on whether tablet mode is supported.
+ void OnReceivedSwitchStates(
+ base::Optional<chromeos::PowerManagerClient::SwitchStates> switch_states);
void OpenExtensionOptionsPage(const char extension_id[]);
Profile* profile_; // Weak pointer.
+ // Timer to record user changed value for the accessibility setting to turn
+ // shelf navigation buttons on in tablet mode. The metric is recorded with 10
+ // second delay to avoid overreporting when the user keeps toggling the
+ // setting value in the screen UI.
+ base::OneShotTimer a11y_nav_buttons_toggle_metrics_reporter_timer_;
+
+ base::WeakPtrFactory<AccessibilityHandler> weak_ptr_factory_{this};
+
DISALLOW_COPY_AND_ASSIGN(AccessibilityHandler);
};
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler_unittest.cc
new file mode 100644
index 00000000000..8ee78caacd8
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler_unittest.cc
@@ -0,0 +1,103 @@
+// Copyright 2020 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 "chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h"
+
+#include <memory>
+
+#include "ash/public/cpp/test/test_tablet_mode.h"
+#include "chrome/test/base/chrome_render_view_host_test_harness.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chromeos/dbus/power/fake_power_manager_client.h"
+#include "content/public/test/test_web_ui.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+namespace settings {
+
+class TestingAccessibilityHandler : public AccessibilityHandler {
+ public:
+ explicit TestingAccessibilityHandler(content::WebUI* web_ui)
+ : AccessibilityHandler(/* profile */ nullptr) {
+ set_web_ui(web_ui);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestingAccessibilityHandler);
+};
+
+class AccessibilityHandlerTest : public ChromeRenderViewHostTestHarness {
+ public:
+ AccessibilityHandlerTest() = default;
+ AccessibilityHandlerTest(const AccessibilityHandlerTest&) = delete;
+ AccessibilityHandlerTest& operator=(const AccessibilityHandlerTest&) = delete;
+
+ void SetUp() override {
+ ChromeRenderViewHostTestHarness::SetUp();
+ PowerManagerClient::InitializeFake();
+ test_tablet_mode_ = std::make_unique<ash::TestTabletMode>();
+ handler_ = std::make_unique<TestingAccessibilityHandler>(&web_ui_);
+ }
+
+ void TearDown() override {
+ handler_.reset();
+ test_tablet_mode_.reset();
+ PowerManagerClient::Shutdown();
+ ChromeRenderViewHostTestHarness::TearDown();
+ }
+
+ content::TestWebUI web_ui_;
+ std::unique_ptr<ash::TestTabletMode> test_tablet_mode_;
+ std::unique_ptr<TestingAccessibilityHandler> handler_;
+};
+
+// Test that when tablet mode is supported, the correct data is returned by
+// HandleManageA11yPageReady().
+TEST_F(AccessibilityHandlerTest, ManageA11yPageReadyTabletModeSupported) {
+ // Set tablet mode as supported.
+ chromeos::FakePowerManagerClient::Get()->SetTabletMode(
+ chromeos::PowerManagerClient::TabletMode::OFF, base::TimeTicks());
+
+ handler_->HandleManageA11yPageReady(/* args */ nullptr);
+
+ // Wait for the AccessibilityHandler to receive data from PowerManagerClient.
+ base::RunLoop().RunUntilIdle();
+
+ const content::TestWebUI::CallData& call_data = *web_ui_.call_data().back();
+
+ // Ensure tablet mode is returned as supported.
+ EXPECT_TRUE(call_data.arg3()->GetBool());
+}
+
+// Test that when tablet mode is unsupported, the correct data is returned by
+// HandleManageA11yPageReady().
+TEST_F(AccessibilityHandlerTest, ManageA11yPageReadyTabletModeUnsupported) {
+ // Set tablet mode as unsupported.
+ chromeos::FakePowerManagerClient::Get()->SetTabletMode(
+ chromeos::PowerManagerClient::TabletMode::UNSUPPORTED, base::TimeTicks());
+ handler_->HandleManageA11yPageReady(/* args */ nullptr);
+
+ // Wait for the AccessibilityHandler to receive data from PowerManagerClient.
+ base::RunLoop().RunUntilIdle();
+
+ const content::TestWebUI::CallData& call_data = *web_ui_.call_data().back();
+
+ // Ensure tablet mode is returned as unsupported.
+ EXPECT_FALSE(call_data.arg3()->GetBool());
+}
+
+// Test that when tablet mode is enabled, the correct data is returned by
+// HandleManageA11yPageReady().
+TEST_F(AccessibilityHandlerTest, ManageA11yPageReadyTabletModeEnabled) {
+ test_tablet_mode_->SetEnabledForTest(true);
+ handler_->HandleManageA11yPageReady(/* args */ nullptr);
+
+ const content::TestWebUI::CallData& call_data = *web_ui_.call_data().back();
+
+ // Ensure tablet mode is returned as supported.
+ EXPECT_TRUE(call_data.arg3()->GetBool());
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc
index a8b296703d0..e6d80c5a757 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc
@@ -23,6 +23,7 @@
#include "chrome/browser/ui/webui/signin/inline_login_handler_dialog_chromeos.h"
#include "chrome/grit/generated_resources.h"
#include "chromeos/components/account_manager/account_manager_factory.h"
+#include "components/signin/public/identity_manager/consent_level.h"
#include "components/user_manager/user.h"
#include "google_apis/gaia/gaia_auth_util.h"
#include "google_apis/gaia/google_service_auth_error.h"
@@ -273,12 +274,13 @@ void AccountManagerUIHandler::OnGetAccounts(
GetEnterpriseDomainFromUsername(user->GetDisplayEmail()));
} else if (profile_->GetProfilePolicyConnector()->IsManaged()) {
device_account.SetOrganization(GetEnterpriseDomainFromUsername(
- identity_manager_->GetPrimaryAccountInfo().email));
+ identity_manager_
+ ->GetPrimaryAccountInfo(signin::ConsentLevel::kNotRequired)
+ .email));
}
// Device account must show up at the top.
- accounts.GetList().insert(accounts.GetList().begin(),
- device_account.Build());
+ accounts.Insert(accounts.GetList().begin(), device_account.Build());
}
ResolveJavascriptCallback(callback_id, accounts);
@@ -418,17 +420,26 @@ void AccountManagerUIHandler::OnAccountRemoved(
RefreshUI();
}
-// |signin::IdentityManager::Observer| overrides. For newly added accounts,
-// |signin::IdentityManager| may take some time to fetch user's full name and
-// account image. Whenever that is completed, we may need to update the UI with
-// this new set of information. Note that we may be listening to
-// |signin::IdentityManager| but we still consider |AccountManager| to be the
-// source of truth for account list.
+// |signin::IdentityManager::Observer| overrides.
+//
+// For newly added accounts, |signin::IdentityManager| may take some time to
+// fetch user's full name and account image. Whenever that is completed, we may
+// need to update the UI with this new set of information. Note that we may be
+// listening to |signin::IdentityManager| but we still consider |AccountManager|
+// to be the source of truth for account list.
void AccountManagerUIHandler::OnExtendedAccountInfoUpdated(
const AccountInfo& info) {
RefreshUI();
}
+void AccountManagerUIHandler::OnErrorStateOfRefreshTokenUpdatedForAccount(
+ const CoreAccountInfo& account_info,
+ const GoogleServiceAuthError& error) {
+ if (error.state() != GoogleServiceAuthError::NONE) {
+ RefreshUI();
+ }
+}
+
void AccountManagerUIHandler::RefreshUI() {
FireWebUIListener("accounts-changed");
}
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.h
index 39f24fbbbec..21e8adf1bc8 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.h
@@ -44,6 +44,9 @@ class AccountManagerUIHandler : public ::settings::SettingsPageUIHandler,
// |signin::IdentityManager::Observer| overrides.
void OnExtendedAccountInfoUpdated(const AccountInfo& info) override;
+ void OnErrorStateOfRefreshTokenUpdatedForAccount(
+ const CoreAccountInfo& account_info,
+ const GoogleServiceAuthError& error) override;
private:
friend class AccountManagerUIHandlerTest;
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.cc
new file mode 100644
index 00000000000..e3c7e6d7645
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.cc
@@ -0,0 +1,32 @@
+// Copyright 2020 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 "chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.h"
+
+#include "base/bind.h"
+#include "base/values.h"
+
+namespace chromeos {
+namespace settings {
+
+AmbientModeHandler::AmbientModeHandler() = default;
+
+AmbientModeHandler::~AmbientModeHandler() = default;
+
+void AmbientModeHandler::RegisterMessages() {
+ web_ui()->RegisterMessageCallback(
+ "onAmbientModePageReady",
+ base::BindRepeating(&AmbientModeHandler::HandleInitialized,
+ base::Unretained(this)));
+}
+
+void AmbientModeHandler::HandleInitialized(const base::ListValue* args) {
+ CHECK(args);
+ CHECK(args->empty());
+
+ AllowJavascript();
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.h
new file mode 100644
index 00000000000..a52b109160a
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.h
@@ -0,0 +1,39 @@
+// Copyright 2020 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 CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_AMBIENT_MODE_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_AMBIENT_MODE_HANDLER_H_
+
+#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+
+namespace base {
+class ListValue;
+} // namespace base
+
+namespace chromeos {
+namespace settings {
+
+// Chrome OS ambient mode settings page UI handler, to allow users to customize
+// photo frame and other related functionalities.
+class AmbientModeHandler : public ::settings::SettingsPageUIHandler {
+ public:
+ AmbientModeHandler();
+ AmbientModeHandler(const AmbientModeHandler&) = delete;
+ AmbientModeHandler& operator=(const AmbientModeHandler&) = delete;
+ ~AmbientModeHandler() override;
+
+ // settings::SettingsPageUIHandler:
+ void RegisterMessages() override;
+ void OnJavascriptAllowed() override {}
+ void OnJavascriptDisallowed() override {}
+
+ private:
+ // WebUI call to signal js side is ready.
+ void HandleInitialized(const base::ListValue* args);
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_AMBIENT_MODE_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.cc
new file mode 100644
index 00000000000..c9cfb838ce3
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.cc
@@ -0,0 +1,393 @@
+// Copyright 2020 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 "chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.h"
+
+#include <numeric>
+
+#include "base/system/sys_info.h"
+#include "base/task/post_task.h"
+#include "base/task/thread_pool.h"
+#include "base/values.h"
+#include "chrome/browser/browsing_data/browsing_data_appcache_helper.h"
+#include "chrome/browser/browsing_data/browsing_data_cache_storage_helper.h"
+#include "chrome/browser/browsing_data/browsing_data_cookie_helper.h"
+#include "chrome/browser/browsing_data/browsing_data_database_helper.h"
+#include "chrome/browser/browsing_data/browsing_data_file_system_helper.h"
+#include "chrome/browser/browsing_data/browsing_data_flash_lso_helper.h"
+#include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h"
+#include "chrome/browser/browsing_data/browsing_data_service_worker_helper.h"
+#include "chrome/browser/chromeos/crostini/crostini_features.h"
+#include "chrome/browser/chromeos/file_manager/path_util.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chromeos/cryptohome/cryptohome_util.h"
+#include "chromeos/dbus/cryptohome/cryptohome_client.h"
+#include "components/arc/arc_service_manager.h"
+#include "components/arc/session/arc_bridge_service.h"
+#include "components/arc/storage_manager/arc_storage_manager.h"
+#include "components/browsing_data/content/conditional_cache_counting_helper.h"
+#include "components/browsing_data/content/local_storage_helper.h"
+#include "components/user_manager/user_manager.h"
+#include "content/public/browser/storage_partition.h"
+
+namespace chromeos {
+namespace settings {
+namespace calculator {
+
+namespace {
+
+void GetSizeStatBlocking(const base::FilePath& mount_path,
+ int64_t* total_size,
+ int64_t* available_size) {
+ int64_t size = base::SysInfo::AmountOfTotalDiskSpace(mount_path);
+ if (size >= 0)
+ *total_size = size;
+ size = base::SysInfo::AmountOfFreeDiskSpace(mount_path);
+ if (size >= 0)
+ *available_size = size;
+}
+
+} // namespace
+
+SizeCalculator::SizeCalculator(const CalculationType& calculation_type)
+ : calculation_type_(calculation_type) {}
+
+SizeCalculator::~SizeCalculator() {}
+
+void SizeCalculator::StartCalculation() {
+ if (calculating_)
+ return;
+ calculating_ = true;
+ PerformCalculation();
+}
+
+void SizeCalculator::AddObserver(SizeCalculator::Observer* observer) {
+ observers_.AddObserver(observer);
+}
+
+void SizeCalculator::RemoveObserver(SizeCalculator::Observer* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+void SizeCalculator::NotifySizeCalculated(
+ int64_t total_bytes,
+ const base::Optional<int64_t>& available_bytes) {
+ calculating_ = false;
+ for (SizeCalculator::Observer& observer : observers_) {
+ observer.OnSizeCalculated(calculation_type_, total_bytes, available_bytes);
+ }
+}
+
+SizeStatCalculator::SizeStatCalculator(Profile* profile)
+ : SizeCalculator(CalculationType::kInUse), profile_(profile) {}
+
+SizeStatCalculator::~SizeStatCalculator() = default;
+void SizeStatCalculator::PerformCalculation() {
+ const base::FilePath my_files_path =
+ file_manager::util::GetMyFilesFolderForProfile(profile_);
+
+ int64_t* total_size = new int64_t(0);
+ int64_t* available_size = new int64_t(0);
+ base::ThreadPool::PostTaskAndReply(
+ FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE},
+ base::Bind(&GetSizeStatBlocking, my_files_path, total_size,
+ available_size),
+ base::Bind(&SizeStatCalculator::OnGetSizeStat,
+ weak_ptr_factory_.GetWeakPtr(), base::Owned(total_size),
+ base::Owned(available_size)));
+}
+
+void SizeStatCalculator::OnGetSizeStat(int64_t* total_bytes,
+ int64_t* available_bytes) {
+ NotifySizeCalculated(*total_bytes, *available_bytes);
+}
+
+MyFilesSizeCalculator::MyFilesSizeCalculator(Profile* profile)
+ : SizeCalculator(CalculationType::kMyFiles), profile_(profile) {}
+
+MyFilesSizeCalculator::~MyFilesSizeCalculator() = default;
+
+void MyFilesSizeCalculator::PerformCalculation() {
+ const base::FilePath my_files_path =
+ file_manager::util::GetMyFilesFolderForProfile(profile_);
+
+ const base::FilePath android_files_path =
+ base::FilePath(file_manager::util::GetAndroidFilesPath());
+
+ base::ThreadPool::PostTaskAndReplyWithResult(
+ FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
+ base::BindOnce(&MyFilesSizeCalculator::ComputeLocalFilesSize,
+ base::Unretained(this), my_files_path, android_files_path),
+ base::BindOnce(&MyFilesSizeCalculator::OnGetMyFilesSize,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+int64_t MyFilesSizeCalculator::ComputeLocalFilesSize(
+ const base::FilePath& my_files_path,
+ const base::FilePath& android_files_path) {
+ int64_t size = 0;
+
+ // Compute directory size of My Files.
+ size += base::ComputeDirectorySize(my_files_path);
+
+ // Compute directory size of Play Files.
+ size += base::ComputeDirectorySize(android_files_path);
+
+ // Remove size of Download. If Android is enabled, the size of the Download
+ // folder is counted in both My Files and Play files. If Android is disabled,
+ // the Download folder doesn't exist and the returned size is 0.
+ const base::FilePath download_files_path =
+ android_files_path.AppendASCII("Download");
+ size -= base::ComputeDirectorySize(download_files_path);
+
+ return size;
+}
+
+void MyFilesSizeCalculator::OnGetMyFilesSize(int64_t total_bytes) {
+ NotifySizeCalculated(total_bytes);
+}
+
+BrowsingDataSizeCalculator::BrowsingDataSizeCalculator(Profile* profile)
+ : SizeCalculator(CalculationType::kBrowsingData), profile_(profile) {}
+
+BrowsingDataSizeCalculator::~BrowsingDataSizeCalculator() = default;
+
+void BrowsingDataSizeCalculator::PerformCalculation() {
+ has_browser_cache_size_ = false;
+ has_browser_site_data_size_ = false;
+
+ // Fetch the size of http cache in browsing data.
+ browsing_data::ConditionalCacheCountingHelper::Count(
+ content::BrowserContext::GetDefaultStoragePartition(profile_),
+ base::Time(), base::Time::Max(),
+ base::BindOnce(&BrowsingDataSizeCalculator::OnGetCacheSize,
+ weak_ptr_factory_.GetWeakPtr()));
+
+ // Fetch the size of site data in browsing data.
+ if (!site_data_size_collector_.get()) {
+ content::StoragePartition* storage_partition =
+ content::BrowserContext::GetDefaultStoragePartition(profile_);
+ site_data_size_collector_ = std::make_unique<SiteDataSizeCollector>(
+ storage_partition->GetPath(),
+ new BrowsingDataCookieHelper(storage_partition),
+ new BrowsingDataDatabaseHelper(profile_),
+ new browsing_data::LocalStorageHelper(profile_),
+ new BrowsingDataAppCacheHelper(storage_partition->GetAppCacheService()),
+ new BrowsingDataIndexedDBHelper(storage_partition),
+ BrowsingDataFileSystemHelper::Create(
+ storage_partition->GetFileSystemContext()),
+ new BrowsingDataServiceWorkerHelper(
+ storage_partition->GetServiceWorkerContext()),
+ new BrowsingDataCacheStorageHelper(
+ storage_partition->GetCacheStorageContext()),
+ BrowsingDataFlashLSOHelper::Create(profile_));
+ }
+ site_data_size_collector_->Fetch(
+ base::Bind(&BrowsingDataSizeCalculator::OnGetBrowsingDataSize,
+ weak_ptr_factory_.GetWeakPtr(), /*is_site_data=*/true));
+}
+
+void BrowsingDataSizeCalculator::OnGetCacheSize(bool is_upper_limit,
+ int64_t size) {
+ DCHECK(!is_upper_limit);
+ OnGetBrowsingDataSize(/*is_site_data=*/false, size);
+}
+
+void BrowsingDataSizeCalculator::OnGetBrowsingDataSize(bool is_site_data,
+ int64_t size) {
+ if (is_site_data) {
+ has_browser_site_data_size_ = true;
+ browser_site_data_size_ = size;
+ } else {
+ has_browser_cache_size_ = true;
+ browser_cache_size_ = size;
+ }
+ if (has_browser_cache_size_ && has_browser_site_data_size_) {
+ int64_t browsing_data_size;
+ if (browser_cache_size_ >= 0 && browser_site_data_size_ >= 0) {
+ browsing_data_size = browser_site_data_size_ + browser_cache_size_;
+ } else {
+ browsing_data_size = -1;
+ }
+ calculating_ = false;
+ NotifySizeCalculated(browsing_data_size);
+ }
+}
+
+AppsSizeCalculator::AppsSizeCalculator(Profile* profile)
+ : SizeCalculator(CalculationType::kAppsExtensions), profile_(profile) {}
+
+AppsSizeCalculator::~AppsSizeCalculator() {
+ arc::ArcServiceManager::Get()
+ ->arc_bridge_service()
+ ->storage_manager()
+ ->RemoveObserver(this);
+}
+
+void AppsSizeCalculator::OnConnectionReady() {
+ is_android_running_ = true;
+ StartCalculation();
+}
+
+void AppsSizeCalculator::OnConnectionClosed() {
+ is_android_running_ = false;
+}
+
+void AppsSizeCalculator::AddObserver(SizeCalculator::Observer* observer) {
+ // Start observing arc mojo connection when the first observer is added, to
+ // allow the calculation of android apps.
+ if (!observers_.might_have_observers()) {
+ arc::ArcServiceManager::Get()
+ ->arc_bridge_service()
+ ->storage_manager()
+ ->AddObserver(this);
+ }
+ observers_.AddObserver(observer);
+}
+
+void AppsSizeCalculator::RemoveObserver(SizeCalculator::Observer* observer) {
+ observers_.RemoveObserver(observer);
+ // Stop observing arc connection if all observers have been removed.
+ if (!observers_.might_have_observers()) {
+ arc::ArcServiceManager::Get()
+ ->arc_bridge_service()
+ ->storage_manager()
+ ->RemoveObserver(this);
+ }
+}
+
+void AppsSizeCalculator::PerformCalculation() {
+ apps_extensions_size_ = 0;
+ has_apps_extensions_size_ = false;
+ android_apps_size_ = 0;
+ has_android_apps_size_ = false;
+
+ UpdateAppsSize();
+ UpdateAndroidAppsSize();
+}
+
+void AppsSizeCalculator::UpdateAppsSize() {
+ // Apps and extensions installed from the web store located in
+ // [user-hash]/Extensions.
+ const base::FilePath extensions_path =
+ profile_->GetPath().AppendASCII("Extensions");
+
+ base::ThreadPool::PostTaskAndReplyWithResult(
+ FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
+ base::BindOnce(&base::ComputeDirectorySize, extensions_path),
+ base::BindOnce(&AppsSizeCalculator::OnGetAppsSize,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void AppsSizeCalculator::OnGetAppsSize(int64_t total_bytes) {
+ apps_extensions_size_ = total_bytes;
+ has_apps_extensions_size_ = true;
+ UpdateAppsAndExtensionsSize();
+}
+
+void AppsSizeCalculator::UpdateAndroidAppsSize() {
+ if (!is_android_running_) {
+ has_android_apps_size_ = true;
+ UpdateAppsAndExtensionsSize();
+ return;
+ }
+
+ bool success = false;
+ auto* arc_storage_manager =
+ arc::ArcStorageManager::GetForBrowserContext(profile_);
+ if (arc_storage_manager) {
+ success = arc_storage_manager->GetApplicationsSize(
+ base::BindOnce(&AppsSizeCalculator::OnGetAndroidAppsSize,
+ weak_ptr_factory_.GetWeakPtr()));
+ }
+ if (!success) {
+ has_android_apps_size_ = true;
+ UpdateAppsAndExtensionsSize();
+ }
+}
+
+void AppsSizeCalculator::OnGetAndroidAppsSize(
+ bool succeeded,
+ arc::mojom::ApplicationsSizePtr size) {
+ has_android_apps_size_ = true;
+ if (succeeded) {
+ android_apps_size_ = size->total_code_bytes + size->total_data_bytes +
+ size->total_cache_bytes;
+ }
+ UpdateAppsAndExtensionsSize();
+}
+
+void AppsSizeCalculator::UpdateAppsAndExtensionsSize() {
+ if (has_apps_extensions_size_ && has_android_apps_size_) {
+ calculating_ = false;
+ NotifySizeCalculated(apps_extensions_size_ + android_apps_size_);
+ }
+}
+
+CrostiniSizeCalculator::CrostiniSizeCalculator(Profile* profile)
+ : SizeCalculator(CalculationType::kCrostini), profile_(profile) {}
+
+CrostiniSizeCalculator::~CrostiniSizeCalculator() = default;
+
+void CrostiniSizeCalculator::PerformCalculation() {
+ if (!crostini::CrostiniFeatures::Get()->IsEnabled(profile_)) {
+ NotifySizeCalculated(0);
+ return;
+ }
+
+ crostini::CrostiniManager::GetForProfile(profile_)->ListVmDisks(
+ base::BindOnce(&CrostiniSizeCalculator::OnGetCrostiniSize,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void CrostiniSizeCalculator::OnGetCrostiniSize(crostini::CrostiniResult result,
+ int64_t total_bytes) {
+ calculating_ = false;
+ NotifySizeCalculated(total_bytes);
+}
+
+OtherUsersSizeCalculator::OtherUsersSizeCalculator()
+ : SizeCalculator(CalculationType::kOtherUsers) {}
+
+OtherUsersSizeCalculator::~OtherUsersSizeCalculator() = default;
+
+void OtherUsersSizeCalculator::PerformCalculation() {
+ other_users_.clear();
+ user_sizes_.clear();
+ const user_manager::UserList& users =
+ user_manager::UserManager::Get()->GetUsers();
+ for (auto* user : users) {
+ if (user->is_active())
+ continue;
+ other_users_.push_back(user);
+ CryptohomeClient::Get()->GetAccountDiskUsage(
+ cryptohome::CreateAccountIdentifierFromAccountId(user->GetAccountId()),
+ base::BindOnce(&OtherUsersSizeCalculator::OnGetOtherUserSize,
+ weak_ptr_factory_.GetWeakPtr()));
+ }
+ // We should show "0 B" if there is no other user.
+ if (other_users_.empty()) {
+ NotifySizeCalculated(0);
+ }
+}
+
+void OtherUsersSizeCalculator::OnGetOtherUserSize(
+ base::Optional<cryptohome::BaseReply> reply) {
+ user_sizes_.push_back(cryptohome::AccountDiskUsageReplyToUsageSize(reply));
+ if (user_sizes_.size() != other_users_.size())
+ return;
+ int64_t other_users_total_bytes;
+ // If all the requests succeed, shows the total bytes in the UI.
+ if (std::count(user_sizes_.begin(), user_sizes_.end(), -1) == 0) {
+ other_users_total_bytes =
+ std::accumulate(user_sizes_.begin(), user_sizes_.end(), 0LL);
+ } else {
+ other_users_total_bytes = -1;
+ }
+ NotifySizeCalculated(other_users_total_bytes);
+}
+
+} // namespace calculator
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.h b/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.h
new file mode 100644
index 00000000000..8f483f50b95
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.h
@@ -0,0 +1,296 @@
+// Copyright 2020 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 CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_CALCULATOR_SIZE_CALCULATOR_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_CALCULATOR_SIZE_CALCULATOR_H_
+
+#include <array>
+#include <bitset>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/files/file_util.h"
+#include "base/memory/weak_ptr.h"
+#include "base/observer_list_types.h"
+#include "base/values.h"
+#include "chrome/browser/browsing_data/site_data_size_collector.h"
+#include "chrome/browser/chromeos/crostini/crostini_manager.h"
+#include "chromeos/dbus/cryptohome/rpc.pb.h"
+#include "components/arc/mojom/storage_manager.mojom.h"
+#include "components/arc/session/connection_observer.h"
+#include "components/arc/storage_manager/arc_storage_manager.h"
+#include "components/user_manager/user.h"
+
+class Profile;
+
+namespace chromeos {
+namespace settings {
+namespace calculator {
+
+// Base class for the calculation of a specific storage item. Instances of this
+// class rely on their observers calling StartCalculation, and are designed to
+// notify observers about the calculated sizes.
+class SizeCalculator {
+ public:
+ // Enumeration listing the items displayed on the storage page.
+ enum class CalculationType {
+ kInUse = 0,
+ kMyFiles,
+ kBrowsingData,
+ kAppsExtensions,
+ kCrostini,
+ kOtherUsers,
+ kLast = kOtherUsers,
+ kSystem,
+ };
+
+ // Implement this interface to be notified about item size callbacks.
+ class Observer : public base::CheckedObserver {
+ public:
+ virtual void OnSizeCalculated(
+ const CalculationType& item_id,
+ int64_t total_bytes,
+ const base::Optional<int64_t>& available_bytes) = 0;
+ };
+
+ // Total number of storage items.
+ static constexpr int kCalculationTypeCount =
+ static_cast<int>(CalculationType::kLast) + 1;
+
+ explicit SizeCalculator(const CalculationType& calculation_type);
+ virtual ~SizeCalculator();
+
+ // Starts the size calculation of a given storage item.
+ void StartCalculation();
+
+ // Adds an observer.
+ virtual void AddObserver(Observer* observer);
+
+ // Removes an observer.
+ virtual void RemoveObserver(Observer* observer);
+
+ protected:
+ // Performs the size calculation.
+ virtual void PerformCalculation() = 0;
+
+ // Notify the StorageHandler about the calculated storage item size
+ void NotifySizeCalculated(
+ int64_t total_bytes,
+ const base::Optional<int64_t>& available_bytes = base::nullopt);
+
+ // Item id.
+ const CalculationType calculation_type_;
+
+ // Flag indicating that fetch operations for storage size are ongoing.
+ bool calculating_ = false;
+ // Observers being notified about storage items size changes.
+ base::ObserverList<SizeCalculator::Observer> observers_;
+};
+
+// Class handling the interactions with the filesystem to get storage
+// statistics, using OnSizeStatCalculated to notify observers.
+class SizeStatCalculator : public SizeCalculator {
+ public:
+ explicit SizeStatCalculator(Profile* profile);
+ ~SizeStatCalculator() override;
+
+ SizeStatCalculator(const SizeStatCalculator&) = delete;
+ SizeStatCalculator& operator=(const SizeStatCalculator&) = delete;
+
+ private:
+ friend class SizeStatTestAPI;
+
+ void PerformCalculation() override;
+
+ // Updates disk space information.
+ void OnGetSizeStat(int64_t* total_bytes, int64_t* available_bytes);
+
+ Profile* profile_;
+ base::WeakPtrFactory<SizeStatCalculator> weak_ptr_factory_{this};
+};
+
+// Class handling the calculation of the size of the user's personal files: My
+// files + Android Play files.
+class MyFilesSizeCalculator : public SizeCalculator {
+ public:
+ explicit MyFilesSizeCalculator(Profile* profile);
+ ~MyFilesSizeCalculator() override;
+
+ MyFilesSizeCalculator(const MyFilesSizeCalculator&) = delete;
+ MyFilesSizeCalculator& operator=(const MyFilesSizeCalculator&) = delete;
+
+ private:
+ friend class MyFilesSizeTestAPI;
+
+ void PerformCalculation() override;
+
+ // Computes the size of My Files and Play files.
+ int64_t ComputeLocalFilesSize(const base::FilePath& my_files_path,
+ const base::FilePath& android_files_path);
+
+ // Updates the size of My Files and Play files.
+ void OnGetMyFilesSize(int64_t total_bytes);
+
+ Profile* profile_;
+ base::WeakPtrFactory<MyFilesSizeCalculator> weak_ptr_factory_{this};
+};
+
+// Class handling the calculation of browsing data and cache.
+class BrowsingDataSizeCalculator : public SizeCalculator {
+ public:
+ explicit BrowsingDataSizeCalculator(Profile* profile);
+ ~BrowsingDataSizeCalculator() override;
+
+ BrowsingDataSizeCalculator(const BrowsingDataSizeCalculator&) = delete;
+ BrowsingDataSizeCalculator& operator=(const BrowsingDataSizeCalculator&) =
+ delete;
+
+ private:
+ friend class BrowsingDataSizeTestAPI;
+
+ void PerformCalculation() override;
+
+ // Callback to receive the cache size.
+ void OnGetCacheSize(bool is_upper_limit, int64_t size);
+
+ // Callback to update the size of browsing data.
+ void OnGetBrowsingDataSize(bool is_site_data, int64_t size);
+
+ // Total size of cache data in browsing data.
+ int64_t browser_cache_size_ = -1;
+
+ // True if we have already received the size of http cache.
+ bool has_browser_cache_size_ = false;
+
+ // Total size of site data in browsing data.
+ int64_t browser_site_data_size_ = -1;
+
+ // True if we have already received the size of http cache.
+ bool has_browser_site_data_size_ = false;
+
+ // Helper to compute the total size of all types of site date.
+ std::unique_ptr<SiteDataSizeCollector> site_data_size_collector_;
+
+ Profile* profile_;
+ base::WeakPtrFactory<BrowsingDataSizeCalculator> weak_ptr_factory_{this};
+};
+
+// Class handling the calculation of the size of the user's apps and extensions.
+class AppsSizeCalculator
+ : public SizeCalculator,
+ public arc::ConnectionObserver<arc::mojom::StorageManagerInstance> {
+ public:
+ explicit AppsSizeCalculator(Profile* profile);
+ ~AppsSizeCalculator() override;
+
+ AppsSizeCalculator(const AppsSizeCalculator&) = delete;
+ AppsSizeCalculator& operator=(const AppsSizeCalculator&) = delete;
+
+ // arc::ConnectionObserver<arc::mojom::StorageManagerInstance>:
+ void OnConnectionReady() override;
+ void OnConnectionClosed() override;
+
+ // Adds an observer. When the first observer is added, start observing the arc
+ // mojo connection UpdateAndroidAppsSize relies on.
+ void AddObserver(Observer* observer) override;
+
+ // Removes an observer. When the last observer is removed, stop observing the
+ // arc mojo connection.
+ void RemoveObserver(Observer* observer) override;
+
+ private:
+ friend class AppsSizeTestAPI;
+
+ void PerformCalculation() override;
+
+ // Requests updating the size of web store apps and extensions.
+ void UpdateAppsSize();
+
+ // Callback to update web store apps and extensions size.
+ void OnGetAppsSize(int64_t total_bytes);
+
+ // Requests updating the size of android apps.
+ void UpdateAndroidAppsSize();
+
+ // Callback to update Android apps and cache.
+ void OnGetAndroidAppsSize(bool succeeded,
+ arc::mojom::ApplicationsSizePtr size);
+
+ // Updates apps and extensions size.
+ void UpdateAppsAndExtensionsSize();
+
+ // Total size of apps and extensions
+ int64_t apps_extensions_size_ = 0;
+
+ // True if we have already received the size of apps and extensions.
+ bool has_apps_extensions_size_ = false;
+
+ // Total size of android apps
+ int64_t android_apps_size_ = 0;
+
+ // True if we have already received the size of Android apps.
+ bool has_android_apps_size_ = false;
+
+ // A flag for keeping track of the mojo connection status to the ARC
+ // container.
+ bool is_android_running_ = false;
+
+ Profile* profile_;
+ base::WeakPtrFactory<AppsSizeCalculator> weak_ptr_factory_{this};
+};
+
+// Class handling the calculation of crostini VM size.
+class CrostiniSizeCalculator : public SizeCalculator {
+ public:
+ explicit CrostiniSizeCalculator(Profile* profile);
+ ~CrostiniSizeCalculator() override;
+
+ CrostiniSizeCalculator(const CrostiniSizeCalculator&) = delete;
+ CrostiniSizeCalculator& operator=(const CrostiniSizeCalculator&) = delete;
+
+ private:
+ friend class CrostiniSizeTestAPI;
+
+ void PerformCalculation() override;
+
+ // Callback to update the size of Crostini VMs.
+ void OnGetCrostiniSize(crostini::CrostiniResult result, int64_t size);
+
+ Profile* profile_;
+ base::WeakPtrFactory<CrostiniSizeCalculator> weak_ptr_factory_{this};
+};
+
+// Class handling the calculation of other users' cryptohomes.
+class OtherUsersSizeCalculator : public SizeCalculator {
+ public:
+ OtherUsersSizeCalculator();
+ ~OtherUsersSizeCalculator() override;
+
+ OtherUsersSizeCalculator(const OtherUsersSizeCalculator&) = delete;
+ OtherUsersSizeCalculator& operator=(const OtherUsersSizeCalculator&) = delete;
+
+ private:
+ friend class OtherUsersSizeTestAPI;
+
+ void PerformCalculation() override;
+
+ // Callback to update the sizes of the other users.
+ void OnGetOtherUserSize(base::Optional<cryptohome::BaseReply> reply);
+
+ // The list of other users whose directory sizes will be accumulated as the
+ // size of "Other users".
+ user_manager::UserList other_users_;
+
+ // Fetched sizes of user directories.
+ std::vector<int64_t> user_sizes_;
+
+ base::WeakPtrFactory<OtherUsersSizeCalculator> weak_ptr_factory_{this};
+};
+
+} // namespace calculator
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_CALCULATOR_SIZE_CALCULATOR_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator_test_api.h b/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator_test_api.h
new file mode 100644
index 00000000000..2e0850df244
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator_test_api.h
@@ -0,0 +1,156 @@
+// Copyright 2020 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 CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_CALCULATOR_SIZE_CALCULATOR_TEST_API_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_CALCULATOR_SIZE_CALCULATOR_TEST_API_H_
+
+#include <utility>
+
+#include "chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.h"
+#include "chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h"
+
+namespace chromeos {
+namespace settings {
+namespace calculator {
+
+class SizeStatTestAPI {
+ public:
+ explicit SizeStatTestAPI(StorageHandler* handler,
+ SizeStatCalculator* size_stat_calculator) {
+ size_stat_calculator_ = size_stat_calculator;
+ size_stat_calculator_->AddObserver(handler);
+ }
+
+ void StartCalculation() { size_stat_calculator_->StartCalculation(); }
+
+ void SimulateOnGetSizeStat(int64_t* total_size, int64_t* available_size) {
+ size_stat_calculator_->OnGetSizeStat(total_size, available_size);
+ }
+
+ private:
+ SizeStatCalculator* size_stat_calculator_;
+};
+
+class MyFilesSizeTestAPI {
+ public:
+ explicit MyFilesSizeTestAPI(StorageHandler* handler,
+ MyFilesSizeCalculator* my_files_size_calculator) {
+ my_files_size_calculator_ = my_files_size_calculator;
+ my_files_size_calculator_->AddObserver(handler);
+ }
+
+ void StartCalculation() { my_files_size_calculator_->StartCalculation(); }
+
+ void SimulateOnGetTotalBytes(int64_t total_bytes) {
+ my_files_size_calculator_->NotifySizeCalculated(total_bytes);
+ }
+
+ private:
+ MyFilesSizeCalculator* my_files_size_calculator_;
+};
+
+class BrowsingDataSizeTestAPI {
+ public:
+ explicit BrowsingDataSizeTestAPI(
+ StorageHandler* handler,
+ BrowsingDataSizeCalculator* browsing_data_size_calculator) {
+ browsing_data_size_calculator_ = browsing_data_size_calculator;
+ browsing_data_size_calculator_->AddObserver(handler);
+ }
+
+ void StartCalculation() {
+ browsing_data_size_calculator_->StartCalculation();
+ }
+
+ void SimulateOnGetBrowsingDataSize(bool is_site_data, int64_t size) {
+ browsing_data_size_calculator_->OnGetBrowsingDataSize(is_site_data, size);
+ }
+
+ private:
+ BrowsingDataSizeCalculator* browsing_data_size_calculator_;
+};
+
+class AppsSizeTestAPI {
+ public:
+ explicit AppsSizeTestAPI(StorageHandler* handler,
+ AppsSizeCalculator* apps_size_calculator) {
+ apps_size_calculator_ = apps_size_calculator;
+ apps_size_calculator_->AddObserver(handler);
+ }
+
+ void StartCalculation() { apps_size_calculator_->StartCalculation(); }
+
+ void SimulateOnGetAppsSize(int64_t total_bytes) {
+ apps_size_calculator_->OnGetAppsSize(total_bytes);
+ }
+
+ void SimulateOnGetAndroidAppsSize(bool succeeded,
+ uint64_t total_code_bytes,
+ uint64_t total_data_bytes,
+ uint64_t total_cache_bytes) {
+ arc::mojom::ApplicationsSizePtr result(
+ ::arc::mojom::ApplicationsSize::New());
+ result->total_code_bytes = total_code_bytes;
+ result->total_data_bytes = total_data_bytes;
+ result->total_cache_bytes = total_cache_bytes;
+ apps_size_calculator_->OnGetAndroidAppsSize(succeeded, std::move(result));
+ }
+
+ private:
+ AppsSizeCalculator* apps_size_calculator_;
+};
+
+class CrostiniSizeTestAPI {
+ public:
+ explicit CrostiniSizeTestAPI(
+ StorageHandler* handler,
+ CrostiniSizeCalculator* crostini_size_calculator) {
+ crostini_size_calculator_ = crostini_size_calculator;
+ crostini_size_calculator_->AddObserver(handler);
+ }
+
+ void StartCalculation() { crostini_size_calculator_->StartCalculation(); }
+
+ void SimulateOnGetCrostiniSize(int64_t size) {
+ crostini_size_calculator_->OnGetCrostiniSize(
+ crostini::CrostiniResult::SUCCESS, size);
+ }
+
+ private:
+ CrostiniSizeCalculator* crostini_size_calculator_;
+};
+
+class OtherUsersSizeTestAPI {
+ public:
+ explicit OtherUsersSizeTestAPI(
+ StorageHandler* handler,
+ OtherUsersSizeCalculator* other_users_size_calculator) {
+ other_users_size_calculator_ = other_users_size_calculator;
+ other_users_size_calculator_->AddObserver(handler);
+ }
+
+ void StartCalculation() { other_users_size_calculator_->StartCalculation(); }
+
+ void InitializeOtherUserSize(int user_count) {
+ // When calling OnGetOtherUserSize, a callback is fired when
+ // user_sizes_.size() == other_users_.size(). We want to control the size of
+ // |other_users_|, rather than its content. This function initializes
+ // other_users_ as a list of |user_count| nullptrs.
+ other_users_size_calculator_->other_users_ =
+ user_manager::UserList(user_count);
+ }
+
+ void SimulateOnGetOtherUserSize(base::Optional<cryptohome::BaseReply> reply) {
+ other_users_size_calculator_->OnGetOtherUserSize(reply);
+ }
+
+ private:
+ OtherUsersSizeCalculator* other_users_size_calculator_;
+};
+
+} // namespace calculator
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_CALCULATOR_SIZE_CALCULATOR_TEST_API_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc
index ed3cdc8465d..4bd641f16e6 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc
@@ -18,6 +18,7 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
+#include "base/task/thread_pool.h"
#include "base/values.h"
#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
#include "chrome/browser/chromeos/camera_presence_notifier.h"
@@ -228,8 +229,8 @@ void ChangePictureHandler::SendSelectedImage() {
DCHECK(previous_image_.IsThreadSafe());
// Post a task because GetBitmapDataUrl does PNG encoding, which is
// slow for large images.
- base::PostTaskAndReplyWithResult(
- FROM_HERE, {base::ThreadPool(), base::TaskPriority::USER_BLOCKING},
+ base::ThreadPool::PostTaskAndReplyWithResult(
+ FROM_HERE, {base::TaskPriority::USER_BLOCKING},
base::BindOnce(&webui::GetBitmapDataUrl, *previous_image_.bitmap()),
base::BindOnce(&ChangePictureHandler::SendOldImage,
weak_ptr_factory_.GetWeakPtr()));
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h
index a3bb95d292e..1be240f6115 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h
@@ -9,7 +9,7 @@
#include "base/memory/weak_ptr.h"
#include "base/scoped_observer.h"
#include "chrome/browser/chromeos/camera_presence_notifier.h"
-#include "chrome/browser/image_decoder.h"
+#include "chrome/browser/image_decoder/image_decoder.h"
#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
#include "components/user_manager/user_manager.h"
#include "ui/gfx/image/image_skia.h"
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc
index 1c966904f49..1351b63b654 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc
@@ -9,21 +9,27 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/callback_forward.h"
#include "base/metrics/histogram_functions.h"
#include "chrome/browser/browser_process.h"
-#include "chrome/browser/browser_process_platform_part.h"
+#include "chrome/browser/chromeos/crostini/crostini_disk.h"
+#include "chrome/browser/chromeos/crostini/crostini_features.h"
+#include "chrome/browser/chromeos/crostini/crostini_installer.h"
+#include "chrome/browser/chromeos/crostini/crostini_port_forwarder.h"
+#include "chrome/browser/chromeos/crostini/crostini_pref_names.h"
+#include "chrome/browser/chromeos/crostini/crostini_types.mojom.h"
#include "chrome/browser/chromeos/crostini/crostini_util.h"
#include "chrome/browser/chromeos/file_manager/path_util.h"
#include "chrome/browser/chromeos/guest_os/guest_os_share_path.h"
-#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/lifetime/application_lifetime.h"
-#include "chrome/browser/policy/profile_policy_connector.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/webui/chromeos/crostini_upgrader/crostini_upgrader_dialog.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "components/user_manager/user_manager.h"
#include "content/public/browser/browser_thread.h"
+#include "ui/display/screen.h"
namespace chromeos {
namespace settings {
@@ -105,11 +111,42 @@ void CrostiniHandler::RegisterMessages() {
"disableArcAdbSideload",
base::BindRepeating(&CrostiniHandler::HandleDisableArcAdbRequest,
weak_ptr_factory_.GetWeakPtr()));
+ web_ui()->RegisterMessageCallback(
+ "requestCrostiniContainerUpgradeView",
+ base::BindRepeating(&CrostiniHandler::HandleRequestContainerUpgradeView,
+ weak_ptr_factory_.GetWeakPtr()));
+ web_ui()->RegisterMessageCallback(
+ "requestCrostiniUpgraderDialogStatus",
+ base::BindRepeating(
+ &CrostiniHandler::HandleCrostiniUpgraderDialogStatusRequest,
+ weak_ptr_factory_.GetWeakPtr()));
+ web_ui()->RegisterMessageCallback(
+ "requestCrostiniContainerUpgradeAvailable",
+ base::BindRepeating(
+ &CrostiniHandler::HandleCrostiniContainerUpgradeAvailableRequest,
+ weak_ptr_factory_.GetWeakPtr()));
+ web_ui()->RegisterMessageCallback(
+ "addCrostiniPortForward",
+ base::BindRepeating(&CrostiniHandler::HandleAddCrostiniPortForward,
+ weak_ptr_factory_.GetWeakPtr()));
+ web_ui()->RegisterMessageCallback(
+ "getCrostiniDiskInfo",
+ base::BindRepeating(&CrostiniHandler::HandleGetCrostiniDiskInfo,
+ weak_ptr_factory_.GetWeakPtr()));
+ web_ui()->RegisterMessageCallback(
+ "resizeCrostiniDisk",
+ base::BindRepeating(&CrostiniHandler::HandleResizeCrostiniDisk,
+ weak_ptr_factory_.GetWeakPtr()));
+ web_ui()->RegisterMessageCallback(
+ "checkCrostiniMicSharingStatus",
+ base::BindRepeating(&CrostiniHandler::HandleCheckCrostiniMicSharingStatus,
+ weak_ptr_factory_.GetWeakPtr()));
}
void CrostiniHandler::OnJavascriptAllowed() {
- crostini::CrostiniManager::GetForProfile(profile_)
- ->AddInstallerViewStatusObserver(this);
+ auto* crostini_manager = crostini::CrostiniManager::GetForProfile(profile_);
+ crostini_manager->AddCrostiniDialogStatusObserver(this);
+ crostini_manager->AddCrostiniContainerPropertiesObserver(this);
if (chromeos::CrosUsbDetector::Get()) {
chromeos::CrosUsbDetector::Get()->AddUsbDeviceObserver(this);
}
@@ -117,11 +154,9 @@ void CrostiniHandler::OnJavascriptAllowed() {
}
void CrostiniHandler::OnJavascriptDisallowed() {
- if (crostini::CrostiniManager::GetForProfile(profile_)
- ->HasInstallerViewStatusObserver(this)) {
- crostini::CrostiniManager::GetForProfile(profile_)
- ->RemoveInstallerViewStatusObserver(this);
- }
+ auto* crostini_manager = crostini::CrostiniManager::GetForProfile(profile_);
+ crostini_manager->RemoveCrostiniDialogStatusObserver(this);
+ crostini_manager->RemoveCrostiniContainerPropertiesObserver(this);
if (chromeos::CrosUsbDetector::Get()) {
chromeos::CrosUsbDetector::Get()->RemoveUsbDeviceObserver(this);
}
@@ -131,8 +166,8 @@ void CrostiniHandler::OnJavascriptDisallowed() {
void CrostiniHandler::HandleRequestCrostiniInstallerView(
const base::ListValue* args) {
AllowJavascript();
- ShowCrostiniInstallerView(Profile::FromWebUI(web_ui()),
- crostini::CrostiniUISurface::kSettings);
+ crostini::CrostiniInstaller::GetForProfile(Profile::FromWebUI(web_ui()))
+ ->ShowDialog(crostini::CrostiniUISurface::kSettings);
}
void CrostiniHandler::HandleRequestRemoveCrostini(const base::ListValue* args) {
@@ -144,40 +179,42 @@ void CrostiniHandler::HandleRequestRemoveCrostini(const base::ListValue* args) {
void CrostiniHandler::HandleGetCrostiniSharedPathsDisplayText(
const base::ListValue* args) {
AllowJavascript();
- CHECK_EQ(2U, args->GetSize());
- std::string callback_id;
- const base::ListValue* paths;
- CHECK(args->GetString(0, &callback_id));
- CHECK(args->GetList(1, &paths));
+ CHECK_EQ(2U, args->GetList().size());
+ std::string callback_id = args->GetList()[0].GetString();
+ base::Value::ConstListView paths = args->GetList()[1].GetList();
base::ListValue texts;
- for (auto it = paths->begin(); it != paths->end(); ++it) {
+ for (size_t i = 0; i < paths.size(); ++i) {
texts.AppendString(file_manager::util::GetPathDisplayTextForSettings(
- profile_, it->GetString()));
+ profile_, paths[i].GetString()));
}
ResolveJavascriptCallback(base::Value(callback_id), texts);
}
void CrostiniHandler::HandleRemoveCrostiniSharedPath(
const base::ListValue* args) {
- CHECK_EQ(2U, args->GetSize());
- std::string vm_name;
- CHECK(args->GetString(0, &vm_name));
- std::string path;
- CHECK(args->GetString(1, &path));
+ AllowJavascript();
+ CHECK_EQ(3U, args->GetList().size());
+ std::string callback_id = args->GetList()[0].GetString();
+ std::string vm_name = args->GetList()[1].GetString();
+ std::string path = args->GetList()[2].GetString();
guest_os::GuestOsSharePath::GetForProfile(profile_)->UnsharePath(
vm_name, base::FilePath(path),
/*unpersist=*/true,
- base::BindOnce(
- [](const std::string& path, bool result,
- const std::string& failure_reason) {
- if (!result) {
- LOG(ERROR) << "Error unsharing " << path << ": "
- << failure_reason;
- }
- },
- path));
+ base::BindOnce(&CrostiniHandler::OnCrostiniSharedPathRemoved,
+ weak_ptr_factory_.GetWeakPtr(), callback_id, path));
+}
+
+void CrostiniHandler::OnCrostiniSharedPathRemoved(
+ const std::string& callback_id,
+ const std::string& path,
+ bool result,
+ const std::string& failure_reason) {
+ if (!result) {
+ LOG(ERROR) << "Error unsharing " << path << ": " << failure_reason;
+ }
+ ResolveJavascriptCallback(base::Value(callback_id), base::Value(result));
}
namespace {
@@ -195,12 +232,35 @@ base::ListValue UsbDevicesToListValue(
}
return usb_devices_list;
}
+
+base::Value CrostiniDiskInfoToValue(
+ std::unique_ptr<crostini::CrostiniDiskInfo> disk_info) {
+ base::Value disk_value(base::Value::Type::DICTIONARY);
+ if (!disk_info) {
+ disk_value.SetBoolKey("succeeded", false);
+ return disk_value;
+ }
+ disk_value.SetBoolKey("succeeded", true);
+ disk_value.SetBoolKey("canResize", disk_info->can_resize);
+ disk_value.SetBoolKey("isUserChosenSize", disk_info->is_user_chosen_size);
+ disk_value.SetIntKey("defaultIndex", disk_info->default_index);
+ base::Value ticks(base::Value::Type::LIST);
+ for (const auto& tick : disk_info->ticks) {
+ base::Value t(base::Value::Type::DICTIONARY);
+ t.SetDoubleKey("value", static_cast<double>(tick->value));
+ t.SetStringKey("ariaValue", tick->aria_value);
+ t.SetStringKey("label", tick->label);
+ ticks.Append(std::move(t));
+ }
+ disk_value.SetKey("ticks", std::move(ticks));
+ return disk_value;
+}
} // namespace
void CrostiniHandler::HandleGetCrostiniSharedUsbDevices(
const base::ListValue* args) {
AllowJavascript();
- CHECK_EQ(1U, args->GetSize());
+ CHECK_EQ(1U, args->GetList().size());
std::string callback_id = args->GetList()[0].GetString();
@@ -217,7 +277,7 @@ void CrostiniHandler::HandleGetCrostiniSharedUsbDevices(
void CrostiniHandler::HandleSetCrostiniUsbDeviceShared(
const base::ListValue* args) {
- CHECK_EQ(2U, args->GetSize());
+ CHECK_EQ(2U, args->GetList().size());
const auto& args_list = args->GetList();
std::string guid = args_list[0].GetString();
bool shared = args_list[1].GetBool();
@@ -245,14 +305,14 @@ void CrostiniHandler::OnUsbDevicesChanged() {
void CrostiniHandler::HandleExportCrostiniContainer(
const base::ListValue* args) {
- CHECK_EQ(0U, args->GetSize());
+ CHECK_EQ(0U, args->GetList().size());
crostini::CrostiniExportImport::GetForProfile(profile_)->ExportContainer(
web_ui()->GetWebContents());
}
void CrostiniHandler::HandleImportCrostiniContainer(
const base::ListValue* args) {
- CHECK_EQ(0U, args->GetSize());
+ CHECK_EQ(0U, args->GetList().size());
crostini::CrostiniExportImport::GetForProfile(profile_)->ImportContainer(
web_ui()->GetWebContents());
}
@@ -260,45 +320,57 @@ void CrostiniHandler::HandleImportCrostiniContainer(
void CrostiniHandler::HandleCrostiniInstallerStatusRequest(
const base::ListValue* args) {
AllowJavascript();
- CHECK_EQ(0U, args->GetSize());
+ CHECK_EQ(0U, args->GetList().size());
bool status = crostini::CrostiniManager::GetForProfile(profile_)
- ->GetInstallerViewStatus();
- OnCrostiniInstallerViewStatusChanged(status);
+ ->GetCrostiniDialogStatus(crostini::DialogType::INSTALLER);
+ OnCrostiniDialogStatusChanged(crostini::DialogType::INSTALLER, status);
}
void CrostiniHandler::HandleCrostiniExportImportOperationStatusRequest(
const base::ListValue* args) {
AllowJavascript();
- CHECK_EQ(0U, args->GetSize());
+ CHECK_EQ(0U, args->GetList().size());
bool in_progress = crostini::CrostiniExportImport::GetForProfile(profile_)
->GetExportImportOperationStatus();
OnCrostiniExportImportOperationStatusChanged(in_progress);
}
-void CrostiniHandler::OnCrostiniInstallerViewStatusChanged(bool status) {
+void CrostiniHandler::OnCrostiniDialogStatusChanged(
+ crostini::DialogType dialog_type,
+ bool status) {
// It's technically possible for this to be called before Javascript is
// enabled, in which case we must not call FireWebUIListener
if (IsJavascriptAllowed()) {
// Other side listens with cr.addWebUIListener
- FireWebUIListener("crostini-installer-status-changed", base::Value(status));
+ switch (dialog_type) {
+ case crostini::DialogType::INSTALLER:
+ FireWebUIListener("crostini-installer-status-changed",
+ base::Value(status));
+ break;
+ case crostini::DialogType::UPGRADER:
+ FireWebUIListener("crostini-upgrader-status-changed",
+ base::Value(status));
+ break;
+ case crostini::DialogType::REMOVER:
+ FireWebUIListener("crostini-remover-status-changed",
+ base::Value(status));
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
}
}
-void CrostiniHandler::OnCrostiniExportImportOperationStatusChanged(
- bool in_progress) {
- // Other side listens with cr.addWebUIListener
- FireWebUIListener("crostini-export-import-operation-status-changed",
- base::Value(in_progress));
-}
-
-void CrostiniHandler::HandleQueryArcAdbRequest(const base::ListValue* args) {
- AllowJavascript();
- CHECK_EQ(0U, args->GetSize());
-
- chromeos::SessionManagerClient* client =
- chromeos::SessionManagerClient::Get();
- client->QueryAdbSideload(base::Bind(&CrostiniHandler::OnQueryAdbSideload,
- weak_ptr_factory_.GetWeakPtr()));
+void CrostiniHandler::OnContainerOsReleaseChanged(
+ const crostini::ContainerId& container_id,
+ bool can_upgrade) {
+ if (crostini::CrostiniFeatures::Get()->IsContainerUpgradeUIAllowed(
+ profile_) &&
+ container_id == crostini::DefaultContainerId()) {
+ FireWebUIListener("crostini-container-upgrade-available-changed",
+ base::Value(can_upgrade));
+ }
}
void CrostiniHandler::OnQueryAdbSideload(
@@ -317,7 +389,7 @@ void CrostiniHandler::OnQueryAdbSideload(
}
void CrostiniHandler::HandleEnableArcAdbRequest(const base::ListValue* args) {
- CHECK_EQ(0U, args->GetSize());
+ CHECK_EQ(0U, args->GetList().size());
if (!CheckEligibilityToChangeArcAdbSideloading())
return;
@@ -331,7 +403,7 @@ void CrostiniHandler::HandleEnableArcAdbRequest(const base::ListValue* args) {
}
void CrostiniHandler::HandleDisableArcAdbRequest(const base::ListValue* args) {
- CHECK_EQ(0U, args->GetSize());
+ CHECK_EQ(0U, args->GetList().size());
if (!CheckEligibilityToChangeArcAdbSideloading())
return;
@@ -346,28 +418,133 @@ void CrostiniHandler::HandleDisableArcAdbRequest(const base::ListValue* args) {
}
bool CrostiniHandler::CheckEligibilityToChangeArcAdbSideloading() const {
- if (!chromeos::ProfileHelper::IsOwnerProfile(profile_)) {
- DVLOG(1) << "Only the owner can change adb sideloading status";
- return false;
- }
+ return crostini::CrostiniFeatures::Get()->CanChangeAdbSideloading(profile_);
+}
- if (user_manager::UserManager::Get()->IsLoggedInAsChildUser()) {
- DVLOG(1) << "adb sideloading is currently unsupported for child account";
- return false;
- }
+void CrostiniHandler::LaunchTerminal() {
+ crostini::LaunchCrostiniApp(
+ profile_, crostini::GetTerminalId(),
+ display::Screen::GetScreen()->GetPrimaryDisplay().id());
+}
- if (profile_->GetProfilePolicyConnector()->IsManaged()) {
- DVLOG(1) << "adb sideloading is currently unsupported for managed user";
- return false;
- }
+void CrostiniHandler::HandleRequestContainerUpgradeView(
+ const base::ListValue* args) {
+ CHECK_EQ(0U, args->GetList().size());
+ chromeos::CrostiniUpgraderDialog::Show(
+ base::BindOnce(&CrostiniHandler::LaunchTerminal,
+ weak_ptr_factory_.GetWeakPtr()),
+ // If the user cancels the upgrade, we won't need to restart Crostini and
+ // we don't want to run the launch closure which would launch Terminal.
+ /*only_run_launch_closure_on_restart=*/true);
+}
- policy::BrowserPolicyConnectorChromeOS* connector =
- g_browser_process->platform_part()->browser_policy_connector_chromeos();
- if (connector->IsEnterpriseManaged()) {
- DVLOG(1) << "adb sideloading is currently unsupported on managed device";
- return false;
- }
- return true;
+void CrostiniHandler::OnCrostiniExportImportOperationStatusChanged(
+ bool in_progress) {
+ // Other side listens with cr.addWebUIListener
+ FireWebUIListener("crostini-export-import-operation-status-changed",
+ base::Value(in_progress));
+}
+
+void CrostiniHandler::HandleQueryArcAdbRequest(const base::ListValue* args) {
+ AllowJavascript();
+ CHECK_EQ(0U, args->GetList().size());
+
+ chromeos::SessionManagerClient* client =
+ chromeos::SessionManagerClient::Get();
+ client->QueryAdbSideload(base::Bind(&CrostiniHandler::OnQueryAdbSideload,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void CrostiniHandler::HandleCrostiniUpgraderDialogStatusRequest(
+ const base::ListValue* args) {
+ AllowJavascript();
+ CHECK_EQ(0U, args->GetList().size());
+ bool is_open = crostini::CrostiniManager::GetForProfile(profile_)
+ ->GetCrostiniDialogStatus(crostini::DialogType::UPGRADER);
+ OnCrostiniDialogStatusChanged(crostini::DialogType::UPGRADER, is_open);
+}
+
+void CrostiniHandler::HandleCrostiniContainerUpgradeAvailableRequest(
+ const base::ListValue* args) {
+ AllowJavascript();
+
+ bool can_upgrade = crostini::ShouldAllowContainerUpgrade(profile_);
+ OnContainerOsReleaseChanged(crostini::DefaultContainerId(), can_upgrade);
+}
+
+void CrostiniHandler::HandleAddCrostiniPortForward(
+ const base::ListValue* args) {
+ CHECK_EQ(6U, args->GetList().size());
+
+ std::string callback_id = args->GetList()[0].GetString();
+ std::string vm_name = args->GetList()[1].GetString();
+ std::string container_name = args->GetList()[2].GetString();
+ int port_number = args->GetList()[3].GetInt();
+ int protocol_type = args->GetList()[4].GetInt();
+ std::string label = args->GetList()[5].GetString();
+
+ crostini::CrostiniPortForwarder::GetForProfile(profile_)->AddPort(
+ crostini::ContainerId(std::move(vm_name), std::move(container_name)),
+ port_number,
+ static_cast<crostini::CrostiniPortForwarder::Protocol>(protocol_type),
+ std::move(label),
+ base::Bind(&CrostiniHandler::OnPortForwardComplete,
+ weak_ptr_factory_.GetWeakPtr(), std::move(callback_id)));
+}
+
+void CrostiniHandler::OnPortForwardComplete(std::string callback_id,
+ bool success) {
+ ResolveJavascriptCallback(base::Value(callback_id), base::Value(success));
+}
+
+void CrostiniHandler::ResolveGetCrostiniDiskInfoCallback(
+ const std::string& callback_id,
+ std::unique_ptr<crostini::CrostiniDiskInfo> disk_info) {
+ ResolveJavascriptCallback(base::Value(std::move(callback_id)),
+ CrostiniDiskInfoToValue(std::move(disk_info)));
+}
+
+void CrostiniHandler::HandleGetCrostiniDiskInfo(const base::ListValue* args) {
+ AllowJavascript();
+ CHECK_EQ(2U, args->GetList().size());
+ std::string callback_id = args->GetList()[0].GetString();
+ std::string vm_name = args->GetList()[1].GetString();
+ crostini::disk::GetDiskInfo(
+ base::BindOnce(&CrostiniHandler::ResolveGetCrostiniDiskInfoCallback,
+ weak_ptr_factory_.GetWeakPtr(), std::move(callback_id)),
+ profile_, std::move(vm_name));
+}
+
+void CrostiniHandler::HandleResizeCrostiniDisk(const base::ListValue* args) {
+ CHECK_EQ(3U, args->GetList().size());
+ std::string callback_id = args->GetList()[0].GetString();
+ std::string vm_name = args->GetList()[1].GetString();
+ double bytes = args->GetList()[2].GetDouble();
+ crostini::disk::ResizeCrostiniDisk(
+ profile_, std::move(vm_name), bytes,
+ base::BindOnce(&CrostiniHandler::ResolveResizeCrostiniDiskCallback,
+ weak_ptr_factory_.GetWeakPtr(), std::move(callback_id)));
+}
+
+void CrostiniHandler::ResolveResizeCrostiniDiskCallback(
+ const std::string& callback_id,
+ bool succeeded) {
+ ResolveJavascriptCallback(base::Value(std::move(callback_id)),
+ base::Value(succeeded));
+}
+
+void CrostiniHandler::HandleCheckCrostiniMicSharingStatus(
+ const base::ListValue* args) {
+ CHECK_EQ(2U, args->GetList().size());
+ std::string callback_id = args->GetList()[0].GetString();
+ bool proposed_value = args->GetList()[1].GetBool();
+ bool requiresRestart =
+ crostini::IsCrostiniRunning(profile_) &&
+ profile_->GetPrefs()->GetBoolean(
+ crostini::prefs::kCrostiniMicSharingAtLastLaunch) != proposed_value;
+
+ ResolveJavascriptCallback(base::Value(std::move(callback_id)),
+ base::Value(requiresRestart));
}
} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.h
index bab8509806a..f51fc69e1b7 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.h
@@ -18,14 +18,16 @@ class Profile;
namespace crostini {
enum class CrostiniResult;
-}
+struct CrostiniDiskInfo;
+} // namespace crostini
namespace chromeos {
namespace settings {
class CrostiniHandler : public ::settings::SettingsPageUIHandler,
- public crostini::InstallerViewStatusObserver,
+ public crostini::CrostiniDialogStatusObserver,
public crostini::CrostiniExportImport::Observer,
+ public crostini::CrostiniContainerPropertiesObserver,
public chromeos::CrosUsbDeviceObserver {
public:
explicit CrostiniHandler(Profile* profile);
@@ -45,6 +47,10 @@ class CrostiniHandler : public ::settings::SettingsPageUIHandler,
void HandleGetCrostiniSharedPathsDisplayText(const base::ListValue* args);
// Remove a specified path from being shared.
void HandleRemoveCrostiniSharedPath(const base::ListValue* args);
+ void OnCrostiniSharedPathRemoved(const std::string& callback_id,
+ const std::string& path,
+ bool result,
+ const std::string& failure_reason);
// Returns a list of available USB devices.
void HandleGetCrostiniSharedUsbDevices(const base::ListValue* args);
// Set the share state of a USB device.
@@ -57,8 +63,12 @@ class CrostiniHandler : public ::settings::SettingsPageUIHandler,
void HandleImportCrostiniContainer(const base::ListValue* args);
// Handle a request for the CrostiniInstallerView status.
void HandleCrostiniInstallerStatusRequest(const base::ListValue* args);
- // Handle the CrostiniInstallerView opening/closing.
- void OnCrostiniInstallerViewStatusChanged(bool open) override;
+ // crostini::CrostiniDialogStatusObserver
+ void OnCrostiniDialogStatusChanged(crostini::DialogType dialog_type,
+ bool open) override;
+ // crostini::CrostiniContainerPropertiesObserver
+ void OnContainerOsReleaseChanged(const crostini::ContainerId& container_id,
+ bool can_upgrade) override;
// Handle a request for the CrostiniExportImport operation status.
void HandleCrostiniExportImportOperationStatusRequest(
const base::ListValue* args);
@@ -70,6 +80,10 @@ class CrostiniHandler : public ::settings::SettingsPageUIHandler,
void HandleEnableArcAdbRequest(const base::ListValue* args);
// Handle a request for disabling adb sideloading in ARC.
void HandleDisableArcAdbRequest(const base::ListValue* args);
+ // Launch the Crostini terminal.
+ void LaunchTerminal();
+ // Handle a request for showing the container upgrade view.
+ void HandleRequestContainerUpgradeView(const base::ListValue* args);
// Callback of HandleQueryArcAdbRequest.
void OnQueryAdbSideload(
SessionManagerClient::AdbSideloadResponseCode response_code,
@@ -77,6 +91,26 @@ class CrostiniHandler : public ::settings::SettingsPageUIHandler,
// Returns whether the current user can change adb sideloading configuration
// on current device.
bool CheckEligibilityToChangeArcAdbSideloading() const;
+ // Handle a request for the CrostiniUpgraderDialog status.
+ void HandleCrostiniUpgraderDialogStatusRequest(const base::ListValue* args);
+ // Handle a request for the availability of a container upgrade.
+ void HandleCrostiniContainerUpgradeAvailableRequest(
+ const base::ListValue* args);
+ // Handles a request for forwarding a new port.
+ void HandleAddCrostiniPortForward(const base::ListValue* args);
+ // Callback of port forwarding requests.
+ void OnPortForwardComplete(std::string callback_id, bool success);
+ // Fetches disk info for a VM, can be slow (seconds).
+ void HandleGetCrostiniDiskInfo(const base::ListValue* args);
+ void ResolveGetCrostiniDiskInfoCallback(
+ const std::string& callback_id,
+ std::unique_ptr<crostini::CrostiniDiskInfo> disk_info);
+ // Handles a request to resize a Crostini disk.
+ void HandleResizeCrostiniDisk(const base::ListValue* args);
+ void ResolveResizeCrostiniDiskCallback(const std::string& callback_id,
+ bool succeeded);
+ // Checks if a restart is required to update mic sharing settings.
+ void HandleCheckCrostiniMicSharingStatus(const base::ListValue* args);
Profile* profile_;
// weak_ptr_factory_ should always be last member.
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
index 74f1ab84039..fd6f8acdd11 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
@@ -14,12 +14,14 @@
#include "base/files/file_util.h"
#include "base/json/json_string_value_serializer.h"
#include "base/logging.h"
+#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/optional.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/task/post_task.h"
+#include "base/task/thread_pool.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
@@ -37,12 +39,11 @@
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/chrome_select_file_policy.h"
+#include "chrome/browser/ui/webui/settings/chromeos/server_printer_url_util.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/pref_names.h"
-#include "chrome/common/webui_url_constants.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/debug_daemon/debug_daemon_client.h"
-#include "chromeos/printing/ppd_cache.h"
#include "chromeos/printing/ppd_line_reader.h"
#include "chromeos/printing/printer_configuration.h"
#include "chromeos/printing/printer_translator.h"
@@ -58,6 +59,7 @@
#include "net/base/ip_endpoint.h"
#include "net/url_request/url_request_context_getter.h"
#include "printing/backend/print_backend.h"
+#include "printing/printer_status.h"
#include "url/gurl.h"
namespace chromeos {
@@ -113,8 +115,8 @@ void QueryAutoconf(const std::string& printer_uri,
// Behavior for querying a non-IPP uri is undefined and disallowed.
if (!IsIppUri(printer_uri) || !optional.has_value()) {
PRINTER_LOG(ERROR) << "Printer uri is invalid: " << printer_uri;
- std::move(callback).Run(PrinterQueryResult::UNKNOWN_FAILURE, "", "", "", {},
- false);
+ std::move(callback).Run(PrinterQueryResult::UNKNOWN_FAILURE,
+ printing::PrinterStatus(), "", "", "", {}, false);
return;
}
@@ -168,6 +170,7 @@ std::unique_ptr<chromeos::Printer> DictToPrinter(
std::string printer_make_and_model;
std::string printer_address;
std::string printer_protocol;
+ std::string print_server_uri;
if (!printer_dict.GetString("printerId", &printer_id) ||
!printer_dict.GetString("printerName", &printer_name) ||
@@ -176,7 +179,8 @@ std::unique_ptr<chromeos::Printer> DictToPrinter(
!printer_dict.GetString("printerModel", &printer_model) ||
!printer_dict.GetString("printerMakeAndModel", &printer_make_and_model) ||
!printer_dict.GetString("printerAddress", &printer_address) ||
- !printer_dict.GetString("printerProtocol", &printer_protocol)) {
+ !printer_dict.GetString("printerProtocol", &printer_protocol) ||
+ !printer_dict.GetString("printServerUri", &print_server_uri)) {
return nullptr;
}
@@ -195,6 +199,7 @@ std::unique_ptr<chromeos::Printer> DictToPrinter(
printer->set_model(printer_model);
printer->set_make_and_model(printer_make_and_model);
printer->set_uri(printer_uri);
+ printer->set_print_server_uri(print_server_uri);
return printer;
}
@@ -237,11 +242,6 @@ void SetPpdReference(const Printer::PpdReference& ppd_ref, base::Value* info) {
}
}
-bool IsFilledPpdReference(const Printer::PpdReference& ppd_ref) {
- return ppd_ref.autoconf || !ppd_ref.user_supplied_ppd_url.empty() ||
- !ppd_ref.effective_make_and_model.empty();
-}
-
Printer::PpdReference GetPpdReference(const base::Value* info) {
const char ppd_ref_pathname[] = "printerPpdReference";
auto* user_supplied_ppd_url =
@@ -267,40 +267,11 @@ Printer::PpdReference GetPpdReference(const base::Value* info) {
return ret;
}
-bool ConvertToGURL(const std::string& url, GURL* gurl) {
- *gurl = GURL(url);
- if (!gurl->is_valid()) {
- // URL is not valid.
- return false;
- }
- if (!gurl->SchemeIsHTTPOrHTTPS() && !gurl->SchemeIs("ipp") &&
- !gurl->SchemeIs("ipps")) {
- // URL has unsupported scheme; we support only: http, https, ipp, ipps.
- return false;
- }
- // Replaces ipp/ipps by http/https. IPP standard describes protocol built
- // on top of HTTP, so both types of addresses have the same meaning in the
- // context of IPP interface. Moreover, the URL must have http/https scheme
- // to pass IsStandard() test from GURL library (see "Validation of the URL
- // address" below).
- bool set_ipp_port = false;
- if (gurl->SchemeIs("ipp")) {
- set_ipp_port = (gurl->IntPort() == url::PORT_UNSPECIFIED);
- *gurl = GURL("http" + url.substr(url.find_first_of(':')));
- } else if (gurl->SchemeIs("ipps")) {
- *gurl = GURL("https" + url.substr(url.find_first_of(':')));
- }
- // The default port for ipp is 631. If the schema ipp is replaced by http
- // and the port is not explicitly defined in the url, we have to overwrite
- // the default http port with the default ipp port. For ipps we do nothing
- // because implementers use the same port for ipps and https.
- if (set_ipp_port) {
- GURL::Replacements replacement;
- replacement.SetPortStr("631");
- *gurl = gurl->ReplaceComponents(replacement);
- }
- // Validation of the URL address.
- return gurl->IsStandard();
+GURL GenerateHttpCupsServerUrl(const GURL& server_url) {
+ GURL::Replacements replacement;
+ replacement.SetSchemeStr("http");
+ replacement.SetPortStr("631");
+ return server_url.ReplaceComponents(replacement);
}
} // namespace
@@ -405,6 +376,10 @@ void CupsPrintersHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(
"getEulaUrl", base::BindRepeating(&CupsPrintersHandler::HandleGetEulaUrl,
base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "queryPrintServer",
+ base::BindRepeating(&CupsPrintersHandler::HandleQueryPrintServer,
+ base::Unretained(this)));
}
void CupsPrintersHandler::OnJavascriptAllowed() {
@@ -513,8 +488,8 @@ void CupsPrintersHandler::HandleGetPrinterInfo(const base::ListValue* args) {
if (printer_address.empty()) {
// Run the failure callback.
- OnAutoconfQueried(callback_id, PrinterQueryResult::UNKNOWN_FAILURE, "", "",
- "", {}, false);
+ OnAutoconfQueried(callback_id, PrinterQueryResult::UNKNOWN_FAILURE,
+ printing::PrinterStatus(), "", "", "", {}, false);
return;
}
@@ -541,6 +516,7 @@ void CupsPrintersHandler::OnAutoconfQueriedDiscovered(
const std::string& callback_id,
Printer printer,
PrinterQueryResult result,
+ const printing::PrinterStatus& printer_status,
const std::string& make,
const std::string& model,
const std::string& make_and_model,
@@ -587,6 +563,7 @@ void CupsPrintersHandler::OnAutoconfQueriedDiscovered(
void CupsPrintersHandler::OnAutoconfQueried(
const std::string& callback_id,
PrinterQueryResult result,
+ const printing::PrinterStatus& printer_status,
const std::string& make,
const std::string& model,
const std::string& make_and_model,
@@ -736,7 +713,7 @@ void CupsPrintersHandler::AddOrReconfigurePrinter(const base::ListValue* args,
// Check if the printer already has a valid ppd_reference.
Printer::PpdReference ppd_ref = GetPpdReference(printer_dict);
- if (IsFilledPpdReference(ppd_ref)) {
+ if (ppd_ref.IsFilled()) {
*printer->mutable_ppd_reference() = ppd_ref;
} else if (!printer_ppd_path.empty()) {
GURL tmp = net::FilePathToFileURL(base::FilePath(printer_ppd_path));
@@ -1003,9 +980,8 @@ void CupsPrintersHandler::FileSelected(const base::FilePath& path,
// VerifyPpdContents() in order to determine whether the file appears to be a
// PPD file. The task's priority is USER_BLOCKING because the this task
// updates the UI as a result of a direct user action.
- base::PostTaskAndReplyWithResult(
- FROM_HERE,
- {base::ThreadPool(), base::MayBlock(), base::TaskPriority::USER_BLOCKING},
+ base::ThreadPool::PostTaskAndReplyWithResult(
+ FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_BLOCKING},
base::BindOnce(&ReadFileToStringWithMaxSize, path, kPpdMaxLineLength),
base::BindOnce(&CupsPrintersHandler::VerifyPpdContents,
weak_factory_.GetWeakPtr(), path));
@@ -1239,7 +1215,7 @@ void CupsPrintersHandler::OnGetEulaUrl(const std::string& callback_id,
return;
}
- GURL eula_url(chrome::kChromeUIOSCreditsURL + license);
+ GURL eula_url = PrinterConfigurer::GeneratePrinterEulaUrl(license);
ResolveJavascriptCallback(
base::Value(callback_id),
eula_url.is_valid() ? base::Value(eula_url.spec()) : base::Value());
@@ -1283,27 +1259,45 @@ void CupsPrintersHandler::HandleQueryPrintServer(const base::ListValue* args) {
CHECK(args->GetString(0, &callback_id));
CHECK(args->GetString(1, &server_url));
- GURL server_gurl;
- if (!ConvertToGURL(server_url, &server_gurl)) {
+ base::Optional<GURL> converted_server_url =
+ GenerateServerPrinterUrlWithValidScheme(server_url);
+ if (!converted_server_url) {
RejectJavascriptCallback(
base::Value(callback_id),
base::Value(PrintServerQueryResult::kIncorrectUrl));
return;
}
+ // Use fallback only if HasValidServerPrinterScheme is false.
+ QueryPrintServer(callback_id, converted_server_url.value(),
+ !HasValidServerPrinterScheme(GURL(server_url)));
+}
+
+void CupsPrintersHandler::QueryPrintServer(const std::string& callback_id,
+ const GURL& server_url,
+ bool should_fallback) {
server_printers_fetcher_ = std::make_unique<ServerPrintersFetcher>(
- server_gurl, "(from user)",
+ server_url, "(from user)",
base::BindRepeating(&CupsPrintersHandler::OnQueryPrintServerCompleted,
- weak_factory_.GetWeakPtr(), callback_id));
+ weak_factory_.GetWeakPtr(), callback_id,
+ should_fallback));
}
void CupsPrintersHandler::OnQueryPrintServerCompleted(
const std::string& callback_id,
+ bool should_fallback,
const ServerPrintersFetcher* sender,
const GURL& server_url,
std::vector<PrinterDetector::DetectedPrinter>&& returned_printers) {
const PrintServerQueryResult result = sender->GetLastError();
if (result != PrintServerQueryResult::kNoErrors) {
+ if (should_fallback) {
+ // Apply the fallback query.
+ QueryPrintServer(callback_id, GenerateHttpCupsServerUrl(server_url),
+ /*should_fallback=*/false);
+ return;
+ }
+
RejectJavascriptCallback(base::Value(callback_id), base::Value(result));
return;
}
@@ -1313,9 +1307,10 @@ void CupsPrintersHandler::OnQueryPrintServerCompleted(
printers_manager_->GetPrinters(PrinterClass::kSaved);
std::set<GURL> known_printers;
for (const Printer& printer : saved_printers) {
- GURL gurl;
- if (ConvertToGURL(printer.uri(), &gurl))
- known_printers.insert(gurl);
+ base::Optional<GURL> gurl =
+ GenerateServerPrinterUrlWithValidScheme(printer.uri());
+ if (gurl)
+ known_printers.insert(gurl.value());
}
// Built final list of printers and a list of current names. If "current name"
@@ -1325,11 +1320,10 @@ void CupsPrintersHandler::OnQueryPrintServerCompleted(
printers.reserve(returned_printers.size());
for (PrinterDetector::DetectedPrinter& printer : returned_printers) {
printers.push_back(std::move(printer.printer));
- GURL printer_gurl;
- if (ConvertToGURL(printers.back().uri(), &printer_gurl)) {
- if (known_printers.count(printer_gurl))
- printers.pop_back();
- }
+ base::Optional<GURL> printer_gurl =
+ GenerateServerPrinterUrlWithValidScheme(printers.back().uri());
+ if (printer_gurl && known_printers.count(printer_gurl.value()))
+ printers.pop_back();
}
// Delete fetcher object.
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h
index 6e80a910a18..82de71cf6cc 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h
@@ -18,7 +18,7 @@
#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
#include "chromeos/printing/ppd_provider.h"
#include "chromeos/printing/printer_configuration.h"
-#include "printing/printer_query_result_chromeos.h"
+#include "printing/printer_query_result.h"
#include "ui/shell_dialogs/select_file_dialog.h"
namespace base {
@@ -30,6 +30,10 @@ namespace local_discovery {
class EndpointResolver;
} // namespace local_discovery
+namespace printing {
+struct PrinterStatus;
+} // namespace printing
+
class GURL;
class Profile;
@@ -77,14 +81,17 @@ class CupsPrintersHandler : public ::settings::SettingsPageUIHandler,
void HandleGetPrinterInfo(const base::ListValue* args);
// Handles the callback for HandleGetPrinterInfo. |callback_id| is the
- // identifier to resolve the correct Promise. |success| indicates if the query
- // was successful. |make| is the detected printer manufacturer. |model| is the
+ // identifier to resolve the correct Promise. |result| indicates if the query
+ // was successful. |printer_status| contains the current status of the
+ // printer. |make| is the detected printer manufacturer. |model| is the
// detected model. |make_and_model| is the unparsed printer-make-and-model
// string. |ipp_everywhere| indicates if configuration using the CUPS IPP
- // Everywhere driver should be attempted. If |success| is false, the values of
- // |make|, |model|, |make_and_model|, and |ipp_everywhere| are not specified.
+ // Everywhere driver should be attempted. If |result| is not SUCCESS, the
+ // values of |printer_status|, |make|, |model|, |make_and_model|, and
+ // |ipp_everywhere| are not specified.
void OnAutoconfQueried(const std::string& callback_id,
printing::PrinterQueryResult result,
+ const printing::PrinterStatus& printer_status,
const std::string& make,
const std::string& model,
const std::string& make_and_model,
@@ -96,6 +103,7 @@ class CupsPrintersHandler : public ::settings::SettingsPageUIHandler,
const std::string& callback_id,
Printer printer,
printing::PrinterQueryResult result,
+ const printing::PrinterStatus& printer_status,
const std::string& make,
const std::string& model,
const std::string& make_and_model,
@@ -214,8 +222,14 @@ class CupsPrintersHandler : public ::settings::SettingsPageUIHandler,
const net::IPEndPoint& endpoint);
void HandleQueryPrintServer(const base::ListValue* args);
+
+ void QueryPrintServer(const std::string& callback_id,
+ const GURL& server_url,
+ bool should_fallback);
+
void OnQueryPrintServerCompleted(
const std::string& callback_id,
+ bool should_fallback,
const ServerPrintersFetcher* sender,
const GURL& server_url,
std::vector<PrinterDetector::DetectedPrinter>&& returned_printers);
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/date_time_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/date_time_handler.cc
index 59656e6e848..39ceb89c02a 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/date_time_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/date_time_handler.cc
@@ -168,8 +168,8 @@ void DateTimeHandler::HandleShowParentAccessForTimeZone(
ash::LoginScreen::Get()->ShowParentAccessWidget(
user_manager::UserManager::Get()->GetActiveUser()->GetAccountId(),
- base::BindRepeating(&DateTimeHandler::OnParentAccessValidation,
- weak_ptr_factory_.GetWeakPtr()),
+ base::BindOnce(&DateTimeHandler::OnParentAccessValidation,
+ weak_ptr_factory_.GetWeakPtr()),
ash::ParentAccessRequestReason::kChangeTimezone, false /* extra_dimmer */,
base::Time());
}
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc
index ee16a539c7b..7195f59a799 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc
@@ -6,7 +6,6 @@
#include "ash/public/cpp/keyboard_shortcut_viewer.h"
#include "ash/public/cpp/tablet_mode.h"
-#include "ash/public/mojom/constants.mojom.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/values.h"
@@ -21,25 +20,33 @@ namespace {
struct KeyboardsStateResult {
bool has_internal_keyboard = false;
- bool has_external_non_apple_keyboard = false;
- bool has_apple_keyboard = false;
+ bool has_external_apple_keyboard = false;
+ bool has_external_chromeos_keyboard = false;
+ bool has_external_generic_keyboard = false;
};
KeyboardsStateResult GetKeyboardsState() {
KeyboardsStateResult result;
for (const ui::InputDevice& keyboard :
ui::DeviceDataManager::GetInstance()->GetKeyboardDevices()) {
- result.has_internal_keyboard |=
- (keyboard.type == ui::INPUT_DEVICE_INTERNAL);
-
- const ui::EventRewriterChromeOS::DeviceType type =
- ui::EventRewriterChromeOS::GetDeviceType(keyboard);
- if (type == ui::EventRewriterChromeOS::kDeviceAppleKeyboard) {
- result.has_apple_keyboard = true;
- } else if (type ==
- ui::EventRewriterChromeOS::kDeviceExternalNonAppleKeyboard ||
- type == ui::EventRewriterChromeOS::kDeviceExternalUnknown) {
- result.has_external_non_apple_keyboard = true;
+ switch (ui::EventRewriterChromeOS::GetDeviceType(keyboard)) {
+ case ui::EventRewriterChromeOS::kDeviceInternalKeyboard:
+ result.has_internal_keyboard = true;
+ break;
+ case ui::EventRewriterChromeOS::kDeviceExternalAppleKeyboard:
+ result.has_external_apple_keyboard = true;
+ break;
+ case ui::EventRewriterChromeOS::kDeviceExternalChromeOsKeyboard:
+ result.has_external_chromeos_keyboard = true;
+ break;
+ case ui::EventRewriterChromeOS::kDeviceExternalGenericKeyboard:
+ case ui::EventRewriterChromeOS::kDeviceExternalUnknown:
+ result.has_external_generic_keyboard = true;
+ break;
+ case ui::EventRewriterChromeOS::kDeviceHotrodRemote:
+ case ui::EventRewriterChromeOS::kDeviceVirtualCoreKeyboard:
+ case ui::EventRewriterChromeOS::kDeviceUnknown:
+ break;
}
}
@@ -131,8 +138,8 @@ void KeyboardHandler::UpdateShowKeys() {
// kHasChromeOSKeyboard will be unset on Chromebooks that have standalone Caps
// Lock keys.
const KeyboardsStateResult keyboards_state = GetKeyboardsState();
- const bool has_caps_lock = keyboards_state.has_apple_keyboard ||
- keyboards_state.has_external_non_apple_keyboard ||
+ const bool has_caps_lock = keyboards_state.has_external_apple_keyboard ||
+ keyboards_state.has_external_generic_keyboard ||
!base::CommandLine::ForCurrentProcess()->HasSwitch(
chromeos::switches::kHasChromeOSKeyboard);
@@ -140,9 +147,10 @@ void KeyboardHandler::UpdateShowKeys() {
keyboard_params.SetKey("showCapsLock", base::Value(has_caps_lock));
keyboard_params.SetKey(
"showExternalMetaKey",
- base::Value(keyboards_state.has_external_non_apple_keyboard));
- keyboard_params.SetKey("showAppleCommandKey",
- base::Value(keyboards_state.has_apple_keyboard));
+ base::Value(keyboards_state.has_external_generic_keyboard));
+ keyboard_params.SetKey(
+ "showAppleCommandKey",
+ base::Value(keyboards_state.has_external_apple_keyboard));
keyboard_params.SetKey("hasInternalKeyboard",
base::Value(keyboards_state.has_internal_keyboard));
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler_unittest.cc
index 8f4f6318a50..a558502222a 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler_unittest.cc
@@ -15,6 +15,7 @@
#include "base/observer_list.h"
#include "chromeos/constants/chromeos_switches.h"
#include "content/public/test/test_web_ui.h"
+#include "device/udev_linux/fake_udev_loader.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/devices/device_data_manager_test_api.h"
#include "ui/events/devices/input_device.h"
@@ -192,11 +193,46 @@ TEST_F(KeyboardHandlerTest, NonChromeOSKeyboard) {
}
TEST_F(KeyboardHandlerTest, ExternalKeyboard) {
+ auto fake_udev = std::make_unique<testing::FakeUdevLoader>();
+
+ // Standard internal keyboard on x86 device.
+ const ui::InputDevice internal_kbd(
+ 1, ui::INPUT_DEVICE_INTERNAL, "AT Translated Set 2 keyboard", "",
+ base::FilePath("/devices/platform/i8042/serio0/input/input1"), 1, 1,
+ 0xab41);
+ fake_udev->AddFakeDevice(internal_kbd.name, internal_kbd.sys_path.value(), {},
+ {});
+ // Generic external USB keyboard.
+ const ui::InputDevice external_generic_kbd(
+ 2, ui::INPUT_DEVICE_USB, "Logitech USB Keyboard", "",
+ base::FilePath("/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1:1.0/"
+ "0003:046D:C31C.0007/"
+ "input/input2"),
+ 0x046d, 0xc31c, 0x0111);
+ fake_udev->AddFakeDevice(external_generic_kbd.name,
+ external_generic_kbd.sys_path.value(), {}, {});
+ // Apple keyboard.
+ const ui::InputDevice external_apple_kbd(
+ 3, ui::INPUT_DEVICE_USB, "Apple Inc. Apple Keyboard", "",
+ base::FilePath("/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1:1.1/"
+ "0003:05AC:026C.000A/input/input3"),
+ 0x05ac, 0x026c, 0x0111);
+ fake_udev->AddFakeDevice(external_apple_kbd.name,
+ external_apple_kbd.sys_path.value(), {}, {});
+ // Chrome OS external USB keyboard.
+ const ui::InputDevice external_chromeos_kbd(
+ 4, ui::INPUT_DEVICE_USB, "LG USB Keyboard", "",
+ base::FilePath("/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1:1.0/"
+ "0003:04CA:0082.000B/input/input4"),
+ 0x04ca, 0x0082, 0x0111);
+ fake_udev->AddFakeDevice(external_chromeos_kbd.name,
+ external_chromeos_kbd.sys_path.value(), {},
+ {{"CROS_KEYBOARD_TOP_ROW_LAYOUT", "1"}});
+
// An internal keyboard shouldn't change the defaults.
base::CommandLine::ForCurrentProcess()->AppendSwitch(
chromeos::switches::kHasChromeOSKeyboard);
- device_data_manager_test_api_.SetKeyboardDevices(std::vector<ui::InputDevice>{
- {1, ui::INPUT_DEVICE_INTERNAL, "internal keyboard"}});
+ device_data_manager_test_api_.SetKeyboardDevices({internal_kbd});
handler_test_api_.Initialize();
EXPECT_TRUE(HasInternalSearchKey());
EXPECT_FALSE(HasCapsLock());
@@ -206,20 +242,28 @@ TEST_F(KeyboardHandlerTest, ExternalKeyboard) {
// Simulate an external keyboard being connected. We should assume there's a
// Caps Lock and Meta keys now.
- device_data_manager_test_api_.SetKeyboardDevices(std::vector<ui::InputDevice>{
- {1, ui::INPUT_DEVICE_INTERNAL, "internal keyboard"},
- {2, ui::INPUT_DEVICE_USB, "external keyboard"}});
+ device_data_manager_test_api_.SetKeyboardDevices(
+ std::vector<ui::InputDevice>{internal_kbd, external_generic_kbd});
EXPECT_TRUE(HasInternalSearchKey());
EXPECT_TRUE(HasCapsLock());
EXPECT_TRUE(HasExternalMetaKey());
EXPECT_FALSE(HasAppleCommandKey());
EXPECT_FALSE(HasAssistantKey());
+ // However when connecting external ChromeOS-branded keyboard, we should not
+ // see neither CapsLock not meta keys.
+ device_data_manager_test_api_.SetKeyboardDevices(
+ std::vector<ui::InputDevice>{internal_kbd, external_chromeos_kbd});
+ EXPECT_TRUE(HasInternalSearchKey());
+ EXPECT_FALSE(HasCapsLock());
+ EXPECT_FALSE(HasExternalMetaKey());
+ EXPECT_FALSE(HasAppleCommandKey());
+ EXPECT_FALSE(HasAssistantKey());
+
// Simulate an external Apple keyboard being connected. Now users can remap
// the command key.
- device_data_manager_test_api_.SetKeyboardDevices(std::vector<ui::InputDevice>{
- {1, ui::INPUT_DEVICE_INTERNAL, "internal keyboard"},
- {3, ui::INPUT_DEVICE_USB, "Apple Inc. Apple Keyboard"}});
+ device_data_manager_test_api_.SetKeyboardDevices(
+ std::vector<ui::InputDevice>{internal_kbd, external_apple_kbd});
EXPECT_TRUE(HasInternalSearchKey());
EXPECT_TRUE(HasCapsLock());
EXPECT_FALSE(HasExternalMetaKey());
@@ -228,9 +272,8 @@ TEST_F(KeyboardHandlerTest, ExternalKeyboard) {
// Simulate two external keyboards (Apple and non-Apple) are connected at the
// same time.
- device_data_manager_test_api_.SetKeyboardDevices(std::vector<ui::InputDevice>{
- {2, ui::INPUT_DEVICE_USB, "external keyboard"},
- {3, ui::INPUT_DEVICE_USB, "Apple Inc. Apple Keyboard"}});
+ device_data_manager_test_api_.SetKeyboardDevices(
+ std::vector<ui::InputDevice>{external_generic_kbd, external_apple_kbd});
EXPECT_FALSE(HasInternalSearchKey());
EXPECT_TRUE(HasCapsLock());
EXPECT_TRUE(HasExternalMetaKey());
@@ -242,7 +285,8 @@ TEST_F(KeyboardHandlerTest, ExternalKeyboard) {
// should show the capslock and external meta remapping.
// https://crbug.com/834594.
device_data_manager_test_api_.SetKeyboardDevices(std::vector<ui::InputDevice>{
- {4, ui::INPUT_DEVICE_USB, "Topre Corporation Realforce 87"}});
+ {5, ui::INPUT_DEVICE_USB, "Topre Corporation Realforce 87", "",
+ external_generic_kbd.sys_path, 0x046d, 0xc31c, 0x0111}});
EXPECT_FALSE(HasInternalSearchKey());
EXPECT_TRUE(HasCapsLock());
EXPECT_TRUE(HasExternalMetaKey());
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc
index 1906a330cd5..a5c66d6f18f 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc
@@ -79,11 +79,34 @@ int PowerSourceToDisplayId(
} // namespace
+PowerHandler::IdleBehaviorInfo::IdleBehaviorInfo() = default;
+PowerHandler::IdleBehaviorInfo::~IdleBehaviorInfo() = default;
+
+PowerHandler::IdleBehaviorInfo::IdleBehaviorInfo(
+ const std::set<PowerHandler::IdleBehavior>& possible_behaviors,
+ const PowerHandler::IdleBehavior& current_behavior,
+ const bool is_managed)
+ : possible_behaviors(possible_behaviors),
+ current_behavior(current_behavior),
+ is_managed(is_managed) {}
+
+PowerHandler::IdleBehaviorInfo::IdleBehaviorInfo(const IdleBehaviorInfo& o) =
+ default;
+
const char PowerHandler::kPowerManagementSettingsChangedName[] =
"power-management-settings-changed";
-const char PowerHandler::kIdleBehaviorKey[] = "idleBehavior";
-const char PowerHandler::kIdleControlledKey[] = "idleControlled";
+
+const char PowerHandler::kPossibleAcIdleBehaviorsKey[] =
+ "possibleAcIdleBehaviors";
+const char PowerHandler::kPossibleBatteryIdleBehaviorsKey[] =
+ "possibleBatteryIdleBehaviors";
+const char PowerHandler::kCurrentAcIdleBehaviorKey[] = "currentAcIdleBehavior";
+const char PowerHandler::kCurrentBatteryIdleBehaviorKey[] =
+ "currentBatteryIdleBehavior";
const char PowerHandler::kLidClosedBehaviorKey[] = "lidClosedBehavior";
+const char PowerHandler::kAcIdleManagedKey[] = "acIdleManaged";
+const char PowerHandler::kBatteryIdleManagedKey[] = "batteryIdleManaged";
+
const char PowerHandler::kLidClosedControlledKey[] = "lidClosedControlled";
const char PowerHandler::kHasLidKey[] = "hasLid";
@@ -96,9 +119,11 @@ void PowerHandler::TestAPI::RequestPowerManagementSettings() {
handler_->HandleRequestPowerManagementSettings(&args);
}
-void PowerHandler::TestAPI::SetIdleBehavior(IdleBehavior behavior) {
+void PowerHandler::TestAPI::SetIdleBehavior(IdleBehavior behavior,
+ bool when_on_ac) {
base::ListValue args;
args.AppendInteger(static_cast<int>(behavior));
+ args.AppendBoolean(when_on_ac);
handler_->HandleSetIdleBehavior(&args);
}
@@ -205,49 +230,48 @@ void PowerHandler::HandleSetIdleBehavior(const base::ListValue* args) {
AllowJavascript();
int value = 0;
+ bool when_on_ac = true;
CHECK(args->GetInteger(0, &value));
+ CHECK(args->GetBoolean(1, &when_on_ac));
+
+ const char* idle_pref = when_on_ac ? ash::prefs::kPowerAcIdleAction
+ : ash::prefs::kPowerBatteryIdleAction;
+ const char* screen_dim_delay_pref =
+ when_on_ac ? ash::prefs::kPowerAcScreenDimDelayMs
+ : ash::prefs::kPowerBatteryScreenDimDelayMs;
+ const char* screen_off_delay_pref =
+ when_on_ac ? ash::prefs::kPowerAcScreenOffDelayMs
+ : ash::prefs::kPowerBatteryScreenOffDelayMs;
+ const char* screen_lock_delay_pref =
+ when_on_ac ? ash::prefs::kPowerAcScreenLockDelayMs
+ : ash::prefs::kPowerBatteryScreenLockDelayMs;
+
switch (static_cast<IdleBehavior>(value)) {
case IdleBehavior::DISPLAY_OFF_SLEEP:
- // The default behavior is to turn the display off and sleep. Clear the
- // prefs so we use the default delays.
- prefs_->ClearPref(ash::prefs::kPowerAcIdleAction);
- prefs_->ClearPref(ash::prefs::kPowerAcScreenDimDelayMs);
- prefs_->ClearPref(ash::prefs::kPowerAcScreenOffDelayMs);
- prefs_->ClearPref(ash::prefs::kPowerAcScreenLockDelayMs);
- prefs_->ClearPref(ash::prefs::kPowerBatteryIdleAction);
- prefs_->ClearPref(ash::prefs::kPowerBatteryScreenDimDelayMs);
- prefs_->ClearPref(ash::prefs::kPowerBatteryScreenOffDelayMs);
- prefs_->ClearPref(ash::prefs::kPowerBatteryScreenLockDelayMs);
+ // The default behavior is to turn the display off and sleep.
+ // Clear the prefs so we use the default delays.
+ prefs_->ClearPref(idle_pref);
+ prefs_->ClearPref(screen_dim_delay_pref);
+ prefs_->ClearPref(screen_off_delay_pref);
+ prefs_->ClearPref(screen_lock_delay_pref);
break;
case IdleBehavior::DISPLAY_OFF:
- // Override idle actions to keep the system awake, but use the default
- // screen delays.
- prefs_->SetInteger(ash::prefs::kPowerAcIdleAction,
- PowerPolicyController::ACTION_DO_NOTHING);
- prefs_->ClearPref(ash::prefs::kPowerAcScreenDimDelayMs);
- prefs_->ClearPref(ash::prefs::kPowerAcScreenOffDelayMs);
- prefs_->ClearPref(ash::prefs::kPowerAcScreenLockDelayMs);
- prefs_->SetInteger(ash::prefs::kPowerBatteryIdleAction,
- PowerPolicyController::ACTION_DO_NOTHING);
- prefs_->ClearPref(ash::prefs::kPowerBatteryScreenDimDelayMs);
- prefs_->ClearPref(ash::prefs::kPowerBatteryScreenOffDelayMs);
- prefs_->ClearPref(ash::prefs::kPowerBatteryScreenLockDelayMs);
+ // Override idle actions to keep the system awake, but use the
+ // default screen delays.
+ prefs_->SetInteger(idle_pref, PowerPolicyController::ACTION_DO_NOTHING);
+ prefs_->ClearPref(screen_dim_delay_pref);
+ prefs_->ClearPref(screen_off_delay_pref);
+ prefs_->ClearPref(screen_lock_delay_pref);
break;
case IdleBehavior::DISPLAY_ON:
- // Override idle actions and set screen delays to 0 in order to disable
- // them (i.e. keep the screen on).
- prefs_->SetInteger(ash::prefs::kPowerAcIdleAction,
- PowerPolicyController::ACTION_DO_NOTHING);
- prefs_->SetInteger(ash::prefs::kPowerAcScreenDimDelayMs, 0);
- prefs_->SetInteger(ash::prefs::kPowerAcScreenOffDelayMs, 0);
- prefs_->SetInteger(ash::prefs::kPowerAcScreenLockDelayMs, 0);
- prefs_->SetInteger(ash::prefs::kPowerBatteryIdleAction,
- PowerPolicyController::ACTION_DO_NOTHING);
- prefs_->SetInteger(ash::prefs::kPowerBatteryScreenDimDelayMs, 0);
- prefs_->SetInteger(ash::prefs::kPowerBatteryScreenOffDelayMs, 0);
- prefs_->SetInteger(ash::prefs::kPowerBatteryScreenLockDelayMs, 0);
+ // Override idle actions and set screen delays to 0 in order to
+ // disable them (i.e. keep the screen on).
+ prefs_->SetInteger(idle_pref, PowerPolicyController::ACTION_DO_NOTHING);
+ prefs_->SetInteger(screen_dim_delay_pref, 0);
+ prefs_->SetInteger(screen_off_delay_pref, 0);
+ prefs_->SetInteger(screen_lock_delay_pref, 0);
break;
- default:
+ case IdleBehavior::OTHER:
NOTREACHED() << "Invalid idle behavior " << value;
}
}
@@ -336,32 +360,10 @@ void PowerHandler::SendPowerSources() {
}
void PowerHandler::SendPowerManagementSettings(bool force) {
- // Infer the idle behavior based on the idle action (determining whether we'll
- // sleep eventually or not) and the AC screen-off delay. Policy can request
- // more-nuanced combinations of AC/battery actions and delays, but we wouldn't
- // be able to display something meaningful in the UI in those cases anyway.
- const PowerPolicyController::Action idle_action =
- static_cast<PowerPolicyController::Action>(
- prefs_->GetInteger(ash::prefs::kPowerAcIdleAction));
- IdleBehavior idle_behavior = IdleBehavior::OTHER;
- if (idle_action == PowerPolicyController::ACTION_SUSPEND) {
- idle_behavior = IdleBehavior::DISPLAY_OFF_SLEEP;
- } else if (idle_action == PowerPolicyController::ACTION_DO_NOTHING) {
- idle_behavior =
- (prefs_->GetInteger(ash::prefs::kPowerAcScreenOffDelayMs) > 0
- ? IdleBehavior::DISPLAY_OFF
- : IdleBehavior::DISPLAY_ON);
- }
-
- const bool idle_controlled =
- prefs_->IsManagedPreference(ash::prefs::kPowerAcIdleAction) ||
- prefs_->IsManagedPreference(ash::prefs::kPowerAcScreenDimDelayMs) ||
- prefs_->IsManagedPreference(ash::prefs::kPowerAcScreenOffDelayMs) ||
- prefs_->IsManagedPreference(ash::prefs::kPowerAcScreenLockDelayMs) ||
- prefs_->IsManagedPreference(ash::prefs::kPowerBatteryIdleAction) ||
- prefs_->IsManagedPreference(ash::prefs::kPowerBatteryScreenDimDelayMs) ||
- prefs_->IsManagedPreference(ash::prefs::kPowerBatteryScreenOffDelayMs) ||
- prefs_->IsManagedPreference(ash::prefs::kPowerBatteryScreenLockDelayMs);
+ const PowerHandler::IdleBehaviorInfo ac_idle_info =
+ GetAllowedIdleBehaviors(PowerSource::kAc);
+ const PowerHandler::IdleBehaviorInfo battery_idle_info =
+ GetAllowedIdleBehaviors(PowerSource::kBattery);
const PowerPolicyController::Action lid_closed_behavior =
static_cast<PowerPolicyController::Action>(
@@ -371,23 +373,37 @@ void PowerHandler::SendPowerManagementSettings(bool force) {
const bool has_lid = lid_state_ != PowerManagerClient::LidState::NOT_PRESENT;
// Don't notify the UI if nothing changed.
- if (!force && idle_behavior == last_idle_behavior_ &&
- idle_controlled == last_idle_controlled_ &&
+ if (!force && ac_idle_info == last_ac_idle_info_ &&
+ battery_idle_info == last_battery_idle_info_ &&
lid_closed_behavior == last_lid_closed_behavior_ &&
lid_closed_controlled == last_lid_closed_controlled_ &&
- has_lid == last_has_lid_)
+ has_lid == last_has_lid_) {
return;
+ }
base::DictionaryValue dict;
- dict.SetInteger(kIdleBehaviorKey, static_cast<int>(idle_behavior));
- dict.SetBoolean(kIdleControlledKey, idle_controlled);
+ base::Value* list = dict.SetKey(kPossibleAcIdleBehaviorsKey,
+ base::Value(base::Value::Type::LIST));
+ for (auto idle_behavior : ac_idle_info.possible_behaviors)
+ list->Append(static_cast<int>(idle_behavior));
+
+ list = dict.SetKey(kPossibleBatteryIdleBehaviorsKey,
+ base::Value(base::Value::Type::LIST));
+ for (auto idle_behavior : battery_idle_info.possible_behaviors)
+ list->Append(static_cast<int>(idle_behavior));
+ dict.SetInteger(kCurrentAcIdleBehaviorKey,
+ static_cast<int>(ac_idle_info.current_behavior));
+ dict.SetInteger(kCurrentBatteryIdleBehaviorKey,
+ static_cast<int>(battery_idle_info.current_behavior));
dict.SetInteger(kLidClosedBehaviorKey, lid_closed_behavior);
+ dict.SetBoolean(kAcIdleManagedKey, ac_idle_info.is_managed);
+ dict.SetBoolean(kBatteryIdleManagedKey, battery_idle_info.is_managed);
dict.SetBoolean(kLidClosedControlledKey, lid_closed_controlled);
dict.SetBoolean(kHasLidKey, has_lid);
FireWebUIListener(kPowerManagementSettingsChangedName, dict);
- last_idle_behavior_ = idle_behavior;
- last_idle_controlled_ = idle_controlled;
+ last_ac_idle_info_ = ac_idle_info;
+ last_battery_idle_info_ = battery_idle_info;
last_lid_closed_behavior_ = lid_closed_behavior;
last_lid_closed_controlled_ = lid_closed_controlled;
last_has_lid_ = has_lid;
@@ -401,5 +417,159 @@ void PowerHandler::OnGotSwitchStates(
SendPowerManagementSettings(false /* force */);
}
+PowerHandler::IdleBehaviorInfo PowerHandler::GetAllowedIdleBehaviors(
+ PowerSource power_source) {
+ const char* idle_pref = power_source == PowerSource::kAc
+ ? ash::prefs::kPowerAcIdleAction
+ : ash::prefs::kPowerBatteryIdleAction;
+ const char* screen_off_delay_pref =
+ power_source == PowerSource::kAc
+ ? ash::prefs::kPowerAcScreenOffDelayMs
+ : ash::prefs::kPowerBatteryScreenOffDelayMs;
+
+ std::set<IdleBehavior> possible_behaviors;
+ IdleBehavior current_idle_behavior;
+
+ // If idle action is managed and set to suspend, only possible idle
+ // behaviour is sleep with display off.
+ if (prefs_->IsManagedPreference(idle_pref) &&
+ prefs_->GetInteger(idle_pref) == PowerPolicyController::ACTION_SUSPEND) {
+ current_idle_behavior = IdleBehavior::DISPLAY_OFF_SLEEP;
+ possible_behaviors.insert(IdleBehavior::DISPLAY_OFF_SLEEP);
+ return IdleBehaviorInfo(possible_behaviors, current_idle_behavior,
+ IsIdleManaged(power_source));
+ }
+
+ // If idle action is managed and set to SHUT_DOWN/STOP_SESSION, only
+ // possible idle behaviour is other.
+ if (prefs_->IsManagedPreference(idle_pref) &&
+ (prefs_->GetInteger(idle_pref) ==
+ PowerPolicyController::ACTION_STOP_SESSION ||
+ prefs_->GetInteger(idle_pref) ==
+ PowerPolicyController::ACTION_SHUT_DOWN)) {
+ current_idle_behavior = IdleBehavior::OTHER;
+ possible_behaviors.insert(IdleBehavior::OTHER);
+ return IdleBehaviorInfo(possible_behaviors, current_idle_behavior,
+ IsIdleManaged(power_source));
+ }
+
+ // Note that after this point |idle_pref| should either be:
+ // 1. Not managed.
+ // 2. Or managed and set to
+ // PowerPolicyController::ACTION_DO_NOTHING.
+ DCHECK(!prefs_->IsManagedPreference(idle_pref) ||
+ (prefs_->GetInteger(idle_pref) ==
+ PowerPolicyController::ACTION_DO_NOTHING));
+
+ // If screen off delay is managed and set to a value greater than 0
+ // and
+ // 1. If idle action is managed and set to DO_NOTHING, only
+ // possible idle behavior is DISPLAY_OFF.
+ // 2. If idle action is not managed then possible idle options
+ // are DiSPLAY_OFF and DISPLAY_OFF_SLEEP
+ if (prefs_->IsManagedPreference(screen_off_delay_pref) &&
+ prefs_->GetInteger(screen_off_delay_pref) > 0) {
+ if (prefs_->IsManagedPreference(idle_pref) &&
+ prefs_->GetInteger(idle_pref) ==
+ PowerPolicyController::ACTION_DO_NOTHING) {
+ current_idle_behavior = IdleBehavior::DISPLAY_OFF;
+ possible_behaviors.insert(IdleBehavior::DISPLAY_OFF);
+ return IdleBehaviorInfo(possible_behaviors, current_idle_behavior,
+ IsIdleManaged(power_source));
+ }
+
+ possible_behaviors.insert(IdleBehavior::DISPLAY_OFF);
+ possible_behaviors.insert(IdleBehavior::DISPLAY_OFF_SLEEP);
+ // Set the current default option based on the current idle action.
+ const PowerPolicyController::Action idle_action =
+ static_cast<PowerPolicyController::Action>(
+ prefs_->GetInteger(idle_pref));
+
+ if (idle_action == PowerPolicyController::ACTION_SUSPEND)
+ current_idle_behavior = IdleBehavior::DISPLAY_OFF_SLEEP;
+ else
+ current_idle_behavior = IdleBehavior::DISPLAY_OFF;
+ return IdleBehaviorInfo(possible_behaviors, current_idle_behavior,
+ IsIdleManaged(power_source));
+ }
+
+ // If idle action is managed and set to DO_NOTHING, and
+ // 1. If screen off delay is also managed (and set to 0), only
+ // possible idle
+ // action is DISPLAY_ON.
+ // 2. If AC screen off delay is not managed, possible idle actions
+ // are DISPLAY_ON && DISPLAY_OFF.
+ if (prefs_->IsManagedPreference(idle_pref) &&
+ prefs_->GetInteger(idle_pref) ==
+ PowerPolicyController::ACTION_DO_NOTHING) {
+ if (prefs_->IsManagedPreference(screen_off_delay_pref)) {
+ // Note that we reach here only when screen off delays are
+ // set by enterprise policy to 0 to prevent display from turning
+ // off.
+ DCHECK(prefs_->GetInteger(screen_off_delay_pref) == 0);
+ current_idle_behavior = IdleBehavior::DISPLAY_ON;
+ possible_behaviors.insert(IdleBehavior::DISPLAY_ON);
+ return IdleBehaviorInfo(possible_behaviors, current_idle_behavior,
+ IsIdleManaged(power_source));
+ }
+ possible_behaviors.insert(IdleBehavior::DISPLAY_ON);
+ possible_behaviors.insert(IdleBehavior::DISPLAY_OFF);
+ // Set the current default option based on the current screen off
+ // delay.
+ current_idle_behavior = prefs_->GetInteger(screen_off_delay_pref) > 0
+ ? IdleBehavior::DISPLAY_OFF
+ : IdleBehavior::DISPLAY_ON;
+ return IdleBehaviorInfo(possible_behaviors, current_idle_behavior,
+ IsIdleManaged(power_source));
+ }
+
+ // Looks like we did not find enterprise policy restricitng the idle
+ // options. So add all three idle options to what user can select
+ // from.
+ possible_behaviors.insert(IdleBehavior::DISPLAY_ON);
+ possible_behaviors.insert(IdleBehavior::DISPLAY_OFF);
+ possible_behaviors.insert(IdleBehavior::DISPLAY_OFF_SLEEP);
+
+ // Infer the idle behavior based on the current idle action
+ // (determining whether we'll sleep eventually or not) and the AC
+ // screen-off delay.
+ const PowerPolicyController::Action idle_action =
+ static_cast<PowerPolicyController::Action>(prefs_->GetInteger(idle_pref));
+
+ if (idle_action == PowerPolicyController::ACTION_SUSPEND) {
+ current_idle_behavior = IdleBehavior::DISPLAY_OFF_SLEEP;
+ } else if (idle_action == PowerPolicyController::ACTION_DO_NOTHING) {
+ current_idle_behavior = (prefs_->GetInteger(screen_off_delay_pref) > 0
+ ? IdleBehavior::DISPLAY_OFF
+ : IdleBehavior::DISPLAY_ON);
+ } else {
+ current_idle_behavior = IdleBehavior::OTHER;
+ possible_behaviors.insert(IdleBehavior::OTHER);
+ }
+
+ return IdleBehaviorInfo(possible_behaviors, current_idle_behavior,
+ IsIdleManaged(power_source));
+}
+
+bool PowerHandler::IsIdleManaged(PowerSource power_source) {
+ switch (power_source) {
+ case PowerSource::kAc:
+ return prefs_->IsManagedPreference(ash::prefs::kPowerAcIdleAction) ||
+ prefs_->IsManagedPreference(
+ ash::prefs::kPowerAcScreenDimDelayMs) ||
+ prefs_->IsManagedPreference(
+ ash::prefs::kPowerAcScreenOffDelayMs) ||
+ prefs_->IsManagedPreference(ash::prefs::kPowerAcScreenLockDelayMs);
+ case PowerSource::kBattery:
+ return prefs_->IsManagedPreference(ash::prefs::kPowerBatteryIdleAction) ||
+ prefs_->IsManagedPreference(
+ ash::prefs::kPowerBatteryScreenDimDelayMs) ||
+ prefs_->IsManagedPreference(
+ ash::prefs::kPowerBatteryScreenOffDelayMs) ||
+ prefs_->IsManagedPreference(
+ ash::prefs::kPowerBatteryScreenLockDelayMs);
+ }
+}
+
} // namespace settings
} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.h
index d55a3944bd5..1d125b0295a 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.h
@@ -6,6 +6,7 @@
#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_POWER_HANDLER_H_
#include <memory>
+#include <set>
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
@@ -22,7 +23,7 @@ class PrefService;
namespace base {
class ListValue;
class TimeTicks;
-}
+} // namespace base
namespace chromeos {
namespace settings {
@@ -43,8 +44,12 @@ class PowerHandler : public ::settings::SettingsPageUIHandler,
// WebUI message name and dictionary keys. Shared with tests.
static const char kPowerManagementSettingsChangedName[];
- static const char kIdleBehaviorKey[];
- static const char kIdleControlledKey[];
+ static const char kPossibleAcIdleBehaviorsKey[];
+ static const char kPossibleBatteryIdleBehaviorsKey[];
+ static const char kAcIdleManagedKey[];
+ static const char kBatteryIdleManagedKey[];
+ static const char kCurrentAcIdleBehaviorKey[];
+ static const char kCurrentBatteryIdleBehaviorKey[];
static const char kLidClosedBehaviorKey[];
static const char kLidClosedControlledKey[];
static const char kHasLidKey[];
@@ -56,7 +61,9 @@ class PowerHandler : public ::settings::SettingsPageUIHandler,
~TestAPI();
void RequestPowerManagementSettings();
- void SetIdleBehavior(IdleBehavior behavior);
+ // Sets AC idle behavior to |behavior| if |when_on_ac| is true. Otherwise
+ // sets battery idle behavior to |behavior|.
+ void SetIdleBehavior(IdleBehavior behavior, bool when_on_ac);
void SetLidClosedBehavior(PowerPolicyController::Action behavior);
private:
@@ -80,6 +87,33 @@ class PowerHandler : public ::settings::SettingsPageUIHandler,
const base::TimeTicks& timestamp) override;
private:
+ enum class PowerSource { kAc, kBattery };
+
+ // Struct holding possible idle behaviors and the current behavior while
+ // charging/when on battery.
+ struct IdleBehaviorInfo {
+ IdleBehaviorInfo();
+ IdleBehaviorInfo(const std::set<IdleBehavior>& possible_behaviors,
+ const IdleBehavior& current_behavior,
+ const bool is_managed);
+
+ IdleBehaviorInfo(const IdleBehaviorInfo& o);
+ ~IdleBehaviorInfo();
+
+ bool operator==(const IdleBehaviorInfo& o) const {
+ return (possible_behaviors == o.possible_behaviors &&
+ current_behavior == o.current_behavior &&
+ is_managed == o.is_managed);
+ }
+
+ // All possible idle behaviors.
+ std::set<IdleBehavior> possible_behaviors;
+ // Current idle behavior.
+ IdleBehavior current_behavior = IdleBehavior::DISPLAY_OFF_SLEEP;
+ // Whether enterpise policy manages idle behavior.
+ bool is_managed = false;
+ };
+
// Handler to request updating the power status.
void HandleUpdatePowerStatus(const base::ListValue* args);
@@ -109,7 +143,16 @@ class PowerHandler : public ::settings::SettingsPageUIHandler,
void OnGotSwitchStates(
base::Optional<PowerManagerClient::SwitchStates> result);
- PrefService* prefs_; // Not owned.
+ // Returns all possible idle behaviors (that a user can choose from) and
+ // current idle behavior based on enterprise policy and other factors when on
+ // |power_source|.
+ IdleBehaviorInfo GetAllowedIdleBehaviors(PowerSource power_source);
+
+ // Returns true if the enterprise policy enforces any settings that can impact
+ // the idle behavior of the device when on |power_source|.
+ bool IsIdleManaged(PowerSource power_source);
+
+ PrefService* const prefs_;
// Used to watch power management prefs for changes so the UI can be notified.
std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;
@@ -123,10 +166,10 @@ class PowerHandler : public ::settings::SettingsPageUIHandler,
// Last values sent by SendPowerManagementSettings(), cached here so
// SendPowerManagementSettings() can avoid spamming the UI after this class
// changes multiple prefs at once.
- IdleBehavior last_idle_behavior_ = IdleBehavior::DISPLAY_OFF_SLEEP;
+ IdleBehaviorInfo last_ac_idle_info_;
+ IdleBehaviorInfo last_battery_idle_info_;
PowerPolicyController::Action last_lid_closed_behavior_ =
PowerPolicyController::ACTION_SUSPEND;
- bool last_idle_controlled_ = false;
bool last_lid_closed_controlled_ = false;
bool last_has_lid_ = true;
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler_browsertest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler_browsertest.cc
index c27e55cb6d4..c928ccd2d75 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler_browsertest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler_browsertest.cc
@@ -2,9 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/ui/webui/settings/chromeos/device_power_handler.h"
-
#include <memory>
+#include <set>
#include <utility>
#include "ash/public/cpp/ash_pref_names.h"
@@ -13,6 +12,7 @@
#include "base/run_loop.h"
#include "base/values.h"
#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/ui/webui/settings/chromeos/device_power_handler.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chromeos/dbus/power/fake_power_manager_client.h"
#include "chromeos/dbus/power/power_policy_controller.h"
@@ -24,8 +24,8 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-using testing::Return;
using testing::_;
+using testing::Return;
namespace chromeos {
namespace settings {
@@ -48,6 +48,34 @@ class TestPowerHandler : public PowerHandler {
class PowerHandlerTest : public InProcessBrowserTest {
protected:
+ struct DevicePowerSettings {
+ // Initialize with initial settings.
+ DevicePowerSettings() {
+ possible_ac_behaviors.insert(
+ PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP);
+ possible_ac_behaviors.insert(PowerHandler::IdleBehavior::DISPLAY_OFF);
+ possible_ac_behaviors.insert(PowerHandler::IdleBehavior::DISPLAY_ON);
+ possible_battery_behaviors.insert(
+ PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP);
+ possible_battery_behaviors.insert(
+ PowerHandler::IdleBehavior::DISPLAY_OFF);
+ possible_battery_behaviors.insert(PowerHandler::IdleBehavior::DISPLAY_ON);
+ }
+
+ std::set<PowerHandler::IdleBehavior> possible_ac_behaviors;
+ std::set<PowerHandler::IdleBehavior> possible_battery_behaviors;
+ PowerHandler::IdleBehavior current_ac_behavior =
+ PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP;
+ PowerHandler::IdleBehavior current_battery_behavior =
+ PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP;
+ bool ac_idle_managed = false;
+ bool battery_idle_managed = false;
+ PowerPolicyController::Action lid_closed_behavior =
+ PowerPolicyController::ACTION_SUSPEND;
+ bool lid_closed_controlled = false;
+ bool has_lid = true;
+ };
+
PowerHandlerTest() = default;
~PowerHandlerTest() override = default;
@@ -99,23 +127,32 @@ class PowerHandlerTest : public InProcessBrowserTest {
return std::string();
}
- // Returns a string for the given settings that can be compared against the
- // output of GetLastSettingsChangedMessage().
- std::string CreateSettingsChangedString(
- PowerHandler::IdleBehavior idle_behavior,
- bool idle_controlled,
- PowerPolicyController::Action lid_closed_behavior,
- bool lid_closed_controlled,
- bool has_lid) {
+ // Returns a string for the given |settings|. Used to verify expected
+ // settings are sent to the UI.
+ std::string ToString(const DevicePowerSettings& settings) {
base::DictionaryValue dict;
- dict.SetInteger(PowerHandler::kIdleBehaviorKey,
- static_cast<int>(idle_behavior));
- dict.SetBoolean(PowerHandler::kIdleControlledKey, idle_controlled);
- dict.SetInteger(PowerHandler::kLidClosedBehaviorKey, lid_closed_behavior);
+ base::Value* list = dict.SetKey(PowerHandler::kPossibleAcIdleBehaviorsKey,
+ base::Value(base::Value::Type::LIST));
+ for (auto idle_behavior : settings.possible_ac_behaviors)
+ list->Append(static_cast<int>(idle_behavior));
+
+ list = dict.SetKey(PowerHandler::kPossibleBatteryIdleBehaviorsKey,
+ base::Value(base::Value::Type::LIST));
+ for (auto idle_behavior : settings.possible_battery_behaviors)
+ list->Append(static_cast<int>(idle_behavior));
+
+ dict.SetInteger(PowerHandler::kCurrentAcIdleBehaviorKey,
+ static_cast<int>(settings.current_ac_behavior));
+ dict.SetInteger(PowerHandler::kCurrentBatteryIdleBehaviorKey,
+ static_cast<int>(settings.current_battery_behavior));
+ dict.SetBoolean(PowerHandler::kAcIdleManagedKey, settings.ac_idle_managed);
+ dict.SetBoolean(PowerHandler::kBatteryIdleManagedKey,
+ settings.battery_idle_managed);
+ dict.SetInteger(PowerHandler::kLidClosedBehaviorKey,
+ settings.lid_closed_behavior);
dict.SetBoolean(PowerHandler::kLidClosedControlledKey,
- lid_closed_controlled);
- dict.SetBoolean(PowerHandler::kHasLidKey, has_lid);
-
+ settings.lid_closed_controlled);
+ dict.SetBoolean(PowerHandler::kHasLidKey, settings.has_lid);
std::string out;
EXPECT_TRUE(base::JSONWriter::Write(dict, &out));
return out;
@@ -129,6 +166,12 @@ class PowerHandlerTest : public InProcessBrowserTest {
return GetPrefs()->GetInteger(name);
}
+ // Trigger power pref managed change.
+ void UpdateChromePolicy(policy::PolicyMap* policy_map) {
+ provider_.UpdateChromePolicy(*policy_map);
+ base::RunLoop().RunUntilIdle();
+ }
+
// Sets a policy update which will cause power pref managed change.
void SetPolicyForPolicyKey(policy::PolicyMap* policy_map,
const std::string& policy_key,
@@ -136,8 +179,7 @@ class PowerHandlerTest : public InProcessBrowserTest {
policy_map->Set(policy_key, policy::POLICY_LEVEL_MANDATORY,
policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
std::move(value), nullptr);
- provider_.UpdateChromePolicy(*policy_map);
- base::RunLoop().RunUntilIdle();
+ UpdateChromePolicy(policy_map);
}
std::unique_ptr<TestPowerHandler> handler_;
@@ -154,155 +196,215 @@ class PowerHandlerTest : public InProcessBrowserTest {
// Verifies that settings are sent to WebUI when requested.
IN_PROC_BROWSER_TEST_F(PowerHandlerTest, SendInitialSettings) {
test_api_->RequestPowerManagementSettings();
- EXPECT_EQ(
- CreateSettingsChangedString(
- PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP,
- false /* idle_controlled */, PowerPolicyController::ACTION_SUSPEND,
- false /* lid_closed_controlled */, true /* has_lid */),
- GetLastSettingsChangedMessage());
+ // Initialized to initial settings.
+ DevicePowerSettings settings;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
}
// Verifies that WebUI receives updated settings when the lid state changes.
IN_PROC_BROWSER_TEST_F(PowerHandlerTest, SendSettingsForLidStateChanges) {
chromeos::FakePowerManagerClient::Get()->SetLidState(
PowerManagerClient::LidState::NOT_PRESENT, base::TimeTicks());
- EXPECT_EQ(
- CreateSettingsChangedString(
- PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP,
- false /* idle_controlled */, PowerPolicyController::ACTION_SUSPEND,
- false /* lid_closed_controlled */, false /* has_lid */),
- GetLastSettingsChangedMessage());
+
+ DevicePowerSettings settings;
+ settings.has_lid = false;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
chromeos::FakePowerManagerClient::Get()->SetLidState(
PowerManagerClient::LidState::OPEN, base::TimeTicks());
- EXPECT_EQ(
- CreateSettingsChangedString(
- PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP,
- false /* idle_controlled */, PowerPolicyController::ACTION_SUSPEND,
- false /* lid_closed_controlled */, true /* has_lid */),
- GetLastSettingsChangedMessage());
+ settings.has_lid = true;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
}
-// Verifies that when various prefs are controlled, the corresponding settings
-// are reported as controlled to WebUI.
+// Verifies that when various prefs are controlled, the corresponding
+// settings are reported as controlled/managed to WebUI.
IN_PROC_BROWSER_TEST_F(PowerHandlerTest, SendSettingsForControlledPrefs) {
policy::PolicyMap policy_map;
- // Making an arbitrary delay pref managed should result in the idle setting
- // being reported as controlled.
+ // Making an arbitrary AC delay pref managed should result in the AC idle
+ // setting being reported as managed.
SetPolicyForPolicyKey(&policy_map, policy::key::kScreenDimDelayAC,
std::make_unique<base::Value>(10000));
- EXPECT_EQ(
- CreateSettingsChangedString(
- PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP,
- true /* idle_controlled */, PowerPolicyController::ACTION_SUSPEND,
- false /* lid_closed_controlled */, true /* has_lid */),
- GetLastSettingsChangedMessage());
+ DevicePowerSettings settings;
+ settings.ac_idle_managed = true;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
+
+ // Ditto for battery delay pref managed.
+ SetPolicyForPolicyKey(&policy_map, policy::key::kScreenDimDelayBattery,
+ std::make_unique<base::Value>(10000));
+ settings.battery_idle_managed = true;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
// Ditto for making the lid action pref managed.
SetPolicyForPolicyKey(
&policy_map, policy::key::kLidCloseAction,
std::make_unique<base::Value>(PowerPolicyController::ACTION_SUSPEND));
- EXPECT_EQ(
- CreateSettingsChangedString(
- PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP,
- true /* idle_controlled */, PowerPolicyController::ACTION_SUSPEND,
- true /* lid_closed_controlled */, true /* has_lid */),
- GetLastSettingsChangedMessage());
+ settings.lid_closed_controlled = true;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
}
-// Verifies that idle-related prefs are distilled into the proper WebUI
-// settings.
+// Verifies that idle-related prefs (when not managed by enterpise policy)
+// are distilled into the proper WebUI settings.
IN_PROC_BROWSER_TEST_F(PowerHandlerTest, SendIdleSettingForPrefChanges) {
- // Set a do-nothing idle action and a nonzero screen-off delay.
+ // Initial power settings.
+ DevicePowerSettings settings;
+ // Set a AC do-nothing idle action and a AC nonzero screen-off delay. User
+ // should see all three options (DISPLAY_ON, DISPLAY_OFF and
+ // DISPLAY_OFF_SLEEP) and the selected setting when on AC should be set to
+ // DISPLAY_OFF.
GetPrefs()->Set(ash::prefs::kPowerAcIdleAction,
base::Value(PowerPolicyController::ACTION_DO_NOTHING));
GetPrefs()->Set(ash::prefs::kPowerAcScreenOffDelayMs, base::Value(10000));
- EXPECT_EQ(CreateSettingsChangedString(PowerHandler::IdleBehavior::DISPLAY_OFF,
- false /* idle_controlled */,
- PowerPolicyController::ACTION_SUSPEND,
- false /* lid_closed_controlled */,
- true /* has_lid */),
- GetLastSettingsChangedMessage());
-
- // Now set the delay to zero and check that the setting goes to "display on".
- GetPrefs()->Set(ash::prefs::kPowerAcScreenOffDelayMs, base::Value(0));
- EXPECT_EQ(CreateSettingsChangedString(PowerHandler::IdleBehavior::DISPLAY_ON,
- false /* idle_controlled */,
- PowerPolicyController::ACTION_SUSPEND,
- false /* lid_closed_controlled */,
- true /* has_lid */),
- GetLastSettingsChangedMessage());
+
+ // Current AC idle behavior should be DISPLAY_OFF.
+ settings.current_ac_behavior = PowerHandler::IdleBehavior::DISPLAY_OFF;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
+
+ // Now set the battery screen off delay to zero along with battery do-nothing
+ // idle action and check that the selected setting goes to "display on" when
+ // on battery.
+ GetPrefs()->Set(ash::prefs::kPowerBatteryIdleAction,
+ base::Value(PowerPolicyController::ACTION_DO_NOTHING));
+ GetPrefs()->Set(ash::prefs::kPowerBatteryScreenOffDelayMs, base::Value(0));
+
+ // Current battery idle behavior should be DISPLAY_ON.
+ settings.current_battery_behavior = PowerHandler::IdleBehavior::DISPLAY_ON;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
// Other idle actions should result in an "other" setting.
GetPrefs()->Set(ash::prefs::kPowerAcIdleAction,
base::Value(PowerPolicyController::ACTION_STOP_SESSION));
- EXPECT_EQ(CreateSettingsChangedString(
- PowerHandler::IdleBehavior::OTHER, false /* idle_controlled */,
- PowerPolicyController::ACTION_SUSPEND,
- false /* lid_closed_controlled */, true /* has_lid */),
- GetLastSettingsChangedMessage());
+ // Current AC idle behavior should be OTHER.
+ settings.current_ac_behavior = PowerHandler::IdleBehavior::OTHER;
+ // Possible AC idle behaviors should include OTHER too.
+ settings.possible_ac_behaviors.insert(PowerHandler::IdleBehavior::OTHER);
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
+}
+
+// Verifies that idle-related prefs when managed by enterpise policy are
+// distilled into the proper WebUI settings.
+IN_PROC_BROWSER_TEST_F(PowerHandlerTest, SendManagedIdleSettingForPrefChanges) {
+ policy::PolicyMap policy_map;
+ // Set Enterpise policy that forces AC idle action to suspend. Only possible
+ // AC idle option visible to the user should be DISPLAY_OFF_SLEEP and the
+ // current should also be set to same.
+ SetPolicyForPolicyKey(&policy_map, policy::key::kIdleActionAC,
+ std::make_unique<base::Value>(
+ chromeos::PowerPolicyController::ACTION_SUSPEND));
+ DevicePowerSettings settings;
+ std::set<PowerHandler::IdleBehavior> behaviors;
+ behaviors.insert(PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP);
+ settings.possible_ac_behaviors = behaviors;
+ settings.ac_idle_managed = true;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
+
+ // Set Enterpise policy that forces battery idle action to Shutdown. Only
+ // possible battery idle option visible to the user then should be OTHER and
+ // the default should also be set to same.
+ SetPolicyForPolicyKey(&policy_map, policy::key::kIdleActionBattery,
+ std::make_unique<base::Value>(
+ chromeos::PowerPolicyController::ACTION_SHUT_DOWN));
+ behaviors.clear();
+ behaviors.insert(PowerHandler::IdleBehavior::OTHER);
+ settings.possible_battery_behaviors = behaviors;
+ settings.current_battery_behavior = PowerHandler::IdleBehavior::OTHER;
+ settings.battery_idle_managed = true;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
+ // Erase battery idle action.
+ policy_map.Erase(policy::key::kIdleActionBattery);
+
+ // Set battery idle action to DO_NOTHING in Enterpise policy. The user then
+ // should not see DISPLAY_OFF_SLEEP in available options.
+ SetPolicyForPolicyKey(
+ &policy_map, policy::key::kIdleActionBattery,
+ std::make_unique<base::Value>(
+ chromeos::PowerPolicyController::ACTION_DO_NOTHING));
+ behaviors.clear();
+ behaviors.insert(PowerHandler::IdleBehavior::DISPLAY_OFF);
+ behaviors.insert(PowerHandler::IdleBehavior::DISPLAY_ON);
+ settings.possible_battery_behaviors = behaviors;
+ settings.current_battery_behavior = PowerHandler::IdleBehavior::DISPLAY_OFF;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
+
+ // Set battery screen delay in Enterprise policy on top of DO_NOTHING idle
+ // action. The user should see only see DISPLAY_OFF as the possible battery
+ // idle action.
+ SetPolicyForPolicyKey(&policy_map, policy::key::kScreenOffDelayBattery,
+ std::make_unique<base::Value>(10000));
+ behaviors.clear();
+ behaviors.insert(PowerHandler::IdleBehavior::DISPLAY_OFF);
+ settings.possible_battery_behaviors = behaviors;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
+
+ // Now stop enforcing battery idle action (to DO_NOTHING) in enterprise
+ // policy. The user should see DISPLAY_OFF and DISPLAY_OFF_SLEEP as
+ // the possible battery idle actions.
+ policy_map.Erase(policy::key::kIdleActionBattery);
+ UpdateChromePolicy(&policy_map);
+ settings.possible_battery_behaviors.insert(
+ PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP);
+ settings.current_battery_behavior =
+ PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
}
// Verifies that the lid-closed pref's value is sent directly to WebUI.
IN_PROC_BROWSER_TEST_F(PowerHandlerTest, SendLidSettingForPrefChanges) {
GetPrefs()->Set(ash::prefs::kPowerLidClosedAction,
base::Value(PowerPolicyController::ACTION_SHUT_DOWN));
- EXPECT_EQ(
- CreateSettingsChangedString(
- PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP,
- false /* idle_controlled */, PowerPolicyController::ACTION_SHUT_DOWN,
- false /* lid_closed_controlled */, true /* has_lid */),
- GetLastSettingsChangedMessage());
+ DevicePowerSettings settings;
+ settings.lid_closed_behavior = PowerPolicyController::ACTION_SHUT_DOWN;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
GetPrefs()->Set(ash::prefs::kPowerLidClosedAction,
base::Value(PowerPolicyController::ACTION_STOP_SESSION));
- EXPECT_EQ(CreateSettingsChangedString(
- PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP,
- false /* idle_controlled */,
- PowerPolicyController::ACTION_STOP_SESSION,
- false /* lid_closed_controlled */, true /* has_lid */),
- GetLastSettingsChangedMessage());
+ settings.lid_closed_behavior = PowerPolicyController::ACTION_STOP_SESSION;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
}
// Verifies that requests from WebUI to update the idle behavior update prefs
// appropriately.
IN_PROC_BROWSER_TEST_F(PowerHandlerTest, SetIdleBehavior) {
- // Request the "Keep display on" setting and check that prefs are set
+ // Request the "Keep display on" AC setting and check that prefs are set
// appropriately.
- test_api_->SetIdleBehavior(PowerHandler::IdleBehavior::DISPLAY_ON);
+ test_api_->SetIdleBehavior(PowerHandler::IdleBehavior::DISPLAY_ON,
+ true /* is_ac */);
EXPECT_EQ(PowerPolicyController::ACTION_DO_NOTHING,
GetIntPref(ash::prefs::kPowerAcIdleAction));
EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerAcScreenDimDelayMs));
EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerAcScreenOffDelayMs));
EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerAcScreenLockDelayMs));
- EXPECT_EQ(PowerPolicyController::ACTION_DO_NOTHING,
- GetIntPref(ash::prefs::kPowerBatteryIdleAction));
- EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerBatteryScreenDimDelayMs));
- EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerBatteryScreenOffDelayMs));
- EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerBatteryScreenLockDelayMs));
+ EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerBatteryIdleAction));
+ EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerBatteryScreenDimDelayMs));
+ EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerBatteryScreenOffDelayMs));
+ EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerBatteryScreenLockDelayMs));
- // "Turn off display" should set the idle prefs but clear the screen
- // delays.
- test_api_->SetIdleBehavior(PowerHandler::IdleBehavior::DISPLAY_OFF);
+ // "Turn off display" battery setting should set the battery idle pref but
+ // clear the battery screen delays.
+ test_api_->SetIdleBehavior(PowerHandler::IdleBehavior::DISPLAY_OFF,
+ false /* is_battery */);
EXPECT_EQ(PowerPolicyController::ACTION_DO_NOTHING,
GetIntPref(ash::prefs::kPowerAcIdleAction));
- EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerAcScreenDimDelayMs));
- EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerAcScreenOffDelayMs));
- EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerAcScreenLockDelayMs));
+ EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerAcScreenDimDelayMs));
+ EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerAcScreenOffDelayMs));
+ EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerAcScreenLockDelayMs));
EXPECT_EQ(PowerPolicyController::ACTION_DO_NOTHING,
GetIntPref(ash::prefs::kPowerBatteryIdleAction));
EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerBatteryScreenDimDelayMs));
EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerBatteryScreenOffDelayMs));
EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerBatteryScreenLockDelayMs));
- // Now switch to the "Keep display on" setting (to set the prefs again) and
- // check that the "Turn off display and sleep" setting clears all the prefs.
- test_api_->SetIdleBehavior(PowerHandler::IdleBehavior::DISPLAY_ON);
- test_api_->SetIdleBehavior(PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP);
- EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerAcIdleAction));
- EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerAcScreenDimDelayMs));
- EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerAcScreenOffDelayMs));
- EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerAcScreenLockDelayMs));
+ // Now switch to the "Keep display on" battery setting (to set the prefs
+ // again) and check that the "Turn off display and sleep" battery setting
+ // clears all the battery prefs.
+ test_api_->SetIdleBehavior(PowerHandler::IdleBehavior::DISPLAY_ON,
+ false /* is_battery */);
+ test_api_->SetIdleBehavior(PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP,
+ false /* is_battery */);
+ EXPECT_EQ(PowerPolicyController::ACTION_DO_NOTHING,
+ GetIntPref(ash::prefs::kPowerAcIdleAction));
+ EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerAcScreenDimDelayMs));
+ EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerAcScreenOffDelayMs));
+ EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerAcScreenLockDelayMs));
EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerBatteryIdleAction));
EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerBatteryScreenDimDelayMs));
EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerBatteryScreenOffDelayMs));
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc
index 0eebb3c1814..128d85cb80b 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc
@@ -6,46 +6,16 @@
#include <algorithm>
#include <limits>
-#include <numeric>
+#include <memory>
#include <string>
+#include <utility>
-#include "base/bind.h"
-#include "base/feature_list.h"
-#include "base/files/file_util.h"
-#include "base/system/sys_info.h"
-#include "base/task/post_task.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/browsing_data/browsing_data_appcache_helper.h"
-#include "chrome/browser/browsing_data/browsing_data_cache_storage_helper.h"
-#include "chrome/browser/browsing_data/browsing_data_cookie_helper.h"
-#include "chrome/browser/browsing_data/browsing_data_database_helper.h"
-#include "chrome/browser/browsing_data/browsing_data_file_system_helper.h"
-#include "chrome/browser/browsing_data/browsing_data_flash_lso_helper.h"
-#include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h"
-#include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h"
-#include "chrome/browser/browsing_data/browsing_data_service_worker_helper.h"
#include "chrome/browser/chromeos/arc/arc_util.h"
-#include "chrome/browser/chromeos/crostini/crostini_features.h"
-#include "chrome/browser/chromeos/crostini/crostini_manager.h"
-#include "chrome/browser/chromeos/crostini/crostini_util.h"
-#include "chrome/browser/chromeos/drive/file_system_util.h"
#include "chrome/browser/chromeos/file_manager/path_util.h"
#include "chrome/browser/platform_util.h"
-#include "chrome/browser/profiles/profile.h"
#include "chrome/grit/generated_resources.h"
-#include "chromeos/cryptohome/cryptohome_util.h"
-#include "chromeos/dbus/cryptohome/cryptohome_client.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/disks/disk.h"
#include "components/arc/arc_features.h"
-#include "components/arc/arc_prefs.h"
-#include "components/arc/arc_service_manager.h"
-#include "components/arc/arc_util.h"
-#include "components/arc/session/arc_bridge_service.h"
-#include "components/browsing_data/content/conditional_cache_counting_helper.h"
-#include "components/user_manager/user_manager.h"
-#include "content/public/browser/browser_context.h"
-#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_ui_data_source.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/text/bytes_formatting.h"
@@ -55,41 +25,43 @@ using chromeos::disks::DiskMountManager;
namespace chromeos {
namespace settings {
-namespace {
-
-void GetSizeStatBlocking(const base::FilePath& mount_path,
- int64_t* total_size,
- int64_t* available_size) {
- int64_t size = base::SysInfo::AmountOfTotalDiskSpace(mount_path);
- if (size >= 0)
- *total_size = size;
- size = base::SysInfo::AmountOfFreeDiskSpace(mount_path);
- if (size >= 0)
- *available_size = size;
-}
-
-// Threshold to show a message indicating space is critically low (512 MB).
-const int64_t kSpaceCriticallyLowBytes = 512 * 1024 * 1024;
-// Threshold to show a message indicating space is low (1 GB).
-const int64_t kSpaceLowBytes = 1 * 1024 * 1024 * 1024;
+namespace {
constexpr char kAndroidEnabled[] = "androidEnabled";
+const char* CalculationTypeToEventName(
+ calculator::SizeCalculator::CalculationType x) {
+ switch (x) {
+ case calculator::SizeCalculator::CalculationType::kSystem:
+ return "storage-system-size-changed";
+ case calculator::SizeCalculator::CalculationType::kInUse:
+ return "storage-size-stat-changed";
+ case calculator::SizeCalculator::CalculationType::kMyFiles:
+ return "storage-my-files-size-changed";
+ case calculator::SizeCalculator::CalculationType::kBrowsingData:
+ return "storage-browsing-data-size-changed";
+ case calculator::SizeCalculator::CalculationType::kAppsExtensions:
+ return "storage-apps-size-changed";
+ case calculator::SizeCalculator::CalculationType::kCrostini:
+ return "storage-crostini-size-changed";
+ case calculator::SizeCalculator::CalculationType::kOtherUsers:
+ return "storage-other-users-size-changed";
+ }
+ NOTREACHED();
+ return "";
+}
+
} // namespace
StorageHandler::StorageHandler(Profile* profile,
content::WebUIDataSource* html_source)
- : browser_cache_size_(-1),
- has_browser_cache_size_(false),
- browser_site_data_size_(-1),
- has_browser_site_data_size_(false),
- updating_downloads_size_(false),
- updating_browsing_data_size_(false),
- updating_android_size_(false),
- updating_crostini_size_(false),
- updating_other_users_size_(false),
- is_android_running_(false),
+ : size_stat_calculator_(profile),
+ my_files_size_calculator_(profile),
+ browsing_data_size_calculator_(profile),
+ apps_size_calculator_(profile),
+ crostini_size_calculator_(profile),
+ other_users_size_calculator_(),
profile_(profile),
source_name_(html_source->GetSource()),
arc_observer_(this),
@@ -101,11 +73,7 @@ StorageHandler::StorageHandler(Profile* profile,
}
StorageHandler::~StorageHandler() {
- DiskMountManager::GetInstance()->RemoveObserver(this);
- arc::ArcServiceManager::Get()
- ->arc_bridge_service()
- ->storage_manager()
- ->RemoveObserver(this);
+ StopObservingEvents();
}
void StorageHandler::RegisterMessages() {
@@ -120,8 +88,8 @@ void StorageHandler::RegisterMessages() {
base::BindRepeating(&StorageHandler::HandleUpdateStorageInfo,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
- "openDownloads", base::BindRepeating(&StorageHandler::HandleOpenDownloads,
- base::Unretained(this)));
+ "openMyFiles", base::BindRepeating(&StorageHandler::HandleOpenMyFiles,
+ base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"openArcStorage",
base::BindRepeating(&StorageHandler::HandleOpenArcStorage,
@@ -136,35 +104,48 @@ void StorageHandler::OnJavascriptAllowed() {
if (base::FeatureList::IsEnabled(arc::kUsbStorageUIFeature))
arc_observer_.Add(arc::ArcSessionManager::Get());
- // Start observing the mojo connection UpdateAndroidSize() relies on. Note
- // that OnConnectionReady() will be called immediately if the connection has
- // already been established.
- arc::ArcServiceManager::Get()
- ->arc_bridge_service()
- ->storage_manager()
- ->AddObserver(this);
-
// Start observing mount/unmount events to update the connected device list.
DiskMountManager::GetInstance()->AddObserver(this);
+
+ // Start observing calculators.
+ size_stat_calculator_.AddObserver(this);
+ my_files_size_calculator_.AddObserver(this);
+ browsing_data_size_calculator_.AddObserver(this);
+ apps_size_calculator_.AddObserver(this);
+ crostini_size_calculator_.AddObserver(this);
+ other_users_size_calculator_.AddObserver(this);
}
void StorageHandler::OnJavascriptDisallowed() {
// Ensure that pending callbacks do not complete and cause JS to be evaluated.
weak_ptr_factory_.InvalidateWeakPtrs();
- // Stop observing mount/unmount events to update the connected device list.
- DiskMountManager::GetInstance()->RemoveObserver(this);
-
- // Stop observing the mojo connection so that OnConnectionReady() and
- // OnConnectionClosed() that use FireWebUIListener() won't be called while JS
- // is disabled.
- arc::ArcServiceManager::Get()
- ->arc_bridge_service()
- ->storage_manager()
- ->RemoveObserver(this);
-
if (base::FeatureList::IsEnabled(arc::kUsbStorageUIFeature))
arc_observer_.Remove(arc::ArcSessionManager::Get());
+
+ StopObservingEvents();
+}
+
+int64_t StorageHandler::RoundByteSize(int64_t bytes) {
+ if (bytes < 0) {
+ NOTREACHED() << "Negative bytes value";
+ return -1;
+ }
+
+ // Subtract one to the original number of bytes.
+ bytes--;
+ // Set all the lower bits to 1.
+ bytes |= bytes >> 1;
+ bytes |= bytes >> 2;
+ bytes |= bytes >> 4;
+ bytes |= bytes >> 8;
+ bytes |= bytes >> 16;
+ bytes |= bytes >> 32;
+ // Add one. The one bit beyond the highest set bit is set to 1. All the lower
+ // bits are set to 0.
+ bytes++;
+
+ return bytes;
}
void StorageHandler::HandleUpdateAndroidEnabled(
@@ -176,20 +157,18 @@ void StorageHandler::HandleUpdateAndroidEnabled(
void StorageHandler::HandleUpdateStorageInfo(const base::ListValue* args) {
AllowJavascript();
- UpdateSizeStat();
- UpdateDownloadsSize();
- UpdateBrowsingDataSize();
- UpdateAndroidRunning();
- UpdateAndroidSize();
- UpdateCrostiniSize();
- UpdateOtherUsersSize();
+ size_stat_calculator_.StartCalculation();
+ my_files_size_calculator_.StartCalculation();
+ browsing_data_size_calculator_.StartCalculation();
+ apps_size_calculator_.StartCalculation();
+ crostini_size_calculator_.StartCalculation();
+ other_users_size_calculator_.StartCalculation();
}
-void StorageHandler::HandleOpenDownloads(
- const base::ListValue* unused_args) {
- const base::FilePath downloads_path =
- file_manager::util::GetDownloadsFolderForProfile(profile_);
- platform_util::OpenItem(profile_, downloads_path, platform_util::OPEN_FOLDER,
+void StorageHandler::HandleOpenMyFiles(const base::ListValue* unused_args) {
+ const base::FilePath my_files_path =
+ file_manager::util::GetMyFilesFolderForProfile(profile_);
+ platform_util::OpenItem(profile_, my_files_path, platform_util::OPEN_FOLDER,
platform_util::OpenOperationCallback());
}
@@ -206,233 +185,6 @@ void StorageHandler::HandleUpdateExternalStorages(
UpdateExternalStorages();
}
-void StorageHandler::UpdateSizeStat() {
- const base::FilePath downloads_path =
- file_manager::util::GetDownloadsFolderForProfile(profile_);
-
- int64_t* total_size = new int64_t(0);
- int64_t* available_size = new int64_t(0);
- base::PostTaskAndReply(
- FROM_HERE,
- {base::ThreadPool(), base::MayBlock(), base::TaskPriority::USER_VISIBLE},
- base::Bind(&GetSizeStatBlocking, downloads_path, total_size,
- available_size),
- base::Bind(&StorageHandler::OnGetSizeStat, weak_ptr_factory_.GetWeakPtr(),
- base::Owned(total_size), base::Owned(available_size)));
-}
-
-void StorageHandler::OnGetSizeStat(int64_t* total_size,
- int64_t* available_size) {
- int64_t used_size = *total_size - *available_size;
- base::DictionaryValue size_stat;
- size_stat.SetString("totalSize", ui::FormatBytes(*total_size));
- size_stat.SetString("availableSize", ui::FormatBytes(*available_size));
- size_stat.SetString("usedSize", ui::FormatBytes(used_size));
- size_stat.SetDouble("usedRatio",
- static_cast<double>(used_size) / *total_size);
- int storage_space_state = STORAGE_SPACE_NORMAL;
- if (*available_size < kSpaceCriticallyLowBytes)
- storage_space_state = STORAGE_SPACE_CRITICALLY_LOW;
- else if (*available_size < kSpaceLowBytes)
- storage_space_state = STORAGE_SPACE_LOW;
- size_stat.SetInteger("spaceState", storage_space_state);
-
- FireWebUIListener("storage-size-stat-changed", size_stat);
-}
-
-void StorageHandler::UpdateDownloadsSize() {
- if (updating_downloads_size_)
- return;
- updating_downloads_size_ = true;
-
- const base::FilePath downloads_path =
- file_manager::util::GetDownloadsFolderForProfile(profile_);
-
- base::PostTaskAndReplyWithResult(
- FROM_HERE,
- {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT},
- base::Bind(&base::ComputeDirectorySize, downloads_path),
- base::Bind(&StorageHandler::OnGetDownloadsSize,
- weak_ptr_factory_.GetWeakPtr()));
-}
-
-void StorageHandler::OnGetDownloadsSize(int64_t size) {
- updating_downloads_size_ = false;
- FireWebUIListener("storage-downloads-size-changed",
- base::Value(ui::FormatBytes(size)));
-}
-
-void StorageHandler::UpdateBrowsingDataSize() {
- if (updating_browsing_data_size_)
- return;
- updating_browsing_data_size_ = true;
-
- has_browser_cache_size_ = false;
- has_browser_site_data_size_ = false;
- // Fetch the size of http cache in browsing data.
- browsing_data::ConditionalCacheCountingHelper::Count(
- content::BrowserContext::GetDefaultStoragePartition(profile_),
- base::Time(), base::Time::Max(),
- base::BindOnce(&StorageHandler::OnGetCacheSize,
- weak_ptr_factory_.GetWeakPtr()));
-
- // Fetch the size of site data in browsing data.
- if (!site_data_size_collector_.get()) {
- content::StoragePartition* storage_partition =
- content::BrowserContext::GetDefaultStoragePartition(profile_);
- site_data_size_collector_ = std::make_unique<SiteDataSizeCollector>(
- storage_partition->GetPath(),
- new BrowsingDataCookieHelper(storage_partition),
- new BrowsingDataDatabaseHelper(profile_),
- new BrowsingDataLocalStorageHelper(profile_),
- new BrowsingDataAppCacheHelper(storage_partition->GetAppCacheService()),
- new BrowsingDataIndexedDBHelper(
- storage_partition->GetIndexedDBContext()),
- BrowsingDataFileSystemHelper::Create(
- storage_partition->GetFileSystemContext()),
- new BrowsingDataServiceWorkerHelper(
- storage_partition->GetServiceWorkerContext()),
- new BrowsingDataCacheStorageHelper(
- storage_partition->GetCacheStorageContext()),
- BrowsingDataFlashLSOHelper::Create(profile_));
- }
- site_data_size_collector_->Fetch(
- base::Bind(&StorageHandler::OnGetBrowsingDataSize,
- weak_ptr_factory_.GetWeakPtr(), true));
-}
-
-void StorageHandler::OnGetCacheSize(bool is_upper_limit, int64_t size) {
- DCHECK(!is_upper_limit);
- OnGetBrowsingDataSize(false, size);
-}
-
-void StorageHandler::OnGetBrowsingDataSize(bool is_site_data, int64_t size) {
- if (is_site_data) {
- has_browser_site_data_size_ = true;
- browser_site_data_size_ = size;
- } else {
- has_browser_cache_size_ = true;
- browser_cache_size_ = size;
- }
- if (has_browser_cache_size_ && has_browser_site_data_size_) {
- base::string16 size_string;
- if (browser_cache_size_ >= 0 && browser_site_data_size_ >= 0) {
- size_string = ui::FormatBytes(
- browser_site_data_size_ + browser_cache_size_);
- } else {
- size_string =
- l10n_util::GetStringUTF16(IDS_SETTINGS_STORAGE_SIZE_UNKNOWN);
- }
- updating_browsing_data_size_ = false;
- FireWebUIListener("storage-browsing-data-size-changed",
- base::Value(size_string));
- }
-}
-
-void StorageHandler::UpdateAndroidRunning() {
- FireWebUIListener("storage-android-running-changed",
- base::Value(is_android_running_));
-}
-
-void StorageHandler::UpdateAndroidSize() {
- if (!is_android_running_)
- return;
-
- if (updating_android_size_)
- return;
- updating_android_size_ = true;
-
- bool success = false;
- auto* arc_storage_manager =
- arc::ArcStorageManager::GetForBrowserContext(profile_);
- if (arc_storage_manager) {
- success = arc_storage_manager->GetApplicationsSize(base::BindOnce(
- &StorageHandler::OnGetAndroidSize, weak_ptr_factory_.GetWeakPtr()));
- }
- if (!success)
- updating_android_size_ = false;
-}
-
-void StorageHandler::OnGetAndroidSize(bool succeeded,
- arc::mojom::ApplicationsSizePtr size) {
- base::string16 size_string;
- if (succeeded) {
- uint64_t total_bytes = size->total_code_bytes + size->total_data_bytes +
- size->total_cache_bytes;
- size_string = ui::FormatBytes(total_bytes);
- } else {
- size_string = l10n_util::GetStringUTF16(IDS_SETTINGS_STORAGE_SIZE_UNKNOWN);
- }
- updating_android_size_ = false;
- FireWebUIListener("storage-android-size-changed", base::Value(size_string));
-}
-
-void StorageHandler::UpdateCrostiniSize() {
- if (!crostini::CrostiniFeatures::Get()->IsEnabled(profile_)) {
- return;
- }
-
- if (updating_crostini_size_)
- return;
- updating_crostini_size_ = true;
-
- crostini::CrostiniManager::GetForProfile(profile_)->ListVmDisks(
- base::BindOnce(&StorageHandler::OnGetCrostiniSize,
- weak_ptr_factory_.GetWeakPtr()));
-}
-
-void StorageHandler::OnGetCrostiniSize(crostini::CrostiniResult result,
- int64_t size) {
- updating_crostini_size_ = false;
- FireWebUIListener("storage-crostini-size-changed",
- base::Value(ui::FormatBytes(size)));
-}
-
-void StorageHandler::UpdateOtherUsersSize() {
- if (updating_other_users_size_)
- return;
- updating_other_users_size_ = true;
-
- other_users_.clear();
- user_sizes_.clear();
- const user_manager::UserList& users =
- user_manager::UserManager::Get()->GetUsers();
- for (auto* user : users) {
- if (user->is_active())
- continue;
- other_users_.push_back(user);
- CryptohomeClient::Get()->GetAccountDiskUsage(
- cryptohome::CreateAccountIdentifierFromAccountId(user->GetAccountId()),
- base::BindOnce(&StorageHandler::OnGetOtherUserSize,
- weak_ptr_factory_.GetWeakPtr()));
- }
- // We should show "0 B" if there is no other user.
- if (other_users_.empty()) {
- updating_other_users_size_ = false;
- FireWebUIListener("storage-other-users-size-changed",
- base::Value(ui::FormatBytes(0)));
- }
-}
-
-void StorageHandler::OnGetOtherUserSize(
- base::Optional<cryptohome::BaseReply> reply) {
- user_sizes_.push_back(cryptohome::AccountDiskUsageReplyToUsageSize(reply));
- if (user_sizes_.size() == other_users_.size()) {
- base::string16 size_string;
- // If all the requests succeed, shows the total bytes in the UI.
- if (std::count(user_sizes_.begin(), user_sizes_.end(), -1) == 0) {
- size_string = ui::FormatBytes(
- std::accumulate(user_sizes_.begin(), user_sizes_.end(), 0LL));
- } else {
- size_string =
- l10n_util::GetStringUTF16(IDS_SETTINGS_STORAGE_SIZE_UNKNOWN);
- }
- updating_other_users_size_ = false;
- FireWebUIListener("storage-other-users-size-changed",
- base::Value(size_string));
- }
-}
-
void StorageHandler::UpdateExternalStorages() {
base::Value devices(base::Value::Type::LIST);
for (const auto& itr : DiskMountManager::GetInstance()->mount_points()) {
@@ -463,19 +215,7 @@ void StorageHandler::UpdateExternalStorages() {
FireWebUIListener("onExternalStoragesUpdated", devices);
}
-void StorageHandler::OnConnectionReady() {
- is_android_running_ = true;
- UpdateAndroidRunning();
- UpdateAndroidSize();
-}
-
-void StorageHandler::OnConnectionClosed() {
- is_android_running_ = false;
- UpdateAndroidRunning();
-}
-
void StorageHandler::OnArcPlayStoreEnabledChanged(bool enabled) {
- FireWebUIListener("storage-android-enabled-changed", base::Value(enabled));
auto update = std::make_unique<base::DictionaryValue>();
update->SetKey(kAndroidEnabled, base::Value(enabled));
content::WebUIDataSource::Update(profile_, source_name_, std::move(update));
@@ -494,6 +234,114 @@ void StorageHandler::OnMountEvent(
UpdateExternalStorages();
}
+void StorageHandler::OnSizeCalculated(
+ const calculator::SizeCalculator::CalculationType& calculation_type,
+ int64_t total_bytes,
+ const base::Optional<int64_t>& available_bytes) {
+ if (available_bytes) {
+ UpdateSizeStat(calculation_type, total_bytes, available_bytes.value());
+ } else {
+ UpdateStorageItem(calculation_type, total_bytes);
+ }
+}
+
+void StorageHandler::StopObservingEvents() {
+ // Stop observing mount/unmount events to update the connected device list.
+ DiskMountManager::GetInstance()->RemoveObserver(this);
+
+ // Stop observing calculators.
+ size_stat_calculator_.RemoveObserver(this);
+ my_files_size_calculator_.RemoveObserver(this);
+ browsing_data_size_calculator_.RemoveObserver(this);
+ apps_size_calculator_.RemoveObserver(this);
+ crostini_size_calculator_.RemoveObserver(this);
+ other_users_size_calculator_.RemoveObserver(this);
+}
+
+void StorageHandler::UpdateStorageItem(
+ const calculator::SizeCalculator::CalculationType& calculation_type,
+ int64_t total_bytes) {
+ // When the system size has been calculated, UpdateSystemSize calls this
+ // method with the calculation type kSystem. This check prevents an infinite
+ // loop.
+ if (calculation_type != calculator::SizeCalculator::CalculationType::kSystem)
+ UpdateSystemSize(calculation_type, total_bytes);
+
+ base::string16 message;
+ if (total_bytes < 0) {
+ message = l10n_util::GetStringUTF16(IDS_SETTINGS_STORAGE_SIZE_UNKNOWN);
+ } else {
+ message = ui::FormatBytes(total_bytes);
+ }
+
+ if (calculation_type ==
+ calculator::SizeCalculator::CalculationType::kOtherUsers) {
+ bool no_other_users = (total_bytes == 0);
+ FireWebUIListener(CalculationTypeToEventName(calculation_type),
+ base::Value(message), base::Value(no_other_users));
+ } else {
+ FireWebUIListener(CalculationTypeToEventName(calculation_type),
+ base::Value(message));
+ }
+}
+
+void StorageHandler::UpdateSizeStat(
+ const calculator::SizeCalculator::CalculationType& calculation_type,
+ int64_t total_bytes,
+ int64_t available_bytes) {
+ int64_t rounded_total_bytes = RoundByteSize(total_bytes);
+ int64_t in_use_total_bytes_ = rounded_total_bytes - available_bytes;
+
+ UpdateSystemSize(calculation_type, in_use_total_bytes_);
+
+ base::DictionaryValue size_stat;
+ size_stat.SetString("availableSize", ui::FormatBytes(available_bytes));
+ size_stat.SetString("usedSize", ui::FormatBytes(in_use_total_bytes_));
+ size_stat.SetDouble("usedRatio", static_cast<double>(in_use_total_bytes_) /
+ rounded_total_bytes);
+ int storage_space_state =
+ static_cast<int>(StorageSpaceState::kStorageSpaceNormal);
+ if (available_bytes < kSpaceCriticallyLowBytes)
+ storage_space_state =
+ static_cast<int>(StorageSpaceState::kStorageSpaceCriticallyLow);
+ else if (available_bytes < kSpaceLowBytes)
+ storage_space_state = static_cast<int>(StorageSpaceState::kStorageSpaceLow);
+ size_stat.SetInteger("spaceState", storage_space_state);
+
+ FireWebUIListener(CalculationTypeToEventName(calculation_type), size_stat);
+}
+
+void StorageHandler::UpdateSystemSize(
+ const calculator::SizeCalculator::CalculationType& calculation_type,
+ int64_t total_bytes) {
+ const int item_index = static_cast<int>(calculation_type);
+ storage_items_total_bytes_[item_index] = total_bytes > 0 ? total_bytes : 0;
+ calculation_state_.set(item_index);
+
+ // Update system size. We only display the total system size when the size of
+ // all categories has been updated. If some size calculations are pending,
+ // return early and wait for all calculations to complete.
+ if (!calculation_state_.all())
+ return;
+
+ int64_t system_bytes = 0;
+ for (int i = 0; i < calculator::SizeCalculator::kCalculationTypeCount; ++i) {
+ int64_t total_bytes_for_current_item = storage_items_total_bytes_[i];
+ // If the storage is in use, add to the system's total storage.
+ if (i ==
+ static_cast<int>(calculator::SizeCalculator::CalculationType::kInUse)) {
+ system_bytes += total_bytes_for_current_item;
+ continue;
+ }
+ // Otherwise, this storage amount counts against the total storage
+ // amount.
+ system_bytes -= total_bytes_for_current_item;
+ }
+
+ OnSizeCalculated(calculator::SizeCalculator::CalculationType::kSystem,
+ system_bytes);
+}
+
bool StorageHandler::IsEligibleForAndroidStorage(std::string source_path) {
// Android's StorageManager volume concept relies on assumption that it is
// local filesystem. Hence, special volumes like DriveFS should not be
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h
index 4c901c9913a..cdd352797a6 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h
@@ -5,25 +5,12 @@
#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_STORAGE_HANDLER_H_
#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_STORAGE_HANDLER_H_
-#include <stdint.h>
-
-#include <memory>
#include <string>
-#include <vector>
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
-#include "base/scoped_observer.h"
-#include "chrome/browser/browsing_data/site_data_size_collector.h"
#include "chrome/browser/chromeos/arc/session/arc_session_manager.h"
+#include "chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.h"
#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
-#include "chromeos/dbus/cryptohome/rpc.pb.h"
#include "chromeos/disks/disk_mount_manager.h"
-#include "components/arc/mojom/storage_manager.mojom.h"
-#include "components/arc/session/connection_observer.h"
-#include "components/arc/storage_manager/arc_storage_manager.h"
-#include "components/user_manager/user.h"
#include "third_party/re2/src/re2/re2.h"
class Profile;
@@ -39,20 +26,25 @@ enum class CrostiniResult;
namespace chromeos {
namespace settings {
-class StorageHandler
- : public ::settings::SettingsPageUIHandler,
- public arc::ConnectionObserver<arc::mojom::StorageManagerInstance>,
- public arc::ArcSessionManager::Observer,
- public chromeos::disks::DiskMountManager::Observer {
- public:
- // Enumeration for device state about remaining space. These values must be
- // kept in sync with settings.StorageSpaceState in JS code.
- enum StorageSpaceState {
- STORAGE_SPACE_NORMAL = 0,
- STORAGE_SPACE_LOW = 1,
- STORAGE_SPACE_CRITICALLY_LOW = 2,
- };
+// Enumeration for device state about remaining space. These values must be
+// kept in sync with settings.StorageSpaceState in JS code.
+enum class StorageSpaceState {
+ kStorageSpaceNormal = 0,
+ kStorageSpaceLow = 1,
+ kStorageSpaceCriticallyLow = 2,
+};
+
+// Threshold to show a message indicating space is critically low (512 MB).
+const int64_t kSpaceCriticallyLowBytes = 512 * 1024 * 1024;
+// Threshold to show a message indicating space is low (1 GB).
+const int64_t kSpaceLowBytes = 1 * 1024 * 1024 * 1024;
+
+class StorageHandler : public ::settings::SettingsPageUIHandler,
+ public arc::ArcSessionManager::Observer,
+ public chromeos::disks::DiskMountManager::Observer,
+ public calculator::SizeCalculator::Observer {
+ public:
StorageHandler(Profile* profile, content::WebUIDataSource* html_source);
~StorageHandler() override;
@@ -61,10 +53,6 @@ class StorageHandler
void OnJavascriptAllowed() override;
void OnJavascriptDisallowed() override;
- // arc::ConnectionObserver<arc::mojom::StorageManagerInstance>:
- void OnConnectionReady() override;
- void OnConnectionClosed() override;
-
// arc::ArcSessionManager::Observer:
void OnArcPlayStoreEnabledChanged(bool enabled) override;
@@ -74,56 +62,42 @@ class StorageHandler
const chromeos::disks::DiskMountManager::MountPointInfo&
mount_info) override;
+ // chromeos::settings::calculator::SizeCalculator::Observer:
+ void OnSizeCalculated(
+ const calculator::SizeCalculator::CalculationType& calculation_type,
+ int64_t total_bytes,
+ const base::Optional<int64_t>& available_bytes = base::nullopt) override;
+
+ // Remove the handler from the list of observers of every observed instances.
+ void StopObservingEvents();
+
+ protected:
+ // Round a given number of bytes up to the next power of 2.
+ // Ex: 14 => 16, 150 => 256.
+ int64_t RoundByteSize(int64_t bytes);
+
private:
// Handlers of JS messages.
void HandleUpdateAndroidEnabled(const base::ListValue* unused_args);
void HandleUpdateStorageInfo(const base::ListValue* unused_args);
- void HandleOpenDownloads(const base::ListValue* unused_args);
+ void HandleOpenMyFiles(const base::ListValue* unused_args);
void HandleOpenArcStorage(const base::ListValue* unused_args);
void HandleUpdateExternalStorages(const base::ListValue* unused_args);
- // Requests updating disk space information.
- void UpdateSizeStat();
-
- // Callback to update the UI about disk space information.
- void OnGetSizeStat(int64_t* total_size, int64_t* available_size);
-
- // Requests updating the size of Downloads directory.
- void UpdateDownloadsSize();
-
- // Callback to update the UI about the size of Downloads directory.
- void OnGetDownloadsSize(int64_t size);
-
- // Requests updating the size of browsing data.
- void UpdateBrowsingDataSize();
-
- // Callback to receive the cache size.
- void OnGetCacheSize(bool is_upper_limit, int64_t size);
-
- // Callback to update the UI about the size of browsing data.
- void OnGetBrowsingDataSize(bool is_site_data, int64_t size);
-
- // Requests updating the flag that hides the Android size UI.
- void UpdateAndroidRunning();
-
- // Requests updating the space size used by Android apps and cache.
- void UpdateAndroidSize();
-
- // Callback to update the UI about Android apps and cache.
- void OnGetAndroidSize(bool succeeded, arc::mojom::ApplicationsSizePtr size);
-
- // Requests updating the space size used by Crostini VMs and their apps and
- // cache.
- void UpdateCrostiniSize();
-
- // Callback to update the UI about Crostini VMs and their apps and cache.
- void OnGetCrostiniSize(crostini::CrostiniResult result, int64_t size);
-
- // Requests updating the total size of other users' data.
- void UpdateOtherUsersSize();
-
- // Callback to save the fetched user sizes and update the UI.
- void OnGetOtherUserSize(base::Optional<cryptohome::BaseReply> reply);
+ // Update storage sizes on the UI.
+ void UpdateStorageItem(
+ const calculator::SizeCalculator::CalculationType& calculation_type,
+ int64_t total_bytes);
+ void UpdateSizeStat(
+ const calculator::SizeCalculator::CalculationType& calculation_type,
+ int64_t total_bytes,
+ int64_t available_bytes);
+
+ // Marks the size of |item| as calculated. When all storage items have been
+ // calculated, then "System" size can be calculated.
+ void UpdateSystemSize(
+ const calculator::SizeCalculator::CalculationType& calculation_type,
+ int64_t total_bytes);
// Updates list of external storages.
void UpdateExternalStorages();
@@ -132,38 +106,21 @@ class StorageHandler
// storage.
bool IsEligibleForAndroidStorage(std::string source_path);
- // Total size of cache data in browsing data.
- int64_t browser_cache_size_;
-
- // True if we have already received the size of http cache.
- bool has_browser_cache_size_;
-
- // Total size of site data in browsing data.
- int64_t browser_site_data_size_;
-
- // True if we have already received the size of site data.
- bool has_browser_site_data_size_;
-
- // Helper to compute the total size of all types of site date.
- std::unique_ptr<SiteDataSizeCollector> site_data_size_collector_;
-
- // The list of other users whose directory sizes will be accumulated as the
- // size of "Other users".
- user_manager::UserList other_users_;
-
- // Fetched sizes of user directories.
- std::vector<int64_t> user_sizes_;
-
- // Flags indicating fetch operations for storage sizes are ongoing.
- bool updating_downloads_size_;
- bool updating_browsing_data_size_;
- bool updating_android_size_;
- bool updating_crostini_size_;
- bool updating_other_users_size_;
-
- // A flag for keeping track of the mojo connection status to the ARC
- // container.
- bool is_android_running_;
+ // Instances calculating the size of each storage items.
+ calculator::SizeStatCalculator size_stat_calculator_;
+ calculator::MyFilesSizeCalculator my_files_size_calculator_;
+ calculator::BrowsingDataSizeCalculator browsing_data_size_calculator_;
+ calculator::AppsSizeCalculator apps_size_calculator_;
+ calculator::CrostiniSizeCalculator crostini_size_calculator_;
+ calculator::OtherUsersSizeCalculator other_users_size_calculator_;
+
+ // Controls if the size of each storage item has been calculated.
+ std::bitset<calculator::SizeCalculator::kCalculationTypeCount>
+ calculation_state_;
+
+ // Keeps track of the size of each storage item.
+ int64_t storage_items_total_bytes_
+ [calculator::SizeCalculator::kCalculationTypeCount] = {0};
Profile* const profile_;
const std::string source_name_;
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler_unittest.cc
new file mode 100644
index 00000000000..57c1ab89f3c
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler_unittest.cc
@@ -0,0 +1,516 @@
+// Copyright 2020 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 <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/files/file.h"
+#include "base/files/file_util.h"
+#include "base/path_service.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/system/sys_info.h"
+#include "chrome/browser/chromeos/arc/session/arc_session_manager.h"
+#include "chrome/browser/chromeos/arc/test/test_arc_session_manager.h"
+#include "chrome/browser/chromeos/file_manager/fake_disk_mount_manager.h"
+#include "chrome/browser/chromeos/file_manager/path_util.h"
+#include "chrome/browser/chromeos/scoped_set_running_on_chromeos_for_testing.h"
+#include "chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator_test_api.h"
+#include "chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/webui_url_constants.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "chrome/test/base/testing_profile_manager.h"
+#include "components/arc/arc_service_manager.h"
+#include "components/arc/test/fake_arc_session.h"
+#include "content/public/browser/web_ui_data_source.h"
+#include "content/public/test/browser_task_environment.h"
+#include "content/public/test/test_web_ui.h"
+#include "storage/browser/file_system/external_mount_points.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/text/bytes_formatting.h"
+
+namespace chromeos {
+namespace settings {
+
+namespace {
+
+const char kLsbRelease[] =
+ "CHROMEOS_RELEASE_NAME=Chrome OS\n"
+ "CHROMEOS_RELEASE_VERSION=1.2.3.4\n";
+
+class TestStorageHandler : public StorageHandler {
+ public:
+ explicit TestStorageHandler(Profile* profile,
+ content::WebUIDataSource* html_source)
+ : StorageHandler(profile, html_source) {}
+
+ // Pull WebUIMessageHandler::set_web_ui() into public so tests can call it.
+ using StorageHandler::RoundByteSize;
+ using StorageHandler::set_web_ui;
+};
+
+class StorageHandlerTest : public testing::Test {
+ public:
+ StorageHandlerTest() = default;
+ ~StorageHandlerTest() override = default;
+
+ void SetUp() override {
+ // The storage handler requires an instance of DiskMountManager,
+ // ArcServiceManager and ArcSessionManager.
+ chromeos::disks::DiskMountManager::InitializeForTesting(
+ new file_manager::FakeDiskMountManager);
+ arc_service_manager_ = std::make_unique<arc::ArcServiceManager>();
+ arc_session_manager_ = arc::CreateTestArcSessionManager(
+ std::make_unique<arc::ArcSessionRunner>(
+ base::BindRepeating(arc::FakeArcSession::Create)));
+
+ // Initialize profile.
+ profile_manager_ = std::make_unique<TestingProfileManager>(
+ TestingBrowserProcess::GetGlobal());
+ ASSERT_TRUE(profile_manager_->SetUp());
+ profile_ = profile_manager_->CreateTestingProfile("p1");
+
+ // Initialize storage handler.
+ content::WebUIDataSource* html_source =
+ content::WebUIDataSource::Create(chrome::kChromeUIOSSettingsHost);
+ handler_ = std::make_unique<TestStorageHandler>(profile_, html_source);
+ handler_->set_web_ui(&web_ui_);
+ handler_->AllowJavascriptForTesting();
+
+ // Initialize tests APIs.
+ size_stat_test_api_ = std::make_unique<calculator::SizeStatTestAPI>(
+ handler_.get(), new calculator::SizeStatCalculator(profile_));
+ my_files_size_test_api_ = std::make_unique<calculator::MyFilesSizeTestAPI>(
+ handler_.get(), new calculator::MyFilesSizeCalculator(profile_));
+ browsing_data_size_test_api_ =
+ std::make_unique<calculator::BrowsingDataSizeTestAPI>(
+ handler_.get(),
+ new calculator::BrowsingDataSizeCalculator(profile_));
+ apps_size_test_api_ = std::make_unique<calculator::AppsSizeTestAPI>(
+ handler_.get(), new calculator::AppsSizeCalculator(profile_));
+ crostini_size_test_api_ = std::make_unique<calculator::CrostiniSizeTestAPI>(
+ handler_.get(), new calculator::CrostiniSizeCalculator(profile_));
+ other_users_size_test_api_ =
+ std::make_unique<calculator::OtherUsersSizeTestAPI>(
+ handler_.get(), new calculator::OtherUsersSizeCalculator());
+
+ // Create and register My files directory.
+ // By emulating chromeos running, GetMyFilesFolderForProfile will return the
+ // profile's temporary location instead of $HOME/Downloads.
+ chromeos::ScopedSetRunningOnChromeOSForTesting fake_release(kLsbRelease,
+ base::Time());
+ const base::FilePath my_files_path =
+ file_manager::util::GetMyFilesFolderForProfile(profile_);
+ CHECK(base::CreateDirectory(my_files_path));
+ CHECK(storage::ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
+ file_manager::util::GetDownloadsMountPointName(profile_),
+ storage::kFileSystemTypeNativeLocal, storage::FileSystemMountOption(),
+ my_files_path));
+ }
+
+ void TearDown() override {
+ handler_.reset();
+ size_stat_test_api_.reset();
+ my_files_size_test_api_.reset();
+ browsing_data_size_test_api_.reset();
+ apps_size_test_api_.reset();
+ crostini_size_test_api_.reset();
+ other_users_size_test_api_.reset();
+ chromeos::disks::DiskMountManager::Shutdown();
+ storage::ExternalMountPoints::GetSystemInstance()->RevokeAllFileSystems();
+ }
+
+ protected:
+ // From a given amount of total size and available size as input, returns the
+ // space state determined by the OnGetSizeState function.
+ int GetSpaceState(int64_t* total_size, int64_t* available_size) {
+ size_stat_test_api_->SimulateOnGetSizeStat(total_size, available_size);
+ task_environment_.RunUntilIdle();
+ const base::Value* dictionary =
+ GetWebUICallbackMessage("storage-size-stat-changed");
+ EXPECT_TRUE(dictionary) << "No 'storage-size-stat-changed' callback";
+ int space_state = dictionary->FindKey("spaceState")->GetInt();
+ return space_state;
+ }
+
+ // Expects a callback message with a given |event_name|. A non null
+ // base::Value is returned if the callback message is found and has associated
+ // data.
+ const base::Value* GetWebUICallbackMessage(const std::string& event_name) {
+ for (auto it = web_ui_.call_data().rbegin();
+ it != web_ui_.call_data().rend(); ++it) {
+ const content::TestWebUI::CallData* data = it->get();
+ std::string name;
+ if (data->function_name() != "cr.webUIListenerCallback" ||
+ !data->arg1()->GetAsString(&name)) {
+ continue;
+ }
+ if (name == event_name)
+ return data->arg2();
+ }
+ return nullptr;
+ }
+
+ // Get the path to file manager's test data directory.
+ base::FilePath GetTestDataFilePath(const std::string& file_name) {
+ // Get the path to file manager's test data directory.
+ base::FilePath source_dir;
+ CHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &source_dir));
+ base::FilePath test_data_dir = source_dir.AppendASCII("chrome")
+ .AppendASCII("test")
+ .AppendASCII("data")
+ .AppendASCII("chromeos")
+ .AppendASCII("file_manager");
+
+ // Return full test data path to the given |file_name|.
+ return test_data_dir.Append(base::FilePath::FromUTF8Unsafe(file_name));
+ }
+
+ // Copy a file from the file manager's test data directory to the specified
+ // target_path.
+ void AddFile(const std::string& file_name,
+ int64_t expected_size,
+ base::FilePath target_path) {
+ const base::FilePath entry_path = GetTestDataFilePath(file_name);
+ target_path = target_path.AppendASCII(file_name);
+ ASSERT_TRUE(base::CopyFile(entry_path, target_path))
+ << "Copy from " << entry_path.value() << " to " << target_path.value()
+ << " failed.";
+ // Verify file size.
+ base::stat_wrapper_t stat;
+ const int res = base::File::Lstat(target_path.value().c_str(), &stat);
+ ASSERT_FALSE(res < 0) << "Couldn't stat" << target_path.value();
+ ASSERT_EQ(expected_size, stat.st_size);
+ }
+
+ std::unique_ptr<TestStorageHandler> handler_;
+ content::TestWebUI web_ui_;
+ content::BrowserTaskEnvironment task_environment_;
+ std::unique_ptr<TestingProfileManager> profile_manager_;
+ Profile* profile_;
+ std::unique_ptr<calculator::SizeStatTestAPI> size_stat_test_api_;
+ std::unique_ptr<calculator::MyFilesSizeTestAPI> my_files_size_test_api_;
+ std::unique_ptr<calculator::BrowsingDataSizeTestAPI>
+ browsing_data_size_test_api_;
+ std::unique_ptr<calculator::AppsSizeTestAPI> apps_size_test_api_;
+ std::unique_ptr<calculator::CrostiniSizeTestAPI> crostini_size_test_api_;
+ std::unique_ptr<calculator::OtherUsersSizeTestAPI> other_users_size_test_api_;
+
+ private:
+ std::unique_ptr<arc::ArcServiceManager> arc_service_manager_;
+ std::unique_ptr<arc::ArcSessionManager> arc_session_manager_;
+ DISALLOW_COPY_AND_ASSIGN(StorageHandlerTest);
+};
+
+TEST_F(StorageHandlerTest, RoundByteSize) {
+ static const struct {
+ int64_t bytes;
+ const char* expected;
+ } cases[] = {
+ {0, "0 B"},
+ {3, "4 B"},
+ {4, "4 B"},
+ {5, "8 B"},
+ {8 * 1024 - 1, "8.0 KB"},
+ {8 * 1024, "8.0 KB"},
+ {8 * 1024 + 1, "16.0 KB"},
+ {31 * 1024 * 1024, "32.0 MB"},
+ {32 * 1024 * 1024, "32.0 MB"},
+ {50 * 1024 * 1024, "64.0 MB"},
+ {65LL * 1024 * 1024 * 1024, "128 GB"},
+ {130LL * 1024 * 1024 * 1024, "256 GB"},
+ {130LL * 1024 * 1024 * 1024, "256 GB"},
+ {1LL * 1024 * 1024 * 1024 * 1024, "1.0 TB"},
+ {1LL * 1024 * 1024 * 1024 * 1024 + 1, "2.0 TB"},
+ {(1LL << 61) + 1, "4,096 PB"},
+ };
+
+ for (auto& c : cases) {
+ int64_t rounded_bytes = handler_->RoundByteSize(c.bytes);
+ EXPECT_EQ(base::ASCIIToUTF16(c.expected), ui::FormatBytes(rounded_bytes));
+ }
+}
+
+TEST_F(StorageHandlerTest, GlobalSizeStat) {
+ // Get local filesystem storage statistics.
+ const base::FilePath mount_path =
+ file_manager::util::GetMyFilesFolderForProfile(profile_);
+ int64_t total_size = base::SysInfo::AmountOfTotalDiskSpace(mount_path);
+ int64_t available_size = base::SysInfo::AmountOfFreeDiskSpace(mount_path);
+
+ // Round the total size.
+ int64_t rounded_total_size = handler_->RoundByteSize(total_size);
+ int64_t used_size = rounded_total_size - available_size;
+ double used_ratio = static_cast<double>(used_size) / rounded_total_size;
+
+ // Get statistics from storage handler's UpdateSizeStat.
+ size_stat_test_api_->StartCalculation();
+ task_environment_.RunUntilIdle();
+
+ const base::Value* dictionary =
+ GetWebUICallbackMessage("storage-size-stat-changed");
+ ASSERT_TRUE(dictionary) << "No 'storage-size-stat-changed' callback";
+
+ const std::string& storage_handler_available_size =
+ dictionary->FindKey("availableSize")->GetString();
+ const std::string& storage_handler_used_size =
+ dictionary->FindKey("usedSize")->GetString();
+ double storage_handler_used_ratio =
+ dictionary->FindKey("usedRatio")->GetDouble();
+
+ EXPECT_EQ(ui::FormatBytes(available_size),
+ base::ASCIIToUTF16(storage_handler_available_size));
+ EXPECT_EQ(ui::FormatBytes(used_size),
+ base::ASCIIToUTF16(storage_handler_used_size));
+ double diff = used_ratio > storage_handler_used_ratio
+ ? used_ratio - storage_handler_used_ratio
+ : storage_handler_used_ratio - used_ratio;
+ // Running the test while writing data on disk (~400MB/s), the difference
+ // between the values returned by the two AmountOfFreeDiskSpace calls is never
+ // more than 100KB. By expecting diff to be less than 100KB /
+ // rounded_total_size, the test is very unlikely to be flaky.
+ EXPECT_LE(diff, static_cast<double>(100 * 1024) / rounded_total_size);
+}
+
+TEST_F(StorageHandlerTest, StorageSpaceState) {
+ // Less than 512 MB available, space state is critically low.
+ int64_t total_size = 1024 * 1024 * 1024;
+ int64_t available_size = 512 * 1024 * 1024 - 1;
+ int space_state = GetSpaceState(&total_size, &available_size);
+ EXPECT_EQ(static_cast<int>(StorageSpaceState::kStorageSpaceCriticallyLow),
+ space_state);
+
+ // Less than 1GB available, space state is low.
+ available_size = 512 * 1024 * 1024;
+ space_state = GetSpaceState(&total_size, &available_size);
+ EXPECT_EQ(static_cast<int>(StorageSpaceState::kStorageSpaceLow), space_state);
+ available_size = 1024 * 1024 * 1024 - 1;
+ space_state = GetSpaceState(&total_size, &available_size);
+ EXPECT_EQ(static_cast<int>(StorageSpaceState::kStorageSpaceLow), space_state);
+
+ // From 1GB, normal space state.
+ available_size = 1024 * 1024 * 1024;
+ space_state = GetSpaceState(&total_size, &available_size);
+ EXPECT_EQ(static_cast<int>(StorageSpaceState::kStorageSpaceNormal),
+ space_state);
+}
+
+TEST_F(StorageHandlerTest, MyFilesSize) {
+ base::ScopedAllowBlockingForTesting allow_blocking;
+
+ const base::FilePath my_files_path =
+ file_manager::util::GetMyFilesFolderForProfile(profile_);
+ const base::FilePath downloads_path =
+ file_manager::util::GetDownloadsFolderForProfile(profile_);
+ const base::FilePath android_files_path =
+ profile_->GetPath().Append("AndroidFiles");
+ const base::FilePath android_files_download_path =
+ android_files_path.Append("Download");
+
+ // Create directories.
+ CHECK(base::CreateDirectory(downloads_path));
+ CHECK(base::CreateDirectory(android_files_path));
+ CHECK(base::CreateDirectory(android_files_download_path));
+
+ // Register android files mount point.
+ CHECK(storage::ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
+ file_manager::util::GetAndroidFilesMountPointName(),
+ storage::kFileSystemTypeNativeLocal, storage::FileSystemMountOption(),
+ android_files_path));
+
+ // Add files in My files and android files.
+ AddFile("random.bin", 8092, my_files_path); // ~7.9 KB
+ AddFile("tall.pdf", 15271, android_files_path); // ~14.9 KB
+ // Add file in Downloads and simulate bind mount with
+ // [android files]/Download.
+ AddFile("video.ogv", 59943, downloads_path); // ~58.6 KB
+ AddFile("video.ogv", 59943, android_files_download_path);
+
+ // Calculate My files size.
+ my_files_size_test_api_->StartCalculation();
+ task_environment_.RunUntilIdle();
+
+ const base::Value* callback =
+ GetWebUICallbackMessage("storage-my-files-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-my-files-size-changed' callback";
+
+ // Check return value.
+ EXPECT_EQ("81.4 KB", callback->GetString());
+}
+
+TEST_F(StorageHandlerTest, AppsExtensionsSize) {
+ // The data for apps and extensions apps_size_test_api_installed from the
+ // webstore is stored in the Extensions folder. Add data at a random location
+ // in the Extensions folder and check UI callback message.
+ const base::FilePath extensions_data_path =
+ profile_->GetPath()
+ .AppendASCII("Extensions")
+ .AppendASCII("fake_extension_id");
+ CHECK(base::CreateDirectory(extensions_data_path));
+ AddFile("id3Audio.mp3", 180999, extensions_data_path); // ~177 KB
+
+ // Calculate web store apps and extensions size.
+ apps_size_test_api_->StartCalculation();
+ task_environment_.RunUntilIdle();
+
+ const base::Value* callback =
+ GetWebUICallbackMessage("storage-apps-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-apps-size-changed' callback";
+
+ // Check return value.
+ EXPECT_EQ("177 KB", callback->GetString());
+
+ // Simulate android apps size callback.
+ // 592840 + 25284 + 9987 = 628111 ~613 KB.
+ apps_size_test_api_->SimulateOnGetAndroidAppsSize(true /* succeeded */,
+ 592840, 25284, 9987);
+ task_environment_.RunUntilIdle();
+
+ callback = GetWebUICallbackMessage("storage-apps-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-apps-size-changed' callback";
+
+ // Check return value.
+ EXPECT_EQ("790 KB", callback->GetString());
+
+ // Add more data in the Extensions folder. Android is not running and the size
+ // of android apps is back down to 0 B.
+ AddFile("video_long.ogv", 230096, extensions_data_path); // ~225 KB
+
+ // Calculate web store apps and extensions size.
+ apps_size_test_api_->StartCalculation();
+ task_environment_.RunUntilIdle();
+
+ callback = GetWebUICallbackMessage("storage-apps-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-apps-size-changed' callback";
+
+ // Check return value.
+ EXPECT_EQ("401 KB", callback->GetString());
+}
+
+TEST_F(StorageHandlerTest, SystemSize) {
+ // The "System" row on the storage page displays the difference between the
+ // total amount of used space and the sum of the sizes of the different
+ // storage items of the storage page (My files, Browsing data, apps etc...)
+ // This test simulates callbacks from each one of these storage items; the
+ // calculation of the "System" size should only happen when all of the other
+ // storage items have been calculated.
+ const int64_t KB = 1024;
+ const int64_t MB = 1024 * KB;
+ const int64_t GB = 1024 * MB;
+ const int64_t TB = 1024 * GB;
+
+ // Simulate size stat callback.
+ int64_t total_size = TB;
+ int64_t available_size = 100 * GB;
+ size_stat_test_api_->SimulateOnGetSizeStat(&total_size, &available_size);
+ const base::Value* callback =
+ GetWebUICallbackMessage("storage-size-stat-changed");
+ ASSERT_TRUE(callback) << "No 'storage-size-stat-changed' callback";
+ EXPECT_EQ("100 GB", callback->FindKey("availableSize")->GetString());
+ EXPECT_EQ("924 GB", callback->FindKey("usedSize")->GetString());
+ // Expect no system size callback until every other item has been updated.
+ ASSERT_FALSE(GetWebUICallbackMessage("storage-system-size-changed"));
+
+ // Simulate my files size callback.
+ my_files_size_test_api_->SimulateOnGetTotalBytes(400 * GB);
+ callback = GetWebUICallbackMessage("storage-my-files-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-my-files-size-changed' callback";
+ EXPECT_EQ("400 GB", callback->GetString());
+ ASSERT_FALSE(GetWebUICallbackMessage("storage-system-size-changed"));
+
+ // Simulate browsing data callbacks. Has to be called with
+ // both |is_data_site| = true and false.
+ browsing_data_size_test_api_->SimulateOnGetBrowsingDataSize(
+ true /* is_site_data */, 10 * GB);
+ ASSERT_FALSE(GetWebUICallbackMessage("storage-browsing-data-size-changed"));
+ ASSERT_FALSE(GetWebUICallbackMessage("storage-system-size-changed"));
+ browsing_data_size_test_api_->SimulateOnGetBrowsingDataSize(
+ false /* is_site_data */, 14 * GB);
+ callback = GetWebUICallbackMessage("storage-browsing-data-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-browsing-data-size-changed' callback";
+ EXPECT_EQ("24.0 GB", callback->GetString());
+ ASSERT_FALSE(GetWebUICallbackMessage("storage-system-size-changed"));
+
+ // Simulate apps and extensions size callbacks.
+ apps_size_test_api_->SimulateOnGetAppsSize(29 * GB);
+ apps_size_test_api_->SimulateOnGetAndroidAppsSize(false, 0, 0, 0);
+ callback = GetWebUICallbackMessage("storage-apps-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-apps-size-changed' callback";
+ EXPECT_EQ("29.0 GB", callback->GetString());
+ ASSERT_FALSE(GetWebUICallbackMessage("storage-system-size-changed"));
+ apps_size_test_api_->SimulateOnGetAndroidAppsSize(
+ true /* succeeded */, 724 * MB, 100 * MB, 200 * MB);
+ callback = GetWebUICallbackMessage("storage-apps-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-apps-size-changed' callback";
+ EXPECT_EQ("30.0 GB", callback->GetString());
+ ASSERT_FALSE(GetWebUICallbackMessage("storage-system-size-changed"));
+
+ // Simulate crostini size callback.
+ crostini_size_test_api_->SimulateOnGetCrostiniSize(70 * GB);
+ callback = GetWebUICallbackMessage("storage-crostini-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-crostini-size-changed' callback";
+ EXPECT_EQ("70.0 GB", callback->GetString());
+ ASSERT_FALSE(GetWebUICallbackMessage("storage-system-size-changed"));
+
+ // Simulate other users size callback. No callback message until the sizes of
+ // every users is calculated.
+ std::vector<int64_t> other_user_sizes =
+ std::vector<int64_t>{200 * GB, 50 * GB, 50 * GB};
+ other_users_size_test_api_->InitializeOtherUserSize(other_user_sizes.size());
+ for (std::size_t i = 0; i < other_user_sizes.size(); i++) {
+ cryptohome::BaseReply result;
+ result.set_error(cryptohome::CRYPTOHOME_ERROR_NOT_SET);
+ cryptohome::GetAccountDiskUsageReply* usage_reply =
+ result.MutableExtension(cryptohome::GetAccountDiskUsageReply::reply);
+ usage_reply->set_size(other_user_sizes[i]);
+ base::Optional<cryptohome::BaseReply> reply = std::move(result);
+ other_users_size_test_api_->SimulateOnGetOtherUserSize(reply);
+ if (i < other_user_sizes.size() - 1) {
+ ASSERT_FALSE(GetWebUICallbackMessage("storage-other-users-size-changed"));
+ ASSERT_FALSE(GetWebUICallbackMessage("storage-system-size-changed"));
+ } else {
+ // When the size of the last user's cryptohome is calculated, we expect a
+ // callback with the "Other users" size.
+ callback = GetWebUICallbackMessage("storage-other-users-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-other-users-size-changed' callback";
+ EXPECT_EQ("300 GB", callback->GetString());
+ // Every item size has been calculated, system size should also be
+ // updated.
+ callback = GetWebUICallbackMessage("storage-system-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-system-size-changed' callback";
+ EXPECT_EQ("100 GB", callback->GetString());
+ }
+ }
+
+ // If there's an error while calculating the size of browsing data, the size
+ // of browsing data and system should be displayed as "Unknown".
+ browsing_data_size_test_api_->SimulateOnGetBrowsingDataSize(
+ true /* is_site_data */, -1);
+ callback = GetWebUICallbackMessage("storage-browsing-data-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-browsing-data-size-changed' callback";
+ EXPECT_EQ("Unknown", callback->GetString());
+ // The missing 24.0 GB of browsing data should be reflected in the system
+ // section instead. We expect the displayed size to be 100 + 24 GB.
+ callback = GetWebUICallbackMessage("storage-system-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-system-size-changed' callback";
+ EXPECT_EQ("124 GB", callback->GetString());
+
+ // No error while recalculating browsing data size, the UI should be updated
+ // with the right sizes.
+ browsing_data_size_test_api_->SimulateOnGetBrowsingDataSize(
+ true /* is_site_data */, 10 * GB);
+ callback = GetWebUICallbackMessage("storage-browsing-data-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-browsing-data-size-changed' callback";
+ EXPECT_EQ("24.0 GB", callback->GetString());
+ callback = GetWebUICallbackMessage("storage-system-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-system-size-changed' callback";
+ EXPECT_EQ("100 GB", callback->GetString());
+}
+
+} // namespace
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.cc
index 601eeaf2435..0a90a0e3039 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.cc
@@ -20,9 +20,7 @@
#include "chrome/common/pref_names.h"
#include "chrome/grit/generated_resources.h"
#include "components/prefs/pref_service.h"
-#include "content/public/browser/system_connector.h"
-#include "services/device/public/mojom/constants.mojom.h"
-#include "services/service_manager/public/cpp/connector.h"
+#include "content/public/browser/device_service.h"
#include "ui/base/l10n/l10n_util.h"
using session_manager::SessionManager;
@@ -57,8 +55,8 @@ std::unique_ptr<base::DictionaryValue> GetFingerprintsInfo(
} // namespace
FingerprintHandler::FingerprintHandler(Profile* profile) : profile_(profile) {
- content::GetSystemConnector()->Connect(
- device::mojom::kServiceName, fp_service_.BindNewPipeAndPassReceiver());
+ content::GetDeviceService().BindFingerprint(
+ fp_service_.BindNewPipeAndPassReceiver());
user_id_ = ProfileHelper::Get()->GetUserIdHashFromProfile(profile);
}
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/internet_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/internet_handler.cc
index e75796ecd32..bd301cfcb91 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/internet_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/internet_handler.cc
@@ -143,7 +143,8 @@ void InternetHandler::ConfigureThirdPartyVpn(const base::ListValue* args) {
return;
}
if (network->type() != shill::kTypeVPN) {
- NET_LOG(ERROR) << "ConfigureThirdPartyVpn: Network is not a VPN: " << guid;
+ NET_LOG(ERROR) << "ConfigureThirdPartyVpn: Network is not a VPN: "
+ << NetworkId(network);
return;
}
@@ -169,7 +170,8 @@ void InternetHandler::ConfigureThirdPartyVpn(const base::ListValue* args) {
}
NET_LOG(ERROR) << "ConfigureThirdPartyVpn: Unsupported VPN type: "
- << network->GetVpnProviderType() << " For: " << guid;
+ << network->GetVpnProviderType()
+ << " For: " << NetworkId(network);
}
void InternetHandler::RequestGmsCoreNotificationsDisabledDeviceNames(
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/internet_strings_provider.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/internet_strings_provider.cc
new file mode 100644
index 00000000000..90a75cf7418
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/internet_strings_provider.cc
@@ -0,0 +1,252 @@
+// Copyright 2020 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 "chrome/browser/ui/webui/settings/chromeos/internet_strings_provider.h"
+
+#include "ash/public/cpp/network_config_service.h"
+#include "base/bind.h"
+#include "base/no_destructor.h"
+#include "chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.h"
+#include "chrome/browser/ui/webui/webui_util.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/common/webui_url_constants.h"
+#include "chrome/grit/chromium_strings.h"
+#include "chrome/grit/generated_resources.h"
+#include "chromeos/strings/grit/chromeos_strings.h"
+#include "components/strings/grit/components_strings.h"
+#include "content/public/browser/web_ui_data_source.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/webui/web_ui_util.h"
+
+namespace chromeos {
+namespace settings {
+namespace {
+
+const std::vector<SearchConcept>& GetNetworkSearchConcepts() {
+ static const base::NoDestructor<std::vector<SearchConcept>> tags({
+ {IDS_SETTINGS_TAG_NETWORK_SETTINGS,
+ chrome::kNetworksSubPage,
+ mojom::SearchResultIcon::kWifi,
+ {IDS_SETTINGS_TAG_NETWORK_SETTINGS_ALT1, SearchConcept::kAltTagEnd}},
+ });
+ return *tags;
+}
+
+const std::vector<SearchConcept>& GetEthernetSearchConcepts() {
+ static const base::NoDestructor<std::vector<SearchConcept>> tags({
+ {IDS_SETTINGS_TAG_ETHERNET_SETTINGS,
+ chrome::kEthernetSettingsSubPage,
+ mojom::SearchResultIcon::kEthernet,
+ {IDS_SETTINGS_TAG_ETHERNET_SETTINGS_ALT1, SearchConcept::kAltTagEnd}},
+ });
+ return *tags;
+}
+
+const std::vector<SearchConcept>& GetWifiSearchConcepts() {
+ static const base::NoDestructor<std::vector<SearchConcept>> tags({
+ {IDS_SETTINGS_TAG_WIFI_SETTINGS, chrome::kWiFiSettingsSubPage,
+ mojom::SearchResultIcon::kWifi},
+ {IDS_SETTINGS_TAG_TURN_ON_WIFI,
+ chrome::kWiFiSettingsSubPage,
+ mojom::SearchResultIcon::kWifi,
+ {IDS_SETTINGS_TAG_TURN_ON_WIFI_ALT1, SearchConcept::kAltTagEnd}},
+ {IDS_SETTINGS_TAG_TURN_OFF_WIFI,
+ chrome::kWiFiSettingsSubPage,
+ mojom::SearchResultIcon::kWifi,
+ {IDS_SETTINGS_TAG_TURN_OFF_WIFI_ALT1, SearchConcept::kAltTagEnd}},
+ {IDS_SETTINGS_TAG_CONNECT_WIFI, chrome::kWiFiSettingsSubPage,
+ mojom::SearchResultIcon::kWifi},
+ {IDS_SETTINGS_TAG_DISCONNECT_WIFI, chrome::kWiFiSettingsSubPage,
+ mojom::SearchResultIcon::kWifi},
+ });
+ return *tags;
+}
+
+} // namespace
+
+InternetStringsProvider::InternetStringsProvider(Profile* profile,
+ Delegate* per_page_delegate)
+ : OsSettingsPerPageStringsProvider(profile, per_page_delegate) {
+ // General network search tags are always added.
+ delegate()->AddSearchTags(GetNetworkSearchConcepts());
+
+ // Receive updates when devices (e.g., Ethernet, Wi-Fi) go on/offline.
+ ash::GetNetworkConfigService(
+ cros_network_config_.BindNewPipeAndPassReceiver());
+ cros_network_config_->AddObserver(receiver_.BindNewPipeAndPassRemote());
+
+ // Fetch initial list of devices.
+ FetchDeviceList();
+}
+
+InternetStringsProvider::~InternetStringsProvider() = default;
+
+void InternetStringsProvider::AddUiStrings(
+ content::WebUIDataSource* html_source) const {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"internetAddConnection", IDS_SETTINGS_INTERNET_ADD_CONNECTION},
+ {"internetAddConnectionExpandA11yLabel",
+ IDS_SETTINGS_INTERNET_ADD_CONNECTION_EXPAND_ACCESSIBILITY_LABEL},
+ {"internetAddConnectionNotAllowed",
+ IDS_SETTINGS_INTERNET_ADD_CONNECTION_NOT_ALLOWED},
+ {"internetAddThirdPartyVPN", IDS_SETTINGS_INTERNET_ADD_THIRD_PARTY_VPN},
+ {"internetAddVPN", IDS_SETTINGS_INTERNET_ADD_VPN},
+ {"internetAddWiFi", IDS_SETTINGS_INTERNET_ADD_WIFI},
+ {"internetConfigName", IDS_SETTINGS_INTERNET_CONFIG_NAME},
+ {"internetDetailPageTitle", IDS_SETTINGS_INTERNET_DETAIL},
+ {"internetDeviceEnabling", IDS_SETTINGS_INTERNET_DEVICE_ENABLING},
+ {"internetDeviceInitializing", IDS_SETTINGS_INTERNET_DEVICE_INITIALIZING},
+ {"internetJoinType", IDS_SETTINGS_INTERNET_JOIN_TYPE},
+ {"internetKnownNetworksPageTitle", IDS_SETTINGS_INTERNET_KNOWN_NETWORKS},
+ {"internetMobileSearching", IDS_SETTINGS_INTERNET_MOBILE_SEARCH},
+ {"internetNoNetworks", IDS_SETTINGS_INTERNET_NO_NETWORKS},
+ {"internetPageTitle", IDS_SETTINGS_INTERNET},
+ {"internetSummaryButtonA11yLabel",
+ IDS_SETTINGS_INTERNET_SUMMARY_BUTTON_ACCESSIBILITY_LABEL},
+ {"internetToggleMobileA11yLabel",
+ IDS_SETTINGS_INTERNET_TOGGLE_MOBILE_ACCESSIBILITY_LABEL},
+ {"internetToggleTetherLabel", IDS_SETTINGS_INTERNET_TOGGLE_TETHER_LABEL},
+ {"internetToggleTetherSubtext",
+ IDS_SETTINGS_INTERNET_TOGGLE_TETHER_SUBTEXT},
+ {"internetToggleWiFiA11yLabel",
+ IDS_SETTINGS_INTERNET_TOGGLE_WIFI_ACCESSIBILITY_LABEL},
+ {"knownNetworksAll", IDS_SETTINGS_INTERNET_KNOWN_NETWORKS_ALL},
+ {"knownNetworksButton", IDS_SETTINGS_INTERNET_KNOWN_NETWORKS_BUTTON},
+ {"knownNetworksMessage", IDS_SETTINGS_INTERNET_KNOWN_NETWORKS_MESSAGE},
+ {"knownNetworksPreferred",
+ IDS_SETTINGS_INTERNET_KNOWN_NETWORKS_PREFFERED},
+ {"knownNetworksMenuAddPreferred",
+ IDS_SETTINGS_INTERNET_KNOWN_NETWORKS_MENU_ADD_PREFERRED},
+ {"knownNetworksMenuRemovePreferred",
+ IDS_SETTINGS_INTERNET_KNOWN_NETWORKS_MENU_REMOVE_PREFERRED},
+ {"knownNetworksMenuForget",
+ IDS_SETTINGS_INTERNET_KNOWN_NETWORKS_MENU_FORGET},
+ {"networkAllowDataRoaming",
+ IDS_SETTINGS_SETTINGS_NETWORK_ALLOW_DATA_ROAMING},
+ {"networkAllowDataRoamingEnabledHome",
+ IDS_SETTINGS_SETTINGS_NETWORK_ALLOW_DATA_ROAMING_ENABLED_HOME},
+ {"networkAllowDataRoamingEnabledRoaming",
+ IDS_SETTINGS_SETTINGS_NETWORK_ALLOW_DATA_ROAMING_ENABLED_ROAMING},
+ {"networkAllowDataRoamingDisabled",
+ IDS_SETTINGS_SETTINGS_NETWORK_ALLOW_DATA_ROAMING_DISABLED},
+ {"networkAlwaysOnVpn", IDS_SETTINGS_INTERNET_NETWORK_ALWAYS_ON_VPN},
+ {"networkAutoConnect", IDS_SETTINGS_INTERNET_NETWORK_AUTO_CONNECT},
+ {"networkAutoConnectCellular",
+ IDS_SETTINGS_INTERNET_NETWORK_AUTO_CONNECT_CELLULAR},
+ {"networkButtonActivate", IDS_SETTINGS_INTERNET_BUTTON_ACTIVATE},
+ {"networkButtonConfigure", IDS_SETTINGS_INTERNET_BUTTON_CONFIGURE},
+ {"networkButtonConnect", IDS_SETTINGS_INTERNET_BUTTON_CONNECT},
+ {"networkButtonDisconnect", IDS_SETTINGS_INTERNET_BUTTON_DISCONNECT},
+ {"networkButtonForget", IDS_SETTINGS_INTERNET_BUTTON_FORGET},
+ {"networkButtonViewAccount", IDS_SETTINGS_INTERNET_BUTTON_VIEW_ACCOUNT},
+ {"networkConnectNotAllowed", IDS_SETTINGS_INTERNET_CONNECT_NOT_ALLOWED},
+ {"networkIPAddress", IDS_SETTINGS_INTERNET_NETWORK_IP_ADDRESS},
+ {"networkIPConfigAuto", IDS_SETTINGS_INTERNET_NETWORK_IP_CONFIG_AUTO},
+ {"networkNameserversLearnMore", IDS_LEARN_MORE},
+ {"networkPrefer", IDS_SETTINGS_INTERNET_NETWORK_PREFER},
+ {"networkPrimaryUserControlled",
+ IDS_SETTINGS_INTERNET_NETWORK_PRIMARY_USER_CONTROLLED},
+ {"networkScanningLabel", IDS_NETWORK_SCANNING_MESSAGE},
+ {"networkSectionAdvanced",
+ IDS_SETTINGS_INTERNET_NETWORK_SECTION_ADVANCED},
+ {"networkSectionAdvancedA11yLabel",
+ IDS_SETTINGS_INTERNET_NETWORK_SECTION_ADVANCED_ACCESSIBILITY_LABEL},
+ {"networkSectionNetwork", IDS_SETTINGS_INTERNET_NETWORK_SECTION_NETWORK},
+ {"networkSectionNetworkExpandA11yLabel",
+ IDS_SETTINGS_INTERNET_NETWORK_SECTION_NETWORK_ACCESSIBILITY_LABEL},
+ {"networkSectionProxy", IDS_SETTINGS_INTERNET_NETWORK_SECTION_PROXY},
+ {"networkSectionProxyExpandA11yLabel",
+ IDS_SETTINGS_INTERNET_NETWORK_SECTION_PROXY_ACCESSIBILITY_LABEL},
+ {"networkShared", IDS_SETTINGS_INTERNET_NETWORK_SHARED},
+ {"networkVpnBuiltin", IDS_NETWORK_TYPE_VPN_BUILTIN},
+ {"networkOutOfRange", IDS_SETTINGS_INTERNET_WIFI_NETWORK_OUT_OF_RANGE},
+ {"cellularContactSpecificCarrier",
+ IDS_SETTINGS_INTERNET_CELLULAR_CONTACT_SPECIFIC_CARRIER},
+ {"cellularContactDefaultCarrier",
+ IDS_SETTINGS_INTERNET_CELLULAR_CONTACT_DEFAULT_CARRIER},
+ {"tetherPhoneOutOfRange",
+ IDS_SETTINGS_INTERNET_TETHER_PHONE_OUT_OF_RANGE},
+ {"gmscoreNotificationsTitle",
+ IDS_SETTINGS_INTERNET_GMSCORE_NOTIFICATIONS_TITLE},
+ {"gmscoreNotificationsOneDeviceSubtitle",
+ IDS_SETTINGS_INTERNET_GMSCORE_NOTIFICATIONS_ONE_DEVICE_SUBTITLE},
+ {"gmscoreNotificationsTwoDevicesSubtitle",
+ IDS_SETTINGS_INTERNET_GMSCORE_NOTIFICATIONS_TWO_DEVICES_SUBTITLE},
+ {"gmscoreNotificationsManyDevicesSubtitle",
+ IDS_SETTINGS_INTERNET_GMSCORE_NOTIFICATIONS_MANY_DEVICES_SUBTITLE},
+ {"gmscoreNotificationsFirstStep",
+ IDS_SETTINGS_INTERNET_GMSCORE_NOTIFICATIONS_FIRST_STEP},
+ {"gmscoreNotificationsSecondStep",
+ IDS_SETTINGS_INTERNET_GMSCORE_NOTIFICATIONS_SECOND_STEP},
+ {"gmscoreNotificationsThirdStep",
+ IDS_SETTINGS_INTERNET_GMSCORE_NOTIFICATIONS_THIRD_STEP},
+ {"gmscoreNotificationsFourthStep",
+ IDS_SETTINGS_INTERNET_GMSCORE_NOTIFICATIONS_FOURTH_STEP},
+ {"tetherConnectionDialogTitle",
+ IDS_SETTINGS_INTERNET_TETHER_CONNECTION_DIALOG_TITLE},
+ {"tetherConnectionAvailableDeviceTitle",
+ IDS_SETTINGS_INTERNET_TETHER_CONNECTION_AVAILABLE_DEVICE_TITLE},
+ {"tetherConnectionBatteryPercentage",
+ IDS_SETTINGS_INTERNET_TETHER_CONNECTION_BATTERY_PERCENTAGE},
+ {"tetherConnectionExplanation",
+ IDS_SETTINGS_INTERNET_TETHER_CONNECTION_EXPLANATION},
+ {"tetherConnectionCarrierWarning",
+ IDS_SETTINGS_INTERNET_TETHER_CONNECTION_CARRIER_WARNING},
+ {"tetherConnectionDescriptionTitle",
+ IDS_SETTINGS_INTERNET_TETHER_CONNECTION_DESCRIPTION_TITLE},
+ {"tetherConnectionDescriptionMobileData",
+ IDS_SETTINGS_INTERNET_TETHER_CONNECTION_DESCRIPTION_MOBILE_DATA},
+ {"tetherConnectionDescriptionBattery",
+ IDS_SETTINGS_INTERNET_TETHER_CONNECTION_DESCRIPTION_BATTERY},
+ {"tetherConnectionDescriptionWiFi",
+ IDS_SETTINGS_INTERNET_TETHER_CONNECTION_DESCRIPTION_WIFI},
+ {"tetherConnectionNotNowButton",
+ IDS_SETTINGS_INTERNET_TETHER_CONNECTION_NOT_NOW_BUTTON},
+ {"tetherConnectionConnectButton",
+ IDS_SETTINGS_INTERNET_TETHER_CONNECTION_CONNECT_BUTTON},
+ {"tetherEnableBluetooth", IDS_ENABLE_BLUETOOTH},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ chromeos::network_element::AddLocalizedStrings(html_source);
+ chromeos::network_element::AddOncLocalizedStrings(html_source);
+ chromeos::network_element::AddDetailsLocalizedStrings(html_source);
+ chromeos::network_element::AddConfigLocalizedStrings(html_source);
+ chromeos::network_element::AddErrorLocalizedStrings(html_source);
+
+ html_source->AddString("networkGoogleNameserversLearnMoreUrl",
+ chrome::kGoogleNameserversLearnMoreURL);
+ html_source->AddString(
+ "internetNoNetworksMobileData",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_INTERNET_LOOKING_FOR_MOBILE_NETWORK,
+ GetHelpUrlWithBoard(chrome::kInstantTetheringLearnMoreURL)));
+}
+
+void InternetStringsProvider::OnDeviceStateListChanged() {
+ FetchDeviceList();
+}
+
+void InternetStringsProvider::FetchDeviceList() {
+ cros_network_config_->GetDeviceStateList(base::BindOnce(
+ &InternetStringsProvider::OnDeviceList, base::Unretained(this)));
+}
+
+void InternetStringsProvider::OnDeviceList(
+ std::vector<network_config::mojom::DeviceStatePropertiesPtr> devices) {
+ // Start with no search tags.
+ delegate()->RemoveSearchTags(GetEthernetSearchConcepts());
+ delegate()->RemoveSearchTags(GetWifiSearchConcepts());
+
+ // Add a search tag each time we see a device type.
+ for (const auto& device : devices) {
+ if (device->type == network_config::mojom::NetworkType::kEthernet)
+ delegate()->AddSearchTags(GetEthernetSearchConcepts());
+ else if (device->type == network_config::mojom::NetworkType::kWiFi)
+ delegate()->AddSearchTags(GetWifiSearchConcepts());
+ }
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/internet_strings_provider.h b/chromium/chrome/browser/ui/webui/settings/chromeos/internet_strings_provider.h
new file mode 100644
index 00000000000..4a0e2a2511e
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/internet_strings_provider.h
@@ -0,0 +1,59 @@
+// Copyright 2020 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 CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_INTERNET_STRINGS_PROVIDER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_INTERNET_STRINGS_PROVIDER_H_
+
+#include <vector>
+
+#include "chrome/browser/ui/webui/settings/chromeos/os_settings_per_page_strings_provider.h"
+#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/bindings/remote.h"
+
+class Profile;
+
+namespace content {
+class WebUIDataSource;
+} // namespace content
+
+namespace chromeos {
+namespace settings {
+
+class InternetStringsProvider
+ : public OsSettingsPerPageStringsProvider,
+ public network_config::mojom::CrosNetworkConfigObserver {
+ public:
+ InternetStringsProvider(Profile* profile, Delegate* per_page_delegate);
+ ~InternetStringsProvider() override;
+
+ private:
+ // OsSettingsPerPageStringsProvider:
+ void AddUiStrings(content::WebUIDataSource* html_source) const override;
+
+ // network_config::mojom::CrosNetworkConfigObserver:
+ void OnActiveNetworksChanged(
+ std::vector<network_config::mojom::NetworkStatePropertiesPtr> networks)
+ override {}
+ void OnNetworkStateChanged(
+ chromeos::network_config::mojom::NetworkStatePropertiesPtr network)
+ override {}
+ void OnNetworkStateListChanged() override {}
+ void OnVpnProvidersChanged() override {}
+ void OnNetworkCertificatesChanged() override {}
+ void OnDeviceStateListChanged() override;
+
+ void FetchDeviceList();
+ void OnDeviceList(
+ std::vector<network_config::mojom::DeviceStatePropertiesPtr> devices);
+
+ mojo::Receiver<network_config::mojom::CrosNetworkConfigObserver> receiver_{
+ this};
+ mojo::Remote<network_config::mojom::CrosNetworkConfig> cros_network_config_;
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_INTERNET_STRINGS_PROVIDER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h
index 8ee0b692ac1..a103760bd1e 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h
@@ -13,7 +13,7 @@
#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
#include "chromeos/components/multidevice/remote_device_ref.h"
#include "chromeos/services/multidevice_setup/public/cpp/multidevice_setup_client.h"
-#include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h"
+#include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom-forward.h"
#include "components/prefs/pref_change_registrar.h"
class PrefService;
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.cc
new file mode 100644
index 00000000000..653188ccf20
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.cc
@@ -0,0 +1,2136 @@
+// Copyright 2020 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 "chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.h"
+
+#include "ash/public/cpp/ash_features.h"
+#include "ash/public/mojom/assistant_state_controller.mojom.h"
+#include "base/command_line.h"
+#include "base/feature_list.h"
+#include "base/i18n/number_formatting.h"
+#include "base/no_destructor.h"
+#include "base/strings/strcat.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/system/sys_info.h"
+#include "build/branding_buildflags.h"
+#include "build/build_config.h"
+#include "build/buildflag.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/browser_process_platform_part.h"
+#include "chrome/browser/chromeos/account_manager/account_manager_util.h"
+#include "chrome/browser/chromeos/arc/arc_util.h"
+#include "chrome/browser/chromeos/assistant/assistant_util.h"
+#include "chrome/browser/chromeos/crostini/crostini_features.h"
+#include "chrome/browser/chromeos/crostini/crostini_util.h"
+#include "chrome/browser/chromeos/kerberos/kerberos_credentials_manager.h"
+#include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.h"
+#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
+#include "chrome/browser/policy/profile_policy_connector.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/supervised_user/supervised_user_service.h"
+#include "chrome/browser/supervised_user/supervised_user_service_factory.h"
+#include "chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.h"
+#include "chrome/browser/ui/webui/chromeos/bluetooth_dialog_localized_strings_provider.h"
+#include "chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.h"
+#include "chrome/browser/ui/webui/chromeos/smb_shares/smb_shares_localized_strings_provider.h"
+#include "chrome/browser/ui/webui/management_ui.h"
+#include "chrome/browser/ui/webui/policy_indicator_localized_strings_provider.h"
+#include "chrome/browser/ui/webui/settings/chromeos/internet_strings_provider.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/search_concept.h"
+#include "chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.h"
+#include "chrome/browser/ui/webui/webui_util.h"
+#include "chrome/common/chrome_features.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/common/webui_url_constants.h"
+#include "chrome/grit/chromium_strings.h"
+#include "chrome/grit/generated_resources.h"
+#include "chrome/grit/locale_settings.h"
+#include "chrome/services/local_search_service/public/mojom/types.mojom.h"
+#include "chromeos/constants/chromeos_features.h"
+#include "chromeos/constants/chromeos_switches.h"
+#include "chromeos/services/assistant/public/features.h"
+#include "chromeos/services/multidevice_setup/public/cpp/url_provider.h"
+#include "chromeos/strings/grit/chromeos_strings.h"
+#include "components/google/core/common/google_util.h"
+#include "components/prefs/pref_service.h"
+#include "components/strings/grit/components_strings.h"
+#include "components/version_ui/version_ui_constants.h"
+#include "content/public/browser/web_ui_data_source.h"
+#include "content/public/common/content_features.h"
+#include "content/public/common/content_switches.h"
+#include "device/bluetooth/strings/grit/bluetooth_strings.h"
+#include "media/base/media_switches.h"
+#include "ui/accessibility/accessibility_switches.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/webui/web_ui_util.h"
+#include "ui/chromeos/devicetype_utils.h"
+#include "ui/chromeos/events/keyboard_layout_util.h"
+#include "ui/display/display_features.h"
+#include "ui/display/display_switches.h"
+#include "ui/display/manager/touch_device_manager.h"
+
+namespace chromeos {
+namespace settings {
+namespace {
+
+std::vector<local_search_service::mojom::DataPtr> ConceptVectorToDataPtrVector(
+ const std::vector<SearchConcept>& tags_group) {
+ std::vector<local_search_service::mojom::DataPtr> data_list;
+
+ for (const auto& concept : tags_group) {
+ std::vector<base::string16> search_tags;
+
+ // Add the canonical tag.
+ search_tags.push_back(
+ l10n_util::GetStringUTF16(concept.canonical_message_id));
+
+ // Add all alternate tags.
+ for (size_t i = 0; i < SearchConcept::kMaxAltTagsPerConcept; ++i) {
+ int curr_alt_tag = concept.alt_tag_ids[i];
+ if (curr_alt_tag == SearchConcept::kAltTagEnd)
+ break;
+ search_tags.push_back(l10n_util::GetStringUTF16(curr_alt_tag));
+ }
+
+ // Note: A stringified version of the canonical tag message ID is used as
+ // the identifier for this search data.
+ data_list.push_back(local_search_service::mojom::Data::New(
+ base::NumberToString(concept.canonical_message_id), search_tags));
+ }
+
+ return data_list;
+}
+
+// Generates a Google Help URL which includes a "board type" parameter. Some
+// help pages need to be adjusted depending on the type of CrOS device that is
+// accessing the page.
+base::string16 GetHelpUrlWithBoard(const std::string& original_url) {
+ return base::ASCIIToUTF16(original_url +
+ "&b=" + base::SysInfo::GetLsbReleaseBoard());
+}
+
+bool IsDeviceManaged() {
+ policy::BrowserPolicyConnectorChromeOS* connector =
+ g_browser_process->platform_part()->browser_policy_connector_chromeos();
+ return connector->IsEnterpriseManaged();
+}
+
+bool IsProfileManaged(Profile* profile) {
+ return profile->GetProfilePolicyConnector()->IsManaged();
+}
+
+void AddCommonStrings(content::WebUIDataSource* html_source, Profile* profile) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"add", IDS_ADD},
+ {"advancedPageTitle", IDS_SETTINGS_ADVANCED},
+ {"back", IDS_ACCNAME_BACK},
+ {"basicPageTitle", IDS_SETTINGS_BASIC},
+ {"cancel", IDS_CANCEL},
+ {"clear", IDS_SETTINGS_CLEAR},
+ {"close", IDS_CLOSE},
+ {"confirm", IDS_CONFIRM},
+ {"continue", IDS_SETTINGS_CONTINUE},
+ {"controlledByExtension", IDS_SETTINGS_CONTROLLED_BY_EXTENSION},
+ {"custom", IDS_SETTINGS_CUSTOM},
+ {"delete", IDS_SETTINGS_DELETE},
+ {"deviceOff", IDS_SETTINGS_DEVICE_OFF},
+ {"deviceOn", IDS_SETTINGS_DEVICE_ON},
+ {"disable", IDS_DISABLE},
+ {"done", IDS_DONE},
+ {"edit", IDS_SETTINGS_EDIT},
+ {"extensionsLinkTooltip", IDS_SETTINGS_MENU_EXTENSIONS_LINK_TOOLTIP},
+ {"learnMore", IDS_LEARN_MORE},
+ {"menu", IDS_MENU},
+ {"menuButtonLabel", IDS_SETTINGS_MENU_BUTTON_LABEL},
+ {"moreActions", IDS_SETTINGS_MORE_ACTIONS},
+ {"ok", IDS_OK},
+ {"restart", IDS_SETTINGS_RESTART},
+ {"save", IDS_SAVE},
+ {"searchResultBubbleText", IDS_SEARCH_RESULT_BUBBLE_TEXT},
+ {"searchResultsBubbleText", IDS_SEARCH_RESULTS_BUBBLE_TEXT},
+ {"settings", IDS_SETTINGS_SETTINGS},
+ {"settingsAltPageTitle", IDS_SETTINGS_ALT_PAGE_TITLE},
+ {"subpageArrowRoleDescription", IDS_SETTINGS_SUBPAGE_BUTTON},
+ {"notValidWebAddress", IDS_SETTINGS_NOT_VALID_WEB_ADDRESS},
+ {"notValidWebAddressForContentType",
+ IDS_SETTINGS_NOT_VALID_WEB_ADDRESS_FOR_CONTENT_TYPE},
+
+ // Common font related strings shown in a11y and appearance sections.
+ {"quickBrownFox", IDS_SETTINGS_QUICK_BROWN_FOX},
+ {"verySmall", IDS_SETTINGS_VERY_SMALL_FONT},
+ {"small", IDS_SETTINGS_SMALL_FONT},
+ {"medium", IDS_SETTINGS_MEDIUM_FONT},
+ {"large", IDS_SETTINGS_LARGE_FONT},
+ {"veryLarge", IDS_SETTINGS_VERY_LARGE_FONT},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddBoolean(
+ "isGuest",
+ user_manager::UserManager::Get()->IsLoggedInAsGuest() ||
+ user_manager::UserManager::Get()->IsLoggedInAsPublicAccount());
+
+ html_source->AddBoolean("isSupervised", profile->IsSupervised());
+}
+
+void AddA11yStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"a11yPageTitle", IDS_SETTINGS_ACCESSIBILITY},
+ {"a11yWebStore", IDS_SETTINGS_ACCESSIBILITY_WEB_STORE},
+ {"moreFeaturesLinkDescription",
+ IDS_SETTINGS_MORE_FEATURES_LINK_DESCRIPTION},
+ {"accessibleImageLabelsTitle",
+ IDS_SETTINGS_ACCESSIBLE_IMAGE_LABELS_TITLE},
+ {"accessibleImageLabelsSubtitle",
+ IDS_SETTINGS_ACCESSIBLE_IMAGE_LABELS_SUBTITLE},
+ {"settingsSliderRoleDescription",
+ IDS_SETTINGS_SLIDER_MIN_MAX_ARIA_ROLE_DESCRIPTION},
+ {"manageAccessibilityFeatures",
+ IDS_SETTINGS_ACCESSIBILITY_MANAGE_ACCESSIBILITY_FEATURES},
+ {"optionsInMenuLabel", IDS_SETTINGS_OPTIONS_IN_MENU_LABEL},
+ {"largeMouseCursorLabel", IDS_SETTINGS_LARGE_MOUSE_CURSOR_LABEL},
+ {"largeMouseCursorSizeLabel", IDS_SETTINGS_LARGE_MOUSE_CURSOR_SIZE_LABEL},
+ {"largeMouseCursorSizeDefaultLabel",
+ IDS_SETTINGS_LARGE_MOUSE_CURSOR_SIZE_DEFAULT_LABEL},
+ {"largeMouseCursorSizeLargeLabel",
+ IDS_SETTINGS_LARGE_MOUSE_CURSOR_SIZE_LARGE_LABEL},
+ {"highContrastLabel", IDS_SETTINGS_HIGH_CONTRAST_LABEL},
+ {"stickyKeysLabel", IDS_SETTINGS_STICKY_KEYS_LABEL},
+ {"chromeVoxLabel", IDS_SETTINGS_CHROMEVOX_LABEL},
+ {"chromeVoxOptionsLabel", IDS_SETTINGS_CHROMEVOX_OPTIONS_LABEL},
+ {"screenMagnifierLabel", IDS_SETTINGS_SCREEN_MAGNIFIER_LABEL},
+ {"screenMagnifierZoomLabel", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_LABEL},
+ {"dockedMagnifierLabel", IDS_SETTINGS_DOCKED_MAGNIFIER_LABEL},
+ {"dockedMagnifierZoomLabel", IDS_SETTINGS_DOCKED_MAGNIFIER_ZOOM_LABEL},
+ {"screenMagnifierZoom2x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_2_X},
+ {"screenMagnifierZoom4x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_4_X},
+ {"screenMagnifierZoom6x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_6_X},
+ {"screenMagnifierZoom8x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_8_X},
+ {"screenMagnifierZoom10x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_10_X},
+ {"screenMagnifierZoom12x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_12_X},
+ {"screenMagnifierZoom14x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_14_X},
+ {"screenMagnifierZoom16x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_16_X},
+ {"screenMagnifierZoom18x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_18_X},
+ {"screenMagnifierZoom20x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_20_X},
+ {"tapDraggingLabel", IDS_SETTINGS_TAP_DRAGGING_LABEL},
+ {"clickOnStopLabel", IDS_SETTINGS_CLICK_ON_STOP_LABEL},
+ {"delayBeforeClickLabel", IDS_SETTINGS_DELAY_BEFORE_CLICK_LABEL},
+ {"delayBeforeClickExtremelyShort",
+ IDS_SETTINGS_DELAY_BEFORE_CLICK_EXTREMELY_SHORT},
+ {"delayBeforeClickVeryShort", IDS_SETTINGS_DELAY_BEFORE_CLICK_VERY_SHORT},
+ {"delayBeforeClickShort", IDS_SETTINGS_DELAY_BEFORE_CLICK_SHORT},
+ {"delayBeforeClickLong", IDS_SETTINGS_DELAY_BEFORE_CLICK_LONG},
+ {"delayBeforeClickVeryLong", IDS_SETTINGS_DELAY_BEFORE_CLICK_VERY_LONG},
+ {"autoclickRevertToLeftClick",
+ IDS_SETTINGS_AUTOCLICK_REVERT_TO_LEFT_CLICK},
+ {"autoclickStabilizeCursorPosition",
+ IDS_SETTINGS_AUTOCLICK_STABILIZE_CURSOR_POSITION},
+ {"autoclickMovementThresholdLabel",
+ IDS_SETTINGS_AUTOCLICK_MOVEMENT_THRESHOLD_LABEL},
+ {"autoclickMovementThresholdExtraSmall",
+ IDS_SETTINGS_AUTOCLICK_MOVEMENT_THRESHOLD_EXTRA_SMALL},
+ {"autoclickMovementThresholdSmall",
+ IDS_SETTINGS_AUTOCLICK_MOVEMENT_THRESHOLD_SMALL},
+ {"autoclickMovementThresholdDefault",
+ IDS_SETTINGS_AUTOCLICK_MOVEMENT_THRESHOLD_DEFAULT},
+ {"autoclickMovementThresholdLarge",
+ IDS_SETTINGS_AUTOCLICK_MOVEMENT_THRESHOLD_LARGE},
+ {"autoclickMovementThresholdExtraLarge",
+ IDS_SETTINGS_AUTOCLICK_MOVEMENT_THRESHOLD_EXTRA_LARGE},
+ {"dictationDescription",
+ IDS_SETTINGS_ACCESSIBILITY_DICTATION_DESCRIPTION},
+ {"dictationLabel", IDS_SETTINGS_ACCESSIBILITY_DICTATION_LABEL},
+ {"onScreenKeyboardLabel", IDS_SETTINGS_ON_SCREEN_KEYBOARD_LABEL},
+ {"monoAudioLabel", IDS_SETTINGS_MONO_AUDIO_LABEL},
+ {"startupSoundLabel", IDS_SETTINGS_STARTUP_SOUND_LABEL},
+ {"a11yExplanation", IDS_SETTINGS_ACCESSIBILITY_EXPLANATION},
+ {"caretHighlightLabel",
+ IDS_SETTINGS_ACCESSIBILITY_CARET_HIGHLIGHT_DESCRIPTION},
+ {"cursorHighlightLabel",
+ IDS_SETTINGS_ACCESSIBILITY_CURSOR_HIGHLIGHT_DESCRIPTION},
+ {"focusHighlightLabel",
+ IDS_SETTINGS_ACCESSIBILITY_FOCUS_HIGHLIGHT_DESCRIPTION},
+ {"selectToSpeakTitle", IDS_SETTINGS_ACCESSIBILITY_SELECT_TO_SPEAK_TITLE},
+ {"selectToSpeakDisabledDescription",
+ IDS_SETTINGS_ACCESSIBILITY_SELECT_TO_SPEAK_DISABLED_DESCRIPTION},
+ {"selectToSpeakDescription",
+ IDS_SETTINGS_ACCESSIBILITY_SELECT_TO_SPEAK_DESCRIPTION},
+ {"selectToSpeakDescriptionWithoutKeyboard",
+ IDS_SETTINGS_ACCESSIBILITY_SELECT_TO_SPEAK_DESCRIPTION_WITHOUT_KEYBOARD},
+ {"selectToSpeakOptionsLabel",
+ IDS_SETTINGS_ACCESSIBILITY_SELECT_TO_SPEAK_OPTIONS_LABEL},
+ {"switchAccessLabel",
+ IDS_SETTINGS_ACCESSIBILITY_SWITCH_ACCESS_DESCRIPTION},
+ {"switchAccessOptionsLabel",
+ IDS_SETTINGS_ACCESSIBILITY_SWITCH_ACCESS_OPTIONS_LABEL},
+ {"manageSwitchAccessSettings",
+ IDS_SETTINGS_MANAGE_SWITCH_ACCESS_SETTINGS},
+ {"switchAssignmentHeading", IDS_SETTINGS_SWITCH_ASSIGNMENT_HEADING},
+ {"switchAssignOptionNone", IDS_SETTINGS_SWITCH_ASSIGN_OPTION_NONE},
+ {"switchAssignOptionSpace", IDS_SETTINGS_SWITCH_ASSIGN_OPTION_SPACE},
+ {"switchAssignOptionEnter", IDS_SETTINGS_SWITCH_ASSIGN_OPTION_ENTER},
+ {"assignSelectSwitchLabel", IDS_SETTINGS_ASSIGN_SELECT_SWITCH_LABEL},
+ {"assignNextSwitchLabel", IDS_SETTINGS_ASSIGN_NEXT_SWITCH_LABEL},
+ {"assignPreviousSwitchLabel", IDS_SETTINGS_ASSIGN_PREVIOUS_SWITCH_LABEL},
+ {"switchAccessAutoScanHeading",
+ IDS_SETTINGS_SWITCH_ACCESS_AUTO_SCAN_HEADING},
+ {"switchAccessAutoScanLabel", IDS_SETTINGS_SWITCH_ACCESS_AUTO_SCAN_LABEL},
+ {"switchAccessAutoScanSpeedLabel",
+ IDS_SETTINGS_SWITCH_ACCESS_AUTO_SCAN_SPEED_LABEL},
+ {"switchAccessAutoScanKeyboardSpeedLabel",
+ IDS_SETTINGS_SWITCH_ACCESS_AUTO_SCAN_KEYBOARD_SPEED_LABEL},
+ {"durationInSeconds", IDS_SETTINGS_DURATION_IN_SECONDS},
+ {"manageAccessibilityFeatures",
+ IDS_SETTINGS_ACCESSIBILITY_MANAGE_ACCESSIBILITY_FEATURES},
+ {"textToSpeechHeading",
+ IDS_SETTINGS_ACCESSIBILITY_TEXT_TO_SPEECH_HEADING},
+ {"displayHeading", IDS_SETTINGS_ACCESSIBILITY_DISPLAY_HEADING},
+ {"displaySettingsTitle",
+ IDS_SETTINGS_ACCESSIBILITY_DISPLAY_SETTINGS_TITLE},
+ {"displaySettingsDescription",
+ IDS_SETTINGS_ACCESSIBILITY_DISPLAY_SETTINGS_DESCRIPTION},
+ {"appearanceSettingsTitle",
+ IDS_SETTINGS_ACCESSIBILITY_APPEARANCE_SETTINGS_TITLE},
+ {"appearanceSettingsDescription",
+ IDS_SETTINGS_ACCESSIBILITY_APPEARANCE_SETTINGS_DESCRIPTION},
+ {"keyboardAndTextInputHeading",
+ IDS_SETTINGS_ACCESSIBILITY_KEYBOARD_AND_TEXT_INPUT_HEADING},
+ {"keyboardSettingsTitle",
+ IDS_SETTINGS_ACCESSIBILITY_KEYBOARD_SETTINGS_TITLE},
+ {"keyboardSettingsDescription",
+ IDS_SETTINGS_ACCESSIBILITY_KEYBOARD_SETTINGS_DESCRIPTION},
+ {"mouseAndTouchpadHeading",
+ IDS_SETTINGS_ACCESSIBILITY_MOUSE_AND_TOUCHPAD_HEADING},
+ {"mouseSettingsTitle", IDS_SETTINGS_ACCESSIBILITY_MOUSE_SETTINGS_TITLE},
+ {"mouseSettingsDescription",
+ IDS_SETTINGS_ACCESSIBILITY_MOUSE_SETTINGS_DESCRIPTION},
+ {"audioAndCaptionsHeading",
+ IDS_SETTINGS_ACCESSIBILITY_AUDIO_AND_CAPTIONS_HEADING},
+ {"additionalFeaturesTitle",
+ IDS_SETTINGS_ACCESSIBILITY_ADDITIONAL_FEATURES_TITLE},
+ {"manageTtsSettings", IDS_SETTINGS_MANAGE_TTS_SETTINGS},
+ {"ttsSettingsLinkDescription", IDS_SETTINGS_TTS_LINK_DESCRIPTION},
+ {"textToSpeechVoices", IDS_SETTINGS_TEXT_TO_SPEECH_VOICES},
+ {"textToSpeechNoVoicesMessage",
+ IDS_SETTINGS_TEXT_TO_SPEECH_NO_VOICES_MESSAGE},
+ {"textToSpeechMoreLanguages", IDS_SETTINGS_TEXT_TO_SPEECH_MORE_LANGUAGES},
+ {"textToSpeechProperties", IDS_SETTINGS_TEXT_TO_SPEECH_PROPERTIES},
+ {"textToSpeechRate", IDS_SETTINGS_TEXT_TO_SPEECH_RATE},
+ {"textToSpeechRateMinimumLabel",
+ IDS_SETTINGS_TEXT_TO_SPEECH_RATE_MINIMUM_LABEL},
+ {"textToSpeechRateMaximumLabel",
+ IDS_SETTINGS_TEXT_TO_SPEECH_RATE_MAXIMUM_LABEL},
+ {"textToSpeechPitch", IDS_SETTINGS_TEXT_TO_SPEECH_PITCH},
+ {"textToSpeechPitchMinimumLabel",
+ IDS_SETTINGS_TEXT_TO_SPEECH_PITCH_MINIMUM_LABEL},
+ {"textToSpeechPitchMaximumLabel",
+ IDS_SETTINGS_TEXT_TO_SPEECH_PITCH_MAXIMUM_LABEL},
+ {"textToSpeechVolume", IDS_SETTINGS_TEXT_TO_SPEECH_VOLUME},
+ {"textToSpeechVolumeMinimumLabel",
+ IDS_SETTINGS_TEXT_TO_SPEECH_VOLUME_MINIMUM_LABEL},
+ {"textToSpeechVolumeMaximumLabel",
+ IDS_SETTINGS_TEXT_TO_SPEECH_VOLUME_MAXIMUM_LABEL},
+ {"percentage", IDS_SETTINGS_PERCENTAGE},
+ {"defaultPercentage", IDS_SETTINGS_DEFAULT_PERCENTAGE},
+ {"textToSpeechPreviewHeading",
+ IDS_SETTINGS_TEXT_TO_SPEECH_PREVIEW_HEADING},
+ {"textToSpeechPreviewInputLabel",
+ IDS_SETTINGS_TEXT_TO_SPEECH_PREVIEW_INPUT_LABEL},
+ {"textToSpeechPreviewInput", IDS_SETTINGS_TEXT_TO_SPEECH_PREVIEW_INPUT},
+ {"textToSpeechPreviewVoice", IDS_SETTINGS_TEXT_TO_SPEECH_PREVIEW_VOICE},
+ {"textToSpeechPreviewPlay", IDS_SETTINGS_TEXT_TO_SPEECH_PREVIEW_PLAY},
+ {"textToSpeechEngines", IDS_SETTINGS_TEXT_TO_SPEECH_ENGINES},
+ {"tabletModeShelfNavigationButtonsSettingLabel",
+ IDS_SETTINGS_A11Y_TABLET_MODE_SHELF_BUTTONS_LABEL},
+ {"tabletModeShelfNavigationButtonsSettingDescription",
+ IDS_SETTINGS_A11Y_TABLET_MODE_SHELF_BUTTONS_DESCRIPTION},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddString("accountManagerLearnMoreUrl",
+ chrome::kAccountManagerLearnMoreURL);
+ html_source->AddString("a11yLearnMoreUrl",
+ chrome::kChromeAccessibilityHelpURL);
+
+ base::CommandLine& cmd = *base::CommandLine::ForCurrentProcess();
+ html_source->AddBoolean(
+ "showExperimentalAccessibilitySwitchAccess",
+ cmd.HasSwitch(::switches::kEnableExperimentalAccessibilitySwitchAccess));
+
+ html_source->AddBoolean(
+ "showExperimentalAccessibilitySwitchAccessImprovedTextInput",
+ cmd.HasSwitch(
+ ::switches::kEnableExperimentalAccessibilitySwitchAccessText));
+
+ html_source->AddBoolean("showExperimentalA11yLabels",
+ base::FeatureList::IsEnabled(
+ ::features::kExperimentalAccessibilityLabels));
+
+ html_source->AddBoolean(
+ "showTabletModeShelfNavigationButtonsSettings",
+ ash::features::IsHideShelfControlsInTabletModeEnabled());
+
+ html_source->AddString("tabletModeShelfNavigationButtonsLearnMoreUrl",
+ chrome::kTabletModeGesturesLearnMoreURL);
+
+ html_source->AddBoolean("enableLiveCaption",
+ base::FeatureList::IsEnabled(media::kLiveCaption));
+
+ ::settings::AddCaptionSubpageStrings(html_source);
+}
+
+void AddLanguagesStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"orderLanguagesInstructions",
+ IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_ORDERING_INSTRUCTIONS},
+ {"osLanguagesPageTitle", IDS_OS_SETTINGS_LANGUAGES_AND_INPUT_PAGE_TITLE},
+ {"osLanguagesListTitle", IDS_OS_SETTINGS_LANGUAGES_LIST_TITLE},
+ {"inputMethodsListTitle",
+ IDS_SETTINGS_LANGUAGES_INPUT_METHODS_LIST_TITLE},
+ {"inputMethodEnabled", IDS_SETTINGS_LANGUAGES_INPUT_METHOD_ENABLED},
+ {"inputMethodsExpandA11yLabel",
+ IDS_SETTINGS_LANGUAGES_INPUT_METHODS_EXPAND_ACCESSIBILITY_LABEL},
+ {"inputMethodsManagedbyPolicy",
+ IDS_SETTINGS_LANGUAGES_INPUT_METHODS_MANAGED_BY_POLICY},
+ {"manageInputMethods", IDS_SETTINGS_LANGUAGES_INPUT_METHODS_MANAGE},
+ {"manageInputMethodsPageTitle",
+ IDS_SETTINGS_LANGUAGES_MANAGE_INPUT_METHODS_TITLE},
+ {"showImeMenu", IDS_SETTINGS_LANGUAGES_SHOW_IME_MENU},
+ {"displayLanguageRestart",
+ IDS_SETTINGS_LANGUAGES_RESTART_TO_DISPLAY_LANGUAGE},
+ {"moveDown", IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_MOVE_DOWN},
+ {"displayInThisLanguage",
+ IDS_SETTINGS_LANGUAGES_DISPLAY_IN_THIS_LANGUAGE},
+ {"searchLanguages", IDS_SETTINGS_LANGUAGE_SEARCH},
+ {"addLanguagesDialogTitle",
+ IDS_SETTINGS_LANGUAGES_MANAGE_LANGUAGES_TITLE},
+ {"moveToTop", IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_MOVE_TO_TOP},
+ {"isDisplayedInThisLanguage",
+ IDS_SETTINGS_LANGUAGES_IS_DISPLAYED_IN_THIS_LANGUAGE},
+ {"removeLanguage", IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_REMOVE},
+ {"addLanguages", IDS_SETTINGS_LANGUAGES_LANGUAGES_ADD},
+ {"moveUp", IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_MOVE_UP},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddString(
+ "languagesLearnMoreURL",
+ base::ASCIIToUTF16(chrome::kLanguageSettingsLearnMoreUrl));
+}
+
+void AddPersonalizationStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"ambientModeTitle", IDS_OS_SETTINGS_AMBIENT_MODE_TITLE},
+ {"ambientModeEnabled", IDS_OS_SETTINGS_AMBIENT_MODE_ENABLED},
+ {"ambientModeDisabled", IDS_OS_SETTINGS_AMBIENT_MODE_DISABLED},
+ {"ambientModeOn", IDS_OS_SETTINGS_AMBIENT_MODE_ON},
+ {"ambientModeOff", IDS_OS_SETTINGS_AMBIENT_MODE_OFF},
+ {"ambientModeTopicSourceTitle",
+ IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_TITLE},
+ {"ambientModeTopicSourceGooglePhotos",
+ IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_GOOGLE_PHOTOS},
+ {"ambientModeTopicSourceArtGallery",
+ IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_ART_GALLERY},
+ {"changePictureTitle", IDS_OS_SETTINGS_CHANGE_PICTURE_TITLE},
+ {"openWallpaperApp", IDS_OS_SETTINGS_OPEN_WALLPAPER_APP},
+ {"personalizationPageTitle", IDS_OS_SETTINGS_PERSONALIZATION},
+ {"setWallpaper", IDS_OS_SETTINGS_SET_WALLPAPER},
+ {"takePhoto", IDS_SETTINGS_CHANGE_PICTURE_TAKE_PHOTO},
+ {"captureVideo", IDS_SETTINGS_CHANGE_PICTURE_CAPTURE_VIDEO},
+ {"discardPhoto", IDS_SETTINGS_CHANGE_PICTURE_DISCARD_PHOTO},
+ {"previewAltText", IDS_SETTINGS_CHANGE_PICTURE_PREVIEW_ALT},
+ {"switchModeToVideo", IDS_SETTINGS_CHANGE_PICTURE_SWITCH_MODE_TO_VIDEO},
+ {"profilePhoto", IDS_SETTINGS_CHANGE_PICTURE_PROFILE_PHOTO},
+ {"changePicturePageDescription", IDS_SETTINGS_CHANGE_PICTURE_DIALOG_TEXT},
+ {"switchModeToCamera", IDS_SETTINGS_CHANGE_PICTURE_SWITCH_MODE_TO_CAMERA},
+ {"chooseFile", IDS_SETTINGS_CHANGE_PICTURE_CHOOSE_FILE},
+ {"oldPhoto", IDS_SETTINGS_CHANGE_PICTURE_OLD_PHOTO},
+ {"oldVideo", IDS_SETTINGS_CHANGE_PICTURE_OLD_VIDEO},
+ {"authorCreditText", IDS_SETTINGS_CHANGE_PICTURE_AUTHOR_CREDIT_TEXT},
+ {"photoCaptureAccessibleText",
+ IDS_SETTINGS_PHOTO_CAPTURE_ACCESSIBLE_TEXT},
+ {"photoDiscardAccessibleText",
+ IDS_SETTINGS_PHOTO_DISCARD_ACCESSIBLE_TEXT},
+ {"photoModeAccessibleText", IDS_SETTINGS_PHOTO_MODE_ACCESSIBLE_TEXT},
+ {"videoModeAccessibleText", IDS_SETTINGS_VIDEO_MODE_ACCESSIBLE_TEXT},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddBoolean(
+ "changePictureVideoModeEnabled",
+ base::FeatureList::IsEnabled(::features::kChangePictureVideoMode));
+ html_source->AddBoolean("isAmbientModeEnabled",
+ chromeos::features::IsAmbientModeEnabled());
+}
+
+void AddFingerprintListStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"lockScreenAddFingerprint",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_ADD_FINGERPRINT_BUTTON},
+ {"lockScreenRegisteredFingerprints",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_REGISTERED_FINGERPRINTS_LABEL},
+ {"lockScreenFingerprintWarning",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_FINGERPRINT_LESS_SECURE},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+}
+
+void AddSetupPinDialogStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"configurePinChoosePinTitle",
+ IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_CHOOSE_PIN_TITLE},
+ {"configurePinConfirmPinTitle",
+ IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_CONFIRM_PIN_TITLE},
+ {"configurePinMismatched", IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_MISMATCHED},
+ {"configurePinTooShort", IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_TOO_SHORT},
+ {"configurePinTooLong", IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_TOO_LONG},
+ {"configurePinWeakPin", IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_WEAK_PIN},
+ {"pinKeyboardPlaceholderPin", IDS_PIN_KEYBOARD_HINT_TEXT_PIN},
+ {"pinKeyboardPlaceholderPinPassword",
+ IDS_PIN_KEYBOARD_HINT_TEXT_PIN_PASSWORD},
+ {"pinKeyboardDeleteAccessibleName",
+ IDS_PIN_KEYBOARD_DELETE_ACCESSIBLE_NAME},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ // Format numbers to be used on the pin keyboard.
+ for (int j = 0; j <= 9; j++) {
+ html_source->AddString("pinKeyboard" + base::NumberToString(j),
+ base::FormatNumber(int64_t{j}));
+ }
+}
+
+void AddSetupFingerprintDialogStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"configureFingerprintTitle", IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_TITLE},
+ {"configureFingerprintAddAnotherButton",
+ IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_ADD_ANOTHER_BUTTON},
+ {"configureFingerprintInstructionReadyStep",
+ IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_READY},
+ {"configureFingerprintLiftFinger",
+ IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_LIFT_FINGER},
+ {"configureFingerprintTryAgain",
+ IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_TRY_AGAIN},
+ {"configureFingerprintImmobile",
+ IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_FINGER_IMMOBILE},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+}
+
+void AddFingerprintStrings(content::WebUIDataSource* html_source) {
+ int instruction_id, aria_label_id;
+ using FingerprintLocation = chromeos::quick_unlock::FingerprintLocation;
+ switch (chromeos::quick_unlock::GetFingerprintLocation()) {
+ case FingerprintLocation::TABLET_POWER_BUTTON:
+ instruction_id =
+ IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_POWER_BUTTON;
+ aria_label_id =
+ IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_POWER_BUTTON_ARIA_LABEL;
+ break;
+ case FingerprintLocation::KEYBOARD_BOTTOM_LEFT:
+ instruction_id =
+ IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD;
+ aria_label_id =
+ IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD_BOTTOM_LEFT_ARIA_LABEL;
+ break;
+ case FingerprintLocation::KEYBOARD_BOTTOM_RIGHT:
+ instruction_id =
+ IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD;
+ aria_label_id =
+ IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD_BOTTOM_RIGHT_ARIA_LABEL;
+ break;
+ case FingerprintLocation::KEYBOARD_TOP_RIGHT:
+ instruction_id =
+ IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD;
+ aria_label_id =
+ IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD_TOP_RIGHT_ARIA_LABEL;
+ break;
+ }
+ html_source->AddLocalizedString(
+ "configureFingerprintInstructionLocateScannerStep", instruction_id);
+ html_source->AddLocalizedString("configureFingerprintScannerStepAriaLabel",
+ aria_label_id);
+}
+
+void AddAccountManagerPageStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"accountManagerDescription", IDS_SETTINGS_ACCOUNT_MANAGER_DESCRIPTION},
+ {"accountManagerChildDescription",
+ IDS_SETTINGS_ACCOUNT_MANAGER_CHILD_DESCRIPTION},
+ {"accountListHeader", IDS_SETTINGS_ACCOUNT_MANAGER_LIST_HEADER},
+ {"accountManagerPrimaryAccountTooltip",
+ IDS_SETTINGS_ACCOUNT_MANAGER_PRIMARY_ACCOUNT_TOOLTIP},
+ {"accountManagerEducationAccountLabel",
+ IDS_SETTINGS_ACCOUNT_MANAGER_EDUCATION_ACCOUNT},
+ {"removeAccountLabel", IDS_SETTINGS_ACCOUNT_MANAGER_REMOVE_ACCOUNT_LABEL},
+ {"addAccountLabel", IDS_SETTINGS_ACCOUNT_MANAGER_ADD_ACCOUNT_LABEL},
+ {"addSchoolAccountLabel",
+ IDS_SETTINGS_ACCOUNT_MANAGER_ADD_SCHOOL_ACCOUNT_LABEL},
+ {"accountManagerSecondaryAccountsDisabledText",
+ IDS_SETTINGS_ACCOUNT_MANAGER_SECONDARY_ACCOUNTS_DISABLED_TEXT},
+ {"accountManagerSecondaryAccountsDisabledChildText",
+ IDS_SETTINGS_ACCOUNT_MANAGER_SECONDARY_ACCOUNTS_DISABLED_CHILD_TEXT},
+ {"accountManagerSignedOutAccountName",
+ IDS_SETTINGS_ACCOUNT_MANAGER_SIGNED_OUT_ACCOUNT_PLACEHOLDER},
+ {"accountManagerUnmigratedAccountName",
+ IDS_SETTINGS_ACCOUNT_MANAGER_UNMIGRATED_ACCOUNT_PLACEHOLDER},
+ {"accountManagerMigrationLabel",
+ IDS_SETTINGS_ACCOUNT_MANAGER_MIGRATION_LABEL},
+ {"accountManagerReauthenticationLabel",
+ IDS_SETTINGS_ACCOUNT_MANAGER_REAUTHENTICATION_LABEL},
+ {"accountManagerMigrationTooltip",
+ IDS_SETTINGS_ACCOUNT_MANAGER_MIGRATION_TOOLTIP},
+ {"accountManagerReauthenticationTooltip",
+ IDS_SETTINGS_ACCOUNT_MANAGER_REAUTHENTICATION_TOOLTIP},
+ {"accountManagerMoreActionsTooltip",
+ IDS_SETTINGS_ACCOUNT_MANAGER_MORE_ACTIONS_TOOLTIP},
+ {"accountManagerManagedLabel",
+ IDS_SETTINGS_ACCOUNT_MANAGER_MANAGEMENT_STATUS_MANAGED_ACCOUNT},
+ {"accountManagerUnmanagedLabel",
+ IDS_SETTINGS_ACCOUNT_MANAGER_MANAGEMENT_STATUS_UNMANAGED_ACCOUNT},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+}
+
+void AddSyncControlsStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"syncEverythingCheckboxLabel",
+ IDS_SETTINGS_SYNC_EVERYTHING_CHECKBOX_LABEL},
+ {"wallpaperCheckboxLabel", IDS_OS_SETTINGS_WALLPAPER_CHECKBOX_LABEL},
+ {"osSyncTurnOff", IDS_OS_SETTINGS_SYNC_TURN_OFF},
+ {"osSyncSettingsCheckboxLabel",
+ IDS_OS_SETTINGS_SYNC_SETTINGS_CHECKBOX_LABEL},
+ {"wifiConfigurationsCheckboxLabel",
+ IDS_SETTINGS_WIFI_CONFIGURATIONS_CHECKBOX_LABEL},
+ {"osSyncAppsCheckboxLabel", IDS_OS_SETTINGS_SYNC_APPS_CHECKBOX_LABEL},
+ {"osSyncTurnOn", IDS_OS_SETTINGS_SYNC_TURN_ON},
+ {"osSyncFeatureLabel", IDS_OS_SETTINGS_SYNC_FEATURE_LABEL},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddString(
+ "browserSettingsSyncSetupUrl",
+ base::StrCat({chrome::kChromeUISettingsURL, chrome::kSyncSetupSubPage}));
+}
+
+void AddCrostiniStrings(content::WebUIDataSource* html_source,
+ Profile* profile) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"crostiniPageTitle", IDS_SETTINGS_CROSTINI_TITLE},
+ {"crostiniPageLabel", IDS_SETTINGS_CROSTINI_LABEL},
+ {"crostiniEnable", IDS_SETTINGS_TURN_ON},
+ {"crostiniSharedPaths", IDS_SETTINGS_CROSTINI_SHARED_PATHS},
+ {"crostiniSharedPathsListHeading",
+ IDS_SETTINGS_CROSTINI_SHARED_PATHS_LIST_HEADING},
+ {"crostiniSharedPathsInstructionsAdd",
+ IDS_SETTINGS_CROSTINI_SHARED_PATHS_INSTRUCTIONS_ADD},
+ {"crostiniSharedPathsInstructionsRemove",
+ IDS_SETTINGS_CROSTINI_SHARED_PATHS_INSTRUCTIONS_REMOVE},
+ {"crostiniSharedPathsRemoveSharing",
+ IDS_SETTINGS_CROSTINI_SHARED_PATHS_REMOVE_SHARING},
+ {"crostiniSharedPathsRemoveFailureDialogMessage",
+ IDS_SETTINGS_CROSTINI_SHARED_PATHS_REMOVE_FAILURE_DIALOG_MESSAGE},
+ {"crostiniSharedPathsRemoveFailureDialogTitle",
+ IDS_SETTINGS_CROSTINI_SHARED_PATHS_REMOVE_FAILURE_DIALOG_TITLE},
+ {"crostiniSharedPathsRemoveFailureTryAgain",
+ IDS_SETTINGS_CROSTINI_SHARED_PATHS_REMOVE_FAILURE_TRY_AGAIN},
+ {"crostiniSharedPathsListEmptyMessage",
+ IDS_SETTINGS_CROSTINI_SHARED_PATHS_LIST_EMPTY_MESSAGE},
+ {"crostiniExportImportTitle", IDS_SETTINGS_CROSTINI_EXPORT_IMPORT_TITLE},
+ {"crostiniExport", IDS_SETTINGS_CROSTINI_EXPORT},
+ {"crostiniExportLabel", IDS_SETTINGS_CROSTINI_EXPORT_LABEL},
+ {"crostiniImport", IDS_SETTINGS_CROSTINI_IMPORT},
+ {"crostiniImportLabel", IDS_SETTINGS_CROSTINI_IMPORT_LABEL},
+ {"crostiniImportConfirmationDialogTitle",
+ IDS_SETTINGS_CROSTINI_CONFIRM_IMPORT_DIALOG_WINDOW_TITLE},
+ {"crostiniImportConfirmationDialogMessage",
+ IDS_SETTINGS_CROSTINI_CONFIRM_IMPORT_DIALOG_WINDOW_MESSAGE},
+ {"crostiniImportConfirmationDialogConfirmationButton",
+ IDS_SETTINGS_CROSTINI_IMPORT},
+ {"crostiniRemoveButton", IDS_SETTINGS_CROSTINI_REMOVE_BUTTON},
+ {"crostiniSharedUsbDevicesLabel",
+ IDS_SETTINGS_CROSTINI_SHARED_USB_DEVICES_LABEL},
+ {"crostiniSharedUsbDevicesDescription",
+ IDS_SETTINGS_CROSTINI_SHARED_USB_DEVICES_DESCRIPTION},
+ {"crostiniSharedUsbDevicesExtraDescription",
+ IDS_SETTINGS_CROSTINI_SHARED_USB_DEVICES_EXTRA_DESCRIPTION},
+ {"crostiniSharedUsbDevicesListEmptyMessage",
+ IDS_SETTINGS_CROSTINI_SHARED_USB_DEVICES_LIST_EMPTY_MESSAGE},
+ {"crostiniArcAdbTitle", IDS_SETTINGS_CROSTINI_ARC_ADB_TITLE},
+ {"crostiniArcAdbDescription", IDS_SETTINGS_CROSTINI_ARC_ADB_DESCRIPTION},
+ {"crostiniArcAdbLabel", IDS_SETTINGS_CROSTINI_ARC_ADB_LABEL},
+ {"crostiniArcAdbRestartButton",
+ IDS_SETTINGS_CROSTINI_ARC_ADB_RESTART_BUTTON},
+ {"crostiniArcAdbConfirmationTitleEnable",
+ IDS_SETTINGS_CROSTINI_ARC_ADB_CONFIRMATION_TITLE_ENABLE},
+ {"crostiniArcAdbConfirmationTitleDisable",
+ IDS_SETTINGS_CROSTINI_ARC_ADB_CONFIRMATION_TITLE_DISABLE},
+ {"crostiniContainerUpgrade",
+ IDS_SETTINGS_CROSTINI_CONTAINER_UPGRADE_MESSAGE},
+ {"crostiniContainerUpgradeSubtext",
+ IDS_SETTINGS_CROSTINI_CONTAINER_UPGRADE_SUBTEXT},
+ {"crostiniContainerUpgradeButton",
+ IDS_SETTINGS_CROSTINI_CONTAINER_UPGRADE_BUTTON},
+ {"crostiniPortForwarding", IDS_SETTINGS_CROSTINI_PORT_FORWARDING},
+ {"crostiniPortForwardingDescription",
+ IDS_SETTINGS_CROSTINI_PORT_FORWARDING_DESCRIPTION},
+ {"crostiniPortForwardingNoPorts",
+ IDS_SETTINGS_CROSTINI_PORT_FORWARDING_NO_PORTS},
+ {"crostiniPortForwardingTableTitle",
+ IDS_SETTINGS_CROSTINI_PORT_FORWARDING_TABLE_TITLE},
+ {"crostiniPortForwardingListPortNumber",
+ IDS_SETTINGS_CROSTINI_PORT_FORWARDING_LIST_PORT_NUMBER},
+ {"crostiniPortForwardingListLabel",
+ IDS_SETTINGS_CROSTINI_PORT_FORWARDING_LIST_LABEL},
+ {"crostiniPortForwardingAddPortButton",
+ IDS_SETTINGS_CROSTINI_PORT_FORWARDING_ADD_PORT_BUTTON},
+ {"crostiniPortForwardingAddPortButtonDescription",
+ IDS_SETTINGS_CROSTINI_PORT_FORWARDING_ADD_PORT_BUTTON_DESCRIPTION},
+ {"crostiniPortForwardingAddPortDialogTitle",
+ IDS_SETTINGS_CROSTINI_PORT_FORWARDING_ADD_PORT_DIALOG_TITLE},
+ {"crostiniPortForwardingAddPortDialogLabel",
+ IDS_SETTINGS_CROSTINI_PORT_FORWARDING_ADD_PORT_DIALOG_LABEL},
+ {"crostiniPortForwardingTCP", IDS_SETTINGS_CROSTINI_PORT_FORWARDING_TCP},
+ {"crostiniPortForwardingUDP", IDS_SETTINGS_CROSTINI_PORT_FORWARDING_UDP},
+ {"crostiniPortForwardingAddError",
+ IDS_SETTINGS_CROSTINI_PORT_FORWARDING_ADD_ERROR},
+ {"crostiniDiskResizeTitle", IDS_SETTINGS_CROSTINI_DISK_RESIZE_TITLE},
+ {"crostiniDiskResizeShowButton",
+ IDS_SETTINGS_CROSTINI_DISK_RESIZE_SHOW_BUTTON},
+ {"crostiniDiskResizeLabel", IDS_SETTINGS_CROSTINI_DISK_RESIZE_LABEL},
+ {"crostiniDiskResizeUnsupported",
+ IDS_SETTINGS_CROSTINI_DISK_RESIZE_UNSUPPORTED},
+ {"crostiniDiskResizeLoading", IDS_SETTINGS_CROSTINI_DISK_RESIZE_LOADING},
+ {"crostiniDiskResizeError", IDS_SETTINGS_CROSTINI_DISK_RESIZE_ERROR},
+ {"crostiniDiskResizeErrorRetry",
+ IDS_SETTINGS_CROSTINI_DISK_RESIZE_ERROR_RETRY},
+ {"crostiniDiskResizeCancel", IDS_SETTINGS_CROSTINI_DISK_RESIZE_CANCEL},
+ {"crostiniDiskResizeGoButton",
+ IDS_SETTINGS_CROSTINI_DISK_RESIZE_GO_BUTTON},
+ {"crostiniDiskResizeInProgress",
+ IDS_SETTINGS_CROSTINI_DISK_RESIZE_IN_PROGRESS},
+ {"crostiniDiskResizeResizingError",
+ IDS_SETTINGS_CROSTINI_DISK_RESIZE_RESIZING_ERROR},
+ {"crostiniDiskResizeDone", IDS_SETTINGS_CROSTINI_DISK_RESIZE_DONE},
+ {"crostiniMicTitle", IDS_SETTINGS_CROSTINI_MIC_TITLE},
+ {"crostiniMicDialogTitle", IDS_SETTINGS_CROSTINI_MIC_DIALOG_TITLE},
+ {"crostiniMicDialogLabel", IDS_SETTINGS_CROSTINI_MIC_DIALOG_LABEL},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+ html_source->AddString(
+ "crostiniSubtext",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_CROSTINI_SUBTEXT, ui::GetChromeOSDeviceName(),
+ GetHelpUrlWithBoard(chrome::kLinuxAppsLearnMoreURL)));
+ html_source->AddString(
+ "crostiniArcAdbPowerwashRequiredSublabel",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_CROSTINI_ARC_ADB_POWERWASH_REQUIRED_SUBLABEL,
+ base::ASCIIToUTF16(chrome::kArcAdbSideloadingLearnMoreURL)));
+ html_source->AddString("crostiniRemove", l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_CROSTINI_REMOVE,
+ ui::GetChromeOSDeviceName()));
+ html_source->AddString(
+ "crostiniArcAdbConfirmationMessageEnable",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_CROSTINI_ARC_ADB_CONFIRMATION_MESSAGE_ENABLE,
+ ui::GetChromeOSDeviceName()));
+ html_source->AddString(
+ "crostiniArcAdbConfirmationMessageDisable",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_CROSTINI_ARC_ADB_CONFIRMATION_MESSAGE_DISABLE,
+ ui::GetChromeOSDeviceName()));
+ html_source->AddString(
+ "crostiniSharedPathsInstructionsLocate",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_CROSTINI_SHARED_PATHS_INSTRUCTIONS_LOCATE,
+ base::ASCIIToUTF16(
+ crostini::ContainerChromeOSBaseDirectory().value())));
+ html_source->AddBoolean(
+ "showCrostiniExportImport",
+ crostini::CrostiniFeatures::Get()->IsExportImportUIAllowed(profile));
+ html_source->AddBoolean("arcAdbSideloadingSupported",
+ base::FeatureList::IsEnabled(
+ chromeos::features::kArcAdbSideloadingFeature));
+ html_source->AddBoolean("showCrostiniPortForwarding",
+ base::FeatureList::IsEnabled(
+ chromeos::features::kCrostiniPortForwarding));
+ html_source->AddBoolean("isOwnerProfile",
+ chromeos::ProfileHelper::IsOwnerProfile(profile));
+ html_source->AddBoolean("isEnterpriseManaged",
+ IsDeviceManaged() || IsProfileManaged(profile));
+ html_source->AddBoolean(
+ "canChangeAdbSideloading",
+ crostini::CrostiniFeatures::Get()->CanChangeAdbSideloading(profile));
+ html_source->AddBoolean("showCrostiniContainerUpgrade",
+ crostini::ShouldAllowContainerUpgrade(profile));
+ html_source->AddBoolean(
+ "showCrostiniDiskResize",
+ base::FeatureList::IsEnabled(chromeos::features::kCrostiniDiskResizing));
+ html_source->AddBoolean("showCrostiniMic",
+ base::FeatureList::IsEnabled(
+ chromeos::features::kCrostiniShowMicSetting));
+}
+
+void AddPluginVmStrings(content::WebUIDataSource* html_source,
+ Profile* profile) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"pluginVmPageTitle", IDS_SETTINGS_PLUGIN_VM_PAGE_TITLE},
+ {"pluginVmPageLabel", IDS_SETTINGS_PLUGIN_VM_PAGE_LABEL},
+ {"pluginVmPageSubtext", IDS_SETTINGS_PLUGIN_VM_PAGE_SUBTEXT},
+ {"pluginVmPageEnable", IDS_SETTINGS_TURN_ON},
+ {"pluginVmPrinterAccess", IDS_SETTINGS_PLUGIN_VM_PRINTER_ACCESS},
+ {"pluginVmSharedPaths", IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS},
+ {"pluginVmSharedPathsListHeading",
+ IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS_LIST_HEADING},
+ {"pluginVmSharedPathsInstructionsAdd",
+ IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS_INSTRUCTIONS_ADD},
+ {"pluginVmSharedPathsInstructionsRemove",
+ IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS_INSTRUCTIONS_REMOVE},
+ {"pluginVmSharedPathsRemoveSharing",
+ IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS_REMOVE_SHARING},
+ {"pluginVmRemove", IDS_SETTINGS_PLUGIN_VM_REMOVE_LABEL},
+ {"pluginVmRemoveButton", IDS_SETTINGS_PLUGIN_VM_REMOVE_BUTTON},
+ {"pluginVmRemoveConfirmationDialogMessage",
+ IDS_SETTINGS_PLUGIN_VM_CONFIRM_REMOVE_DIALOG_BODY},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+}
+
+void AddAndroidAppStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"androidAppsPageLabel", IDS_SETTINGS_ANDROID_APPS_LABEL},
+ {"androidAppsEnable", IDS_SETTINGS_TURN_ON},
+ {"androidAppsManageApps", IDS_SETTINGS_ANDROID_APPS_MANAGE_APPS},
+ {"androidAppsRemove", IDS_SETTINGS_ANDROID_APPS_REMOVE},
+ {"androidAppsRemoveButton", IDS_SETTINGS_ANDROID_APPS_REMOVE_BUTTON},
+ {"androidAppsDisableDialogTitle",
+ IDS_SETTINGS_ANDROID_APPS_DISABLE_DIALOG_TITLE},
+ {"androidAppsDisableDialogMessage",
+ IDS_SETTINGS_ANDROID_APPS_DISABLE_DIALOG_MESSAGE},
+ {"androidAppsDisableDialogRemove",
+ IDS_SETTINGS_ANDROID_APPS_DISABLE_DIALOG_REMOVE},
+ {"androidAppsManageAppLinks", IDS_SETTINGS_ANDROID_APPS_MANAGE_APP_LINKS},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+ html_source->AddLocalizedString("androidAppsPageTitle",
+ arc::IsPlayStoreAvailable()
+ ? IDS_SETTINGS_ANDROID_APPS_TITLE
+ : IDS_SETTINGS_ANDROID_SETTINGS_TITLE);
+ html_source->AddString(
+ "androidAppsSubtext",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_ANDROID_APPS_SUBTEXT, ui::GetChromeOSDeviceName(),
+ GetHelpUrlWithBoard(chrome::kAndroidAppsLearnMoreURL)));
+}
+
+void AddAppsStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"appsPageTitle", IDS_SETTINGS_APPS_TITLE},
+ {"appManagementTitle", IDS_SETTINGS_APPS_LINK_TEXT},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+}
+
+void AddAppManagementStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"appManagementAppInstalledByPolicyLabel",
+ IDS_APP_MANAGEMENT_POLICY_APP_POLICY_STRING},
+ {"appManagementCameraPermissionLabel", IDS_APP_MANAGEMENT_CAMERA},
+ {"appManagementContactsPermissionLabel", IDS_APP_MANAGEMENT_CONTACTS},
+ {"appManagementLocationPermissionLabel", IDS_APP_MANAGEMENT_LOCATION},
+ {"appManagementMicrophonePermissionLabel", IDS_APP_MANAGEMENT_MICROPHONE},
+ {"appManagementMoreSettingsLabel", IDS_APP_MANAGEMENT_MORE_SETTINGS},
+ {"appManagementNoAppsFound", IDS_APP_MANAGEMENT_NO_APPS_FOUND},
+ {"appManagementNoPermissions",
+ IDS_APPLICATION_INFO_APP_NO_PERMISSIONS_TEXT},
+ {"appManagementNotificationsLabel", IDS_APP_MANAGEMENT_NOTIFICATIONS},
+ {"appManagementPermissionsLabel", IDS_APP_MANAGEMENT_PERMISSIONS},
+ {"appManagementPinToShelfLabel", IDS_APP_MANAGEMENT_PIN_TO_SHELF},
+ {"appManagementSearchPrompt", IDS_APP_MANAGEMENT_SEARCH_PROMPT},
+ {"appManagementStoragePermissionLabel", IDS_APP_MANAGEMENT_STORAGE},
+ {"appManagementUninstallLabel", IDS_APP_MANAGEMENT_UNINSTALL_APP},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+}
+
+void AddParentalControlStrings(content::WebUIDataSource* html_source,
+ Profile* profile) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"parentalControlsPageTitle", IDS_SETTINGS_PARENTAL_CONTROLS_PAGE_TITLE},
+ {"parentalControlsPageSetUpLabel",
+ IDS_SETTINGS_PARENTAL_CONTROLS_PAGE_SET_UP_LABEL},
+ {"parentalControlsPageViewSettingsLabel",
+ IDS_SETTINGS_PARENTAL_CONTROLS_PAGE_VIEW_SETTINGS_LABEL},
+ {"parentalControlsPageConnectToInternetLabel",
+ IDS_SETTINGS_PARENTAL_CONTROLS_PAGE_CONNECT_TO_INTERNET_LABEL},
+ {"parentalControlsSetUpButtonLabel",
+ IDS_SETTINGS_PARENTAL_CONTROLS_SET_UP_BUTTON_LABEL},
+ {"parentalControlsSetUpButtonRole",
+ IDS_SETTINGS_PARENTAL_CONTROLS_SET_UP_BUTTON_ROLE},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddBoolean(
+ "isChild", user_manager::UserManager::Get()->IsLoggedInAsChildUser());
+
+ if (user_manager::UserManager::Get()->IsLoggedInAsChildUser()) {
+ SupervisedUserService* supervised_user_service =
+ SupervisedUserServiceFactory::GetForProfile(profile);
+ std::string custodian = supervised_user_service->GetCustodianName();
+ std::string second_custodian =
+ supervised_user_service->GetSecondCustodianName();
+
+ base::string16 child_managed_tooltip;
+ if (second_custodian.empty()) {
+ child_managed_tooltip = l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_ACCOUNT_MANAGER_CHILD_MANAGED_BY_ONE_PARENT_TOOLTIP,
+ base::UTF8ToUTF16(custodian));
+ } else {
+ child_managed_tooltip = l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_ACCOUNT_MANAGER_CHILD_MANAGED_BY_TWO_PARENTS_TOOLTIP,
+ base::UTF8ToUTF16(custodian), base::UTF8ToUTF16(second_custodian));
+ }
+ html_source->AddString("accountManagerPrimaryAccountChildManagedTooltip",
+ child_managed_tooltip);
+ }
+}
+
+void AddBluetoothStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"bluetoothConnected", IDS_SETTINGS_BLUETOOTH_CONNECTED},
+ {"bluetoothConnectedWithBattery",
+ IDS_SETTINGS_BLUETOOTH_CONNECTED_WITH_BATTERY},
+ {"bluetoothConnecting", IDS_SETTINGS_BLUETOOTH_CONNECTING},
+ {"bluetoothDeviceListPaired", IDS_SETTINGS_BLUETOOTH_DEVICE_LIST_PAIRED},
+ {"bluetoothDeviceListUnpaired",
+ IDS_SETTINGS_BLUETOOTH_DEVICE_LIST_UNPAIRED},
+ {"bluetoothConnect", IDS_SETTINGS_BLUETOOTH_CONNECT},
+ {"bluetoothDisconnect", IDS_SETTINGS_BLUETOOTH_DISCONNECT},
+ {"bluetoothToggleA11yLabel",
+ IDS_SETTINGS_BLUETOOTH_TOGGLE_ACCESSIBILITY_LABEL},
+ {"bluetoothExpandA11yLabel",
+ IDS_SETTINGS_BLUETOOTH_EXPAND_ACCESSIBILITY_LABEL},
+ {"bluetoothNoDevices", IDS_SETTINGS_BLUETOOTH_NO_DEVICES},
+ {"bluetoothNoDevicesFound", IDS_SETTINGS_BLUETOOTH_NO_DEVICES_FOUND},
+ {"bluetoothNotConnected", IDS_SETTINGS_BLUETOOTH_NOT_CONNECTED},
+ {"bluetoothPageTitle", IDS_SETTINGS_BLUETOOTH},
+ {"bluetoothPairDevicePageTitle",
+ IDS_SETTINGS_BLUETOOTH_PAIR_DEVICE_TITLE},
+ {"bluetoothRemove", IDS_SETTINGS_BLUETOOTH_REMOVE},
+ {"bluetoothPrimaryUserControlled",
+ IDS_SETTINGS_BLUETOOTH_PRIMARY_USER_CONTROLLED},
+ {"bluetoothDeviceType_computer",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_COMPUTER},
+ {"bluetoothDeviceType_phone",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_PHONE},
+ {"bluetoothDeviceType_modem",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_MODEM},
+ {"bluetoothDeviceType_audio",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_AUDIO},
+ {"bluetoothDeviceType_carAudio",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_CAR_AUDIO},
+ {"bluetoothDeviceType_video",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_VIDEO},
+ {"bluetoothDeviceType_peripheral",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_PERIPHERAL},
+ {"bluetoothDeviceType_joystick",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_JOYSTICK},
+ {"bluetoothDeviceType_gamepad",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_GAMEPAD},
+ {"bluetoothDeviceType_keyboard",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_KEYBOARD},
+ {"bluetoothDeviceType_mouse",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_MOUSE},
+ {"bluetoothDeviceType_tablet",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_TABLET},
+ {"bluetoothDeviceType_keyboardMouseCombo",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_KEYBOARD_MOUSE_COMBO},
+ {"bluetoothDeviceType_unknown",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_UNKNOWN},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+ chromeos::bluetooth_dialog::AddLocalizedStrings(html_source);
+}
+
+void AddChromeOSUserStrings(content::WebUIDataSource* html_source,
+ Profile* profile) {
+ user_manager::UserManager* user_manager = user_manager::UserManager::Get();
+
+ const user_manager::User* user =
+ chromeos::ProfileHelper::Get()->GetUserByProfile(profile);
+ const user_manager::User* primary_user = user_manager->GetPrimaryUser();
+ std::string primary_user_email = primary_user->GetAccountId().GetUserEmail();
+ html_source->AddString("primaryUserEmail", primary_user_email);
+ html_source->AddString("browserSettingsBannerText",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_BROWSER_SETTINGS_BANNER,
+ base::ASCIIToUTF16(chrome::kChromeUISettingsURL)));
+ html_source->AddBoolean("isActiveDirectoryUser",
+ user && user->IsActiveDirectoryUser());
+ html_source->AddBoolean(
+ "isSecondaryUser",
+ user && user->GetAccountId() != primary_user->GetAccountId());
+ html_source->AddString(
+ "secondaryUserBannerText",
+ l10n_util::GetStringFUTF16(IDS_SETTINGS_SECONDARY_USER_BANNER,
+ base::ASCIIToUTF16(primary_user_email)));
+
+ if (!IsDeviceManaged() && !user_manager->IsCurrentUserOwner()) {
+ html_source->AddString("ownerEmail",
+ user_manager->GetOwnerAccountId().GetUserEmail());
+ }
+}
+
+void AddDevicePointersStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kPointersStrings[] = {
+ {"mouseTitle", IDS_SETTINGS_MOUSE_TITLE},
+ {"touchpadTitle", IDS_SETTINGS_TOUCHPAD_TITLE},
+ {"mouseAndTouchpadTitle", IDS_SETTINGS_MOUSE_AND_TOUCHPAD_TITLE},
+ {"touchpadTapToClickEnabledLabel",
+ IDS_SETTINGS_TOUCHPAD_TAP_TO_CLICK_ENABLED_LABEL},
+ {"touchpadSpeed", IDS_SETTINGS_TOUCHPAD_SPEED_LABEL},
+ {"pointerSlow", IDS_SETTINGS_POINTER_SPEED_SLOW_LABEL},
+ {"pointerFast", IDS_SETTINGS_POINTER_SPEED_FAST_LABEL},
+ {"mouseScrollSpeed", IDS_SETTINGS_MOUSE_SCROLL_SPEED_LABEL},
+ {"mouseSpeed", IDS_SETTINGS_MOUSE_SPEED_LABEL},
+ {"mouseSwapButtons", IDS_SETTINGS_MOUSE_SWAP_BUTTONS_LABEL},
+ {"mouseReverseScroll", IDS_SETTINGS_MOUSE_REVERSE_SCROLL_LABEL},
+ {"mouseAccelerationLabel", IDS_SETTINGS_MOUSE_ACCELERATION_LABEL},
+ {"mouseScrollAccelerationLabel",
+ IDS_SETTINGS_MOUSE_SCROLL_ACCELERATION_LABEL},
+ {"touchpadAccelerationLabel", IDS_SETTINGS_TOUCHPAD_ACCELERATION_LABEL},
+ {"touchpadScrollAccelerationLabel",
+ IDS_SETTINGS_TOUCHPAD_SCROLL_ACCELERATION_LABEL},
+ {"touchpadScrollSpeed", IDS_SETTINGS_TOUCHPAD_SCROLL_SPEED_LABEL},
+ };
+ AddLocalizedStringsBulk(html_source, kPointersStrings);
+
+ html_source->AddString("naturalScrollLearnMoreLink",
+ GetHelpUrlWithBoard(chrome::kNaturalScrollHelpURL));
+
+ html_source->AddBoolean(
+ "allowDisableMouseAcceleration",
+ base::FeatureList::IsEnabled(::features::kAllowDisableMouseAcceleration));
+ html_source->AddBoolean(
+ "allowScrollSettings",
+ base::FeatureList::IsEnabled(features::kAllowScrollSettings));
+}
+
+void AddDeviceKeyboardStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString keyboard_strings[] = {
+ {"keyboardTitle", IDS_SETTINGS_KEYBOARD_TITLE},
+ {"keyboardKeyCtrl", IDS_SETTINGS_KEYBOARD_KEY_LEFT_CTRL},
+ {"keyboardKeyAlt", IDS_SETTINGS_KEYBOARD_KEY_LEFT_ALT},
+ {"keyboardKeyCapsLock", IDS_SETTINGS_KEYBOARD_KEY_CAPS_LOCK},
+ {"keyboardKeyCommand", IDS_SETTINGS_KEYBOARD_KEY_COMMAND},
+ {"keyboardKeyDiamond", IDS_SETTINGS_KEYBOARD_KEY_DIAMOND},
+ {"keyboardKeyEscape", IDS_SETTINGS_KEYBOARD_KEY_ESCAPE},
+ {"keyboardKeyBackspace", IDS_SETTINGS_KEYBOARD_KEY_BACKSPACE},
+ {"keyboardKeyAssistant", IDS_SETTINGS_KEYBOARD_KEY_ASSISTANT},
+ {"keyboardKeyDisabled", IDS_SETTINGS_KEYBOARD_KEY_DISABLED},
+ {"keyboardKeyExternalCommand",
+ IDS_SETTINGS_KEYBOARD_KEY_EXTERNAL_COMMAND},
+ {"keyboardKeyExternalMeta", IDS_SETTINGS_KEYBOARD_KEY_EXTERNAL_META},
+ {"keyboardKeyMeta", IDS_SETTINGS_KEYBOARD_KEY_META},
+ {"keyboardSendFunctionKeys", IDS_SETTINGS_KEYBOARD_SEND_FUNCTION_KEYS},
+ {"keyboardEnableAutoRepeat", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_ENABLE},
+ {"keyRepeatDelay", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_DELAY},
+ {"keyRepeatDelayLong", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_DELAY_LONG},
+ {"keyRepeatDelayShort", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_DELAY_SHORT},
+ {"keyRepeatRate", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_RATE},
+ {"keyRepeatRateSlow", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_RATE_SLOW},
+ {"keyRepeatRateFast", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_FAST},
+ {"showKeyboardShortcutViewer",
+ IDS_SETTINGS_KEYBOARD_SHOW_SHORTCUT_VIEWER},
+ {"keyboardShowLanguageAndInput",
+ IDS_SETTINGS_KEYBOARD_SHOW_LANGUAGE_AND_INPUT},
+ };
+ AddLocalizedStringsBulk(html_source, keyboard_strings);
+
+ html_source->AddLocalizedString("keyboardKeySearch",
+ ui::DeviceUsesKeyboardLayout2()
+ ? IDS_SETTINGS_KEYBOARD_KEY_LAUNCHER
+ : IDS_SETTINGS_KEYBOARD_KEY_SEARCH);
+ html_source->AddLocalizedString(
+ "keyboardSendFunctionKeysDescription",
+ ui::DeviceUsesKeyboardLayout2()
+ ? IDS_SETTINGS_KEYBOARD_SEND_FUNCTION_KEYS_LAYOUT2_DESCRIPTION
+ : IDS_SETTINGS_KEYBOARD_SEND_FUNCTION_KEYS_DESCRIPTION);
+}
+
+void AddDeviceStylusStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kStylusStrings[] = {
+ {"stylusTitle", IDS_SETTINGS_STYLUS_TITLE},
+ {"stylusEnableStylusTools", IDS_SETTINGS_STYLUS_ENABLE_STYLUS_TOOLS},
+ {"stylusAutoOpenStylusTools", IDS_SETTINGS_STYLUS_AUTO_OPEN_STYLUS_TOOLS},
+ {"stylusFindMoreAppsPrimary", IDS_SETTINGS_STYLUS_FIND_MORE_APPS_PRIMARY},
+ {"stylusFindMoreAppsSecondary",
+ IDS_SETTINGS_STYLUS_FIND_MORE_APPS_SECONDARY},
+ {"stylusNoteTakingApp", IDS_SETTINGS_STYLUS_NOTE_TAKING_APP_LABEL},
+ {"stylusNoteTakingAppEnabledOnLockScreen",
+ IDS_SETTINGS_STYLUS_NOTE_TAKING_APP_LOCK_SCREEN_CHECKBOX},
+ {"stylusNoteTakingAppKeepsLastNoteOnLockScreen",
+ IDS_SETTINGS_STYLUS_NOTE_TAKING_APP_KEEP_LATEST_NOTE},
+ {"stylusNoteTakingAppLockScreenSettingsHeader",
+ IDS_SETTINGS_STYLUS_LOCK_SCREEN_NOTES_TITLE},
+ {"stylusNoteTakingAppNoneAvailable",
+ IDS_SETTINGS_STYLUS_NOTE_TAKING_APP_NONE_AVAILABLE},
+ {"stylusNoteTakingAppWaitingForAndroid",
+ IDS_SETTINGS_STYLUS_NOTE_TAKING_APP_WAITING_FOR_ANDROID}};
+ AddLocalizedStringsBulk(html_source, kStylusStrings);
+}
+
+void AddDeviceDisplayStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kDisplayStrings[] = {
+ {"displayTitle", IDS_SETTINGS_DISPLAY_TITLE},
+ {"displayArrangementText", IDS_SETTINGS_DISPLAY_ARRANGEMENT_TEXT},
+ {"displayArrangementTitle", IDS_SETTINGS_DISPLAY_ARRANGEMENT_TITLE},
+ {"displayMirror", IDS_SETTINGS_DISPLAY_MIRROR},
+ {"displayMirrorDisplayName", IDS_SETTINGS_DISPLAY_MIRROR_DISPLAY_NAME},
+ {"displayAmbientColorTitle", IDS_SETTINGS_DISPLAY_AMBIENT_COLOR_TITLE},
+ {"displayAmbientColorSubtitle",
+ IDS_SETTINGS_DISPLAY_AMBIENT_COLOR_SUBTITLE},
+ {"displayNightLightLabel", IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_LABEL},
+ {"displayNightLightOnAtSunset",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_ON_AT_SUNSET},
+ {"displayNightLightOffAtSunrise",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_OFF_AT_SUNRISE},
+ {"displayNightLightScheduleCustom",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_CUSTOM},
+ {"displayNightLightScheduleLabel",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_LABEL},
+ {"displayNightLightScheduleNever",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_NEVER},
+ {"displayNightLightScheduleSunsetToSunRise",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_SUNSET_TO_SUNRISE},
+ {"displayNightLightStartTime",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_START_TIME},
+ {"displayNightLightStopTime", IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_STOP_TIME},
+ {"displayNightLightText", IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEXT},
+ {"displayNightLightTemperatureLabel",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEMPERATURE_LABEL},
+ {"displayNightLightTempSliderMaxLabel",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEMP_SLIDER_MAX_LABEL},
+ {"displayNightLightTempSliderMinLabel",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEMP_SLIDER_MIN_LABEL},
+ {"displayUnifiedDesktop", IDS_SETTINGS_DISPLAY_UNIFIED_DESKTOP},
+ {"displayUnifiedDesktopOn", IDS_SETTINGS_DISPLAY_UNIFIED_DESKTOP_ON},
+ {"displayUnifiedDesktopOff", IDS_SETTINGS_DISPLAY_UNIFIED_DESKTOP_OFF},
+ {"displayResolutionTitle", IDS_SETTINGS_DISPLAY_RESOLUTION_TITLE},
+ {"displayResolutionText", IDS_SETTINGS_DISPLAY_RESOLUTION_TEXT},
+ {"displayResolutionTextBest", IDS_SETTINGS_DISPLAY_RESOLUTION_TEXT_BEST},
+ {"displayResolutionTextNative",
+ IDS_SETTINGS_DISPLAY_RESOLUTION_TEXT_NATIVE},
+ {"displayResolutionSublabel", IDS_SETTINGS_DISPLAY_RESOLUTION_SUBLABEL},
+ {"displayResolutionMenuItem", IDS_SETTINGS_DISPLAY_RESOLUTION_MENU_ITEM},
+ {"displayResolutionInterlacedMenuItem",
+ IDS_SETTINGS_DISPLAY_RESOLUTION_INTERLACED_MENU_ITEM},
+ {"displayZoomTitle", IDS_SETTINGS_DISPLAY_ZOOM_TITLE},
+ {"displayZoomSublabel", IDS_SETTINGS_DISPLAY_ZOOM_SUBLABEL},
+ {"displayZoomValue", IDS_SETTINGS_DISPLAY_ZOOM_VALUE},
+ {"displayZoomLogicalResolutionText",
+ IDS_SETTINGS_DISPLAY_ZOOM_LOGICAL_RESOLUTION_TEXT},
+ {"displayZoomNativeLogicalResolutionNativeText",
+ IDS_SETTINGS_DISPLAY_ZOOM_LOGICAL_RESOLUTION_NATIVE_TEXT},
+ {"displayZoomLogicalResolutionDefaultText",
+ IDS_SETTINGS_DISPLAY_ZOOM_LOGICAL_RESOLUTION_DEFAULT_TEXT},
+ {"displaySizeSliderMinLabel", IDS_SETTINGS_DISPLAY_ZOOM_SLIDER_MINIMUM},
+ {"displaySizeSliderMaxLabel", IDS_SETTINGS_DISPLAY_ZOOM_SLIDER_MAXIMUM},
+ {"displayScreenTitle", IDS_SETTINGS_DISPLAY_SCREEN},
+ {"displayScreenExtended", IDS_SETTINGS_DISPLAY_SCREEN_EXTENDED},
+ {"displayScreenPrimary", IDS_SETTINGS_DISPLAY_SCREEN_PRIMARY},
+ {"displayOrientation", IDS_SETTINGS_DISPLAY_ORIENTATION},
+ {"displayOrientationStandard", IDS_SETTINGS_DISPLAY_ORIENTATION_STANDARD},
+ {"displayOrientationAutoRotate",
+ IDS_SETTINGS_DISPLAY_ORIENTATION_AUTO_ROTATE},
+ {"displayOverscanPageText", IDS_SETTINGS_DISPLAY_OVERSCAN_TEXT},
+ {"displayOverscanPageTitle", IDS_SETTINGS_DISPLAY_OVERSCAN_TITLE},
+ {"displayOverscanSubtitle", IDS_SETTINGS_DISPLAY_OVERSCAN_SUBTITLE},
+ {"displayOverscanInstructions",
+ IDS_SETTINGS_DISPLAY_OVERSCAN_INSTRUCTIONS},
+ {"displayOverscanResize", IDS_SETTINGS_DISPLAY_OVERSCAN_RESIZE},
+ {"displayOverscanPosition", IDS_SETTINGS_DISPLAY_OVERSCAN_POSITION},
+ {"displayOverscanReset", IDS_SETTINGS_DISPLAY_OVERSCAN_RESET},
+ {"displayTouchCalibrationTitle",
+ IDS_SETTINGS_DISPLAY_TOUCH_CALIBRATION_TITLE},
+ {"displayTouchCalibrationText",
+ IDS_SETTINGS_DISPLAY_TOUCH_CALIBRATION_TEXT}};
+ AddLocalizedStringsBulk(html_source, kDisplayStrings);
+
+ base::CommandLine& cmd = *base::CommandLine::ForCurrentProcess();
+ html_source->AddBoolean("unifiedDesktopAvailable",
+ cmd.HasSwitch(::switches::kEnableUnifiedDesktop));
+
+ html_source->AddBoolean("listAllDisplayModes",
+ display::features::IsListAllDisplayModesEnabled());
+
+ html_source->AddBoolean("deviceSupportsAmbientColor",
+ ash::features::IsAllowAmbientEQEnabled());
+
+ html_source->AddBoolean(
+ "enableTouchCalibrationSetting",
+ cmd.HasSwitch(chromeos::switches::kEnableTouchCalibrationSetting));
+
+ html_source->AddBoolean("hasExternalTouchDevice",
+ display::HasExternalTouchscreenDevice());
+}
+
+void AddDeviceStorageStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kStorageStrings[] = {
+ {"storageTitle", IDS_SETTINGS_STORAGE_TITLE},
+ {"storageItemInUse", IDS_SETTINGS_STORAGE_ITEM_IN_USE},
+ {"storageItemAvailable", IDS_SETTINGS_STORAGE_ITEM_AVAILABLE},
+ {"storageItemSystem", IDS_SETTINGS_STORAGE_ITEM_SYSTEM},
+ {"storageItemMyFiles", IDS_SETTINGS_STORAGE_ITEM_MY_FILES},
+ {"storageItemBrowsingData", IDS_SETTINGS_STORAGE_ITEM_BROWSING_DATA},
+ {"storageItemApps", IDS_SETTINGS_STORAGE_ITEM_APPS},
+ {"storageItemCrostini", IDS_SETTINGS_STORAGE_ITEM_CROSTINI},
+ {"storageItemOtherUsers", IDS_SETTINGS_STORAGE_ITEM_OTHER_USERS},
+ {"storageSizeComputing", IDS_SETTINGS_STORAGE_SIZE_CALCULATING},
+ {"storageSizeUnknown", IDS_SETTINGS_STORAGE_SIZE_UNKNOWN},
+ {"storageSpaceLowMessageTitle",
+ IDS_SETTINGS_STORAGE_SPACE_LOW_MESSAGE_TITLE},
+ {"storageSpaceLowMessageLine1",
+ IDS_SETTINGS_STORAGE_SPACE_LOW_MESSAGE_LINE_1},
+ {"storageSpaceLowMessageLine2",
+ IDS_SETTINGS_STORAGE_SPACE_LOW_MESSAGE_LINE_2},
+ {"storageSpaceCriticallyLowMessageTitle",
+ IDS_SETTINGS_STORAGE_SPACE_CRITICALLY_LOW_MESSAGE_TITLE},
+ {"storageSpaceCriticallyLowMessageLine1",
+ IDS_SETTINGS_STORAGE_SPACE_CRITICALLY_LOW_MESSAGE_LINE_1},
+ {"storageSpaceCriticallyLowMessageLine2",
+ IDS_SETTINGS_STORAGE_SPACE_CRITICALLY_LOW_MESSAGE_LINE_2},
+ {"storageExternal", IDS_SETTINGS_STORAGE_EXTERNAL},
+ {"storageExternalStorageEmptyListHeader",
+ IDS_SETTINGS_STORAGE_EXTERNAL_STORAGE_EMPTY_LIST_HEADER},
+ {"storageExternalStorageListHeader",
+ IDS_SETTINGS_STORAGE_EXTERNAL_STORAGE_LIST_HEADER},
+ {"storageOverviewAriaLabel", IDS_SETTINGS_STORAGE_OVERVIEW_ARIA_LABEL}};
+ AddLocalizedStringsBulk(html_source, kStorageStrings);
+
+ html_source->AddString(
+ "storageAndroidAppsExternalDrivesNote",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_STORAGE_ANDROID_APPS_ACCESS_EXTERNAL_DRIVES_NOTE,
+ base::ASCIIToUTF16(chrome::kArcExternalStorageLearnMoreURL)));
+}
+
+void AddDevicePowerStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kPowerStrings[] = {
+ {"powerTitle", IDS_SETTINGS_POWER_TITLE},
+ {"powerSourceLabel", IDS_SETTINGS_POWER_SOURCE_LABEL},
+ {"powerSourceBattery", IDS_SETTINGS_POWER_SOURCE_BATTERY},
+ {"powerSourceAcAdapter", IDS_SETTINGS_POWER_SOURCE_AC_ADAPTER},
+ {"powerSourceLowPowerCharger",
+ IDS_SETTINGS_POWER_SOURCE_LOW_POWER_CHARGER},
+ {"calculatingPower", IDS_SETTINGS_POWER_SOURCE_CALCULATING},
+ {"powerIdleLabel", IDS_SETTINGS_POWER_IDLE_LABEL},
+ {"powerIdleWhileChargingLabel",
+ IDS_SETTINGS_POWER_IDLE_WHILE_CHARGING_LABEL},
+ {"powerIdleWhileChargingAriaLabel",
+ IDS_SETTINGS_POWER_IDLE_WHILE_CHARGING_ARIA_LABEL},
+ {"powerIdleWhileOnBatteryLabel",
+ IDS_SETTINGS_POWER_IDLE_WHILE_ON_BATTERY_LABEL},
+ {"powerIdleWhileOnBatteryAriaLabel",
+ IDS_SETTINGS_POWER_IDLE_WHILE_ON_BATTERY_ARIA_LABEL},
+ {"powerIdleDisplayOffSleep", IDS_SETTINGS_POWER_IDLE_DISPLAY_OFF_SLEEP},
+ {"powerIdleDisplayOff", IDS_SETTINGS_POWER_IDLE_DISPLAY_OFF},
+ {"powerIdleDisplayOn", IDS_SETTINGS_POWER_IDLE_DISPLAY_ON},
+ {"powerIdleOther", IDS_SETTINGS_POWER_IDLE_OTHER},
+ {"powerLidSleepLabel", IDS_SETTINGS_POWER_LID_CLOSED_SLEEP_LABEL},
+ {"powerLidSignOutLabel", IDS_SETTINGS_POWER_LID_CLOSED_SIGN_OUT_LABEL},
+ {"powerLidShutDownLabel", IDS_SETTINGS_POWER_LID_CLOSED_SHUT_DOWN_LABEL},
+ };
+ AddLocalizedStringsBulk(html_source, kPowerStrings);
+}
+
+void AddDeviceStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kDeviceStrings[] = {
+ {"devicePageTitle", IDS_SETTINGS_DEVICE_TITLE},
+ {"scrollLabel", IDS_SETTINGS_SCROLL_LABEL},
+ {"touchPadScrollLabel", IDS_OS_SETTINGS_TOUCHPAD_REVERSE_SCROLL_LABEL},
+ };
+ AddLocalizedStringsBulk(html_source, kDeviceStrings);
+
+ AddDevicePointersStrings(html_source);
+ AddDeviceKeyboardStrings(html_source);
+ AddDeviceStylusStrings(html_source);
+ AddDeviceDisplayStrings(html_source);
+ AddDeviceStorageStrings(html_source);
+ AddDevicePowerStrings(html_source);
+}
+
+void AddFilesStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"disconnectGoogleDriveAccount", IDS_SETTINGS_DISCONNECT_GOOGLE_DRIVE},
+ {"filesPageTitle", IDS_OS_SETTINGS_FILES},
+ {"smbSharesTitle", IDS_SETTINGS_DOWNLOADS_SMB_SHARES},
+ {"smbSharesLearnMoreLabel",
+ IDS_SETTINGS_DOWNLOADS_SMB_SHARES_LEARN_MORE_LABEL},
+ {"addSmbShare", IDS_SETTINGS_DOWNLOADS_SMB_SHARES_ADD_SHARE},
+ {"smbShareAddedSuccessfulMessage",
+ IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_SUCCESS_MESSAGE},
+ {"smbShareAddedErrorMessage",
+ IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_ERROR_MESSAGE},
+ {"smbShareAddedAuthFailedMessage",
+ IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_AUTH_FAILED_MESSAGE},
+ {"smbShareAddedNotFoundMessage",
+ IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_NOT_FOUND_MESSAGE},
+ {"smbShareAddedUnsupportedDeviceMessage",
+ IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_UNSUPPORTED_DEVICE_MESSAGE},
+ {"smbShareAddedMountExistsMessage",
+ IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_MOUNT_EXISTS_MESSAGE},
+ {"smbShareAddedTooManyMountsMessage",
+ IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_TOO_MANY_MOUNTS_MESSAGE},
+ {"smbShareAddedInvalidURLMessage",
+ IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_MOUNT_INVALID_URL_MESSAGE},
+ {"smbShareAddedInvalidSSOURLMessage",
+ IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_MOUNT_INVALID_SSO_URL_MESSAGE},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ chromeos::smb_dialog::AddLocalizedStrings(html_source);
+
+ html_source->AddString("smbSharesLearnMoreURL",
+ GetHelpUrlWithBoard(chrome::kSmbSharesLearnMoreURL));
+}
+
+void AddEasyUnlockStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"easyUnlockSectionTitle", IDS_SETTINGS_EASY_UNLOCK_SECTION_TITLE},
+ {"easyUnlockUnlockDeviceOnly",
+ IDS_SETTINGS_EASY_UNLOCK_UNLOCK_DEVICE_ONLY},
+ {"easyUnlockUnlockDeviceAndAllowSignin",
+ IDS_SETTINGS_EASY_UNLOCK_UNLOCK_DEVICE_AND_ALLOW_SIGNIN},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+}
+
+void AddMultideviceStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"multidevicePageTitle", IDS_SETTINGS_MULTIDEVICE},
+ {"multideviceSetupButton", IDS_SETTINGS_MULTIDEVICE_SETUP_BUTTON},
+ {"multideviceVerifyButton", IDS_SETTINGS_MULTIDEVICE_VERIFY_BUTTON},
+ {"multideviceSetupItemHeading",
+ IDS_SETTINGS_MULTIDEVICE_SETUP_ITEM_HEADING},
+ {"multideviceEnabled", IDS_SETTINGS_MULTIDEVICE_ENABLED},
+ {"multideviceDisabled", IDS_SETTINGS_MULTIDEVICE_DISABLED},
+ {"multideviceSmartLockItemTitle", IDS_SETTINGS_EASY_UNLOCK_SECTION_TITLE},
+ {"multideviceInstantTetheringItemTitle",
+ IDS_SETTINGS_MULTIDEVICE_INSTANT_TETHERING},
+ {"multideviceInstantTetheringItemSummary",
+ IDS_SETTINGS_MULTIDEVICE_INSTANT_TETHERING_SUMMARY},
+ {"multideviceAndroidMessagesItemTitle",
+ IDS_SETTINGS_MULTIDEVICE_ANDROID_MESSAGES},
+ {"multideviceForgetDevice", IDS_SETTINGS_MULTIDEVICE_FORGET_THIS_DEVICE},
+ {"multideviceSmartLockOptions",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_OPTIONS_LOCK},
+ {"multideviceForgetDeviceDisconnect",
+ IDS_SETTINGS_MULTIDEVICE_FORGET_THIS_DEVICE_DISCONNECT},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddString(
+ "multideviceForgetDeviceSummary",
+ ui::SubstituteChromeOSDeviceType(
+ IDS_SETTINGS_MULTIDEVICE_FORGET_THIS_DEVICE_EXPLANATION));
+ html_source->AddString(
+ "multideviceForgetDeviceDialogMessage",
+ ui::SubstituteChromeOSDeviceType(
+ IDS_SETTINGS_MULTIDEVICE_FORGET_DEVICE_DIALOG_MESSAGE));
+ html_source->AddString(
+ "multideviceVerificationText",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_MULTIDEVICE_VERIFICATION_TEXT,
+ base::UTF8ToUTF16(
+ chromeos::multidevice_setup::
+ GetBoardSpecificBetterTogetherSuiteLearnMoreUrl()
+ .spec())));
+ html_source->AddString(
+ "multideviceSetupSummary",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_MULTIDEVICE_SETUP_SUMMARY, ui::GetChromeOSDeviceName(),
+ base::UTF8ToUTF16(
+ chromeos::multidevice_setup::
+ GetBoardSpecificBetterTogetherSuiteLearnMoreUrl()
+ .spec())));
+ html_source->AddString(
+ "multideviceNoHostText",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_MULTIDEVICE_NO_ELIGIBLE_HOSTS,
+ base::UTF8ToUTF16(
+ chromeos::multidevice_setup::
+ GetBoardSpecificBetterTogetherSuiteLearnMoreUrl()
+ .spec())));
+ html_source->AddString(
+ "multideviceAndroidMessagesItemSummary",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_MULTIDEVICE_ANDROID_MESSAGES_SUMMARY,
+ ui::GetChromeOSDeviceName(),
+ base::UTF8ToUTF16(chromeos::multidevice_setup::
+ GetBoardSpecificMessagesLearnMoreUrl()
+ .spec())));
+ html_source->AddString(
+ "multideviceSmartLockItemSummary",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_MULTIDEVICE_SMART_LOCK_SUMMARY,
+ ui::GetChromeOSDeviceName(),
+ GetHelpUrlWithBoard(chrome::kEasyUnlockLearnMoreUrl)));
+
+ AddEasyUnlockStrings(html_source);
+}
+
+void AddKerberosAccountsPageStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"kerberosAccountsAddAccountLabel",
+ IDS_SETTINGS_KERBEROS_ACCOUNTS_ADD_ACCOUNT_LABEL},
+ {"kerberosAccountsRefreshNowLabel",
+ IDS_SETTINGS_KERBEROS_ACCOUNTS_REFRESH_NOW_LABEL},
+ {"kerberosAccountsSetAsActiveAccountLabel",
+ IDS_SETTINGS_KERBEROS_ACCOUNTS_SET_AS_ACTIVE_ACCOUNT_LABEL},
+ {"kerberosAccountsSignedOut", IDS_SETTINGS_KERBEROS_ACCOUNTS_SIGNED_OUT},
+ {"kerberosAccountsListHeader",
+ IDS_SETTINGS_KERBEROS_ACCOUNTS_LIST_HEADER},
+ {"kerberosAccountsRemoveAccountLabel",
+ IDS_SETTINGS_KERBEROS_ACCOUNTS_REMOVE_ACCOUNT_LABEL},
+ {"kerberosAccountsReauthenticationLabel",
+ IDS_SETTINGS_KERBEROS_ACCOUNTS_REAUTHENTICATION_LABEL},
+ {"kerberosAccountsTicketActive",
+ IDS_SETTINGS_KERBEROS_ACCOUNTS_TICKET_ACTIVE},
+ {"kerberosAccountsAccountRemovedTip",
+ IDS_SETTINGS_KERBEROS_ACCOUNTS_ACCOUNT_REMOVED_TIP},
+ {"kerberosAccountsAccountRefreshedTip",
+ IDS_SETTINGS_KERBEROS_ACCOUNTS_ACCOUNT_REFRESHED_TIP},
+ {"kerberosAccountsSignedIn", IDS_SETTINGS_KERBEROS_ACCOUNTS_SIGNED_IN},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ PrefService* local_state = g_browser_process->local_state();
+
+ // Whether new Kerberos accounts may be added.
+ html_source->AddBoolean(
+ "kerberosAddAccountsAllowed",
+ local_state->GetBoolean(prefs::kKerberosAddAccountsAllowed));
+
+ // Kerberos accounts page with "Learn more" link.
+ html_source->AddString(
+ "kerberosAccountsDescription",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_KERBEROS_ACCOUNTS_DESCRIPTION,
+ GetHelpUrlWithBoard(chrome::kKerberosAccountsLearnMoreURL)));
+}
+
+void AddKerberosAddAccountDialogStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"kerberosAccountsAdvancedConfigLabel",
+ IDS_SETTINGS_KERBEROS_ACCOUNTS_ADVANCED_CONFIG_LABEL},
+ {"kerberosAdvancedConfigTitle",
+ IDS_SETTINGS_KERBEROS_ADVANCED_CONFIG_TITLE},
+ {"kerberosAdvancedConfigDesc",
+ IDS_SETTINGS_KERBEROS_ADVANCED_CONFIG_DESC},
+ {"addKerberosAccountRememberPassword",
+ IDS_SETTINGS_ADD_KERBEROS_ACCOUNT_REMEMBER_PASSWORD},
+ {"kerberosPassword", IDS_SETTINGS_KERBEROS_PASSWORD},
+ {"kerberosUsername", IDS_SETTINGS_KERBEROS_USERNAME},
+ {"addKerberosAccountDescription",
+ IDS_SETTINGS_ADD_KERBEROS_ACCOUNT_DESCRIPTION},
+ {"kerberosErrorNetworkProblem",
+ IDS_SETTINGS_KERBEROS_ERROR_NETWORK_PROBLEM},
+ {"kerberosErrorUsernameInvalid",
+ IDS_SETTINGS_KERBEROS_ERROR_USERNAME_INVALID},
+ {"kerberosErrorUsernameUnknown",
+ IDS_SETTINGS_KERBEROS_ERROR_USERNAME_UNKNOWN},
+ {"kerberosErrorDuplicatePrincipalName",
+ IDS_SETTINGS_KERBEROS_ERROR_DUPLICATE_PRINCIPAL_NAME},
+ {"kerberosErrorContactingServer",
+ IDS_SETTINGS_KERBEROS_ERROR_CONTACTING_SERVER},
+ {"kerberosErrorPasswordInvalid",
+ IDS_SETTINGS_KERBEROS_ERROR_PASSWORD_INVALID},
+ {"kerberosErrorPasswordExpired",
+ IDS_SETTINGS_KERBEROS_ERROR_PASSWORD_EXPIRED},
+ {"kerberosErrorKdcEncType", IDS_SETTINGS_KERBEROS_ERROR_KDC_ENC_TYPE},
+ {"kerberosErrorGeneral", IDS_SETTINGS_KERBEROS_ERROR_GENERAL},
+ {"kerberosConfigErrorSectionNestedInGroup",
+ IDS_SETTINGS_KERBEROS_CONFIG_ERROR_SECTION_NESTED_IN_GROUP},
+ {"kerberosConfigErrorSectionSyntax",
+ IDS_SETTINGS_KERBEROS_CONFIG_ERROR_SECTION_SYNTAX},
+ {"kerberosConfigErrorExpectedOpeningCurlyBrace",
+ IDS_SETTINGS_KERBEROS_CONFIG_ERROR_EXPECTED_OPENING_CURLY_BRACE},
+ {"kerberosConfigErrorExtraCurlyBrace",
+ IDS_SETTINGS_KERBEROS_CONFIG_ERROR_EXTRA_CURLY_BRACE},
+ {"kerberosConfigErrorRelationSyntax",
+ IDS_SETTINGS_KERBEROS_CONFIG_ERROR_RELATION_SYNTAX_ERROR},
+ {"kerberosConfigErrorKeyNotSupported",
+ IDS_SETTINGS_KERBEROS_CONFIG_ERROR_KEY_NOT_SUPPORTED},
+ {"kerberosConfigErrorSectionNotSupported",
+ IDS_SETTINGS_KERBEROS_CONFIG_ERROR_SECTION_NOT_SUPPORTED},
+ {"kerberosConfigErrorKrb5FailedToParse",
+ IDS_SETTINGS_KERBEROS_CONFIG_ERROR_KRB5_FAILED_TO_PARSE},
+ {"addKerberosAccountRefreshButtonLabel",
+ IDS_SETTINGS_ADD_KERBEROS_ACCOUNT_REFRESH_BUTTON_LABEL},
+ {"addKerberosAccount", IDS_SETTINGS_ADD_KERBEROS_ACCOUNT},
+ {"refreshKerberosAccount", IDS_SETTINGS_REFRESH_KERBEROS_ACCOUNT},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ PrefService* local_state = g_browser_process->local_state();
+
+ // Whether the 'Remember password' checkbox is enabled.
+ html_source->AddBoolean(
+ "kerberosRememberPasswordEnabled",
+ local_state->GetBoolean(prefs::kKerberosRememberPasswordEnabled));
+
+ // Kerberos default configuration.
+ html_source->AddString(
+ "defaultKerberosConfig",
+ chromeos::KerberosCredentialsManager::GetDefaultKerberosConfig());
+}
+
+void AddLockScreenPageStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"lockScreenNotificationTitle",
+ IDS_ASH_SETTINGS_LOCK_SCREEN_NOTIFICATION_TITLE},
+ {"lockScreenNotificationHideSensitive",
+ IDS_ASH_SETTINGS_LOCK_SCREEN_NOTIFICATION_HIDE_SENSITIVE},
+ {"enableScreenlock", IDS_SETTINGS_PEOPLE_ENABLE_SCREENLOCK},
+ {"lockScreenNotificationShow",
+ IDS_ASH_SETTINGS_LOCK_SCREEN_NOTIFICATION_SHOW},
+ {"lockScreenPinOrPassword",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_PIN_OR_PASSWORD},
+ {"lockScreenSetupFingerprintButton",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_FINGERPRINT_SETUP_BUTTON},
+ {"lockScreenNotificationHide",
+ IDS_ASH_SETTINGS_LOCK_SCREEN_NOTIFICATION_HIDE},
+ {"lockScreenEditFingerprints",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_EDIT_FINGERPRINTS},
+ {"lockScreenPasswordOnly", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_PASSWORD_ONLY},
+ {"lockScreenChangePinButton",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_CHANGE_PIN_BUTTON},
+ {"lockScreenEditFingerprintsDescription",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_EDIT_FINGERPRINTS_DESCRIPTION},
+ {"lockScreenNumberFingerprints",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_NUM_FINGERPRINTS},
+ {"lockScreenNone", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_NONE},
+ {"lockScreenFingerprintNewName",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_NEW_FINGERPRINT_DEFAULT_NAME},
+ {"lockScreenDeleteFingerprintLabel",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_DELETE_FINGERPRINT_ARIA_LABEL},
+ {"lockScreenOptionsLock", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_OPTIONS_LOCK},
+ {"lockScreenOptionsLoginLock",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_OPTIONS_LOGIN_LOCK},
+ {"lockScreenSetupPinButton",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_SETUP_PIN_BUTTON},
+ {"lockScreenTitleLock", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_TITLE_LOCK},
+ {"lockScreenTitleLoginLock",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_TITLE_LOGIN_LOCK},
+ {"passwordPromptEnterPasswordLock",
+ IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_ENTER_PASSWORD_LOCK},
+ {"passwordPromptEnterPasswordLoginLock",
+ IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_ENTER_PASSWORD_LOGIN_LOCK},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+}
+
+void AddUsersStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"usersModifiedByOwnerLabel", IDS_SETTINGS_USERS_MODIFIED_BY_OWNER_LABEL},
+ {"guestBrowsingLabel", IDS_SETTINGS_USERS_GUEST_BROWSING_LABEL},
+ {"settingsManagedLabel", IDS_SETTINGS_USERS_MANAGED_LABEL},
+ {"showOnSigninLabel", IDS_SETTINGS_USERS_SHOW_ON_SIGNIN_LABEL},
+ {"restrictSigninLabel", IDS_SETTINGS_USERS_RESTRICT_SIGNIN_LABEL},
+ {"deviceOwnerLabel", IDS_SETTINGS_USERS_DEVICE_OWNER_LABEL},
+ {"removeUserTooltip", IDS_SETTINGS_USERS_REMOVE_USER_TOOLTIP},
+ {"addUsers", IDS_SETTINGS_USERS_ADD_USERS},
+ {"addUsersEmail", IDS_SETTINGS_USERS_ADD_USERS_EMAIL},
+ {"userExistsError", IDS_SETTINGS_USER_EXISTS_ERROR},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+}
+
+void AddGoogleAssistantStrings(content::WebUIDataSource* html_source,
+ Profile* profile) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"googleAssistantPageTitle", IDS_SETTINGS_GOOGLE_ASSISTANT},
+ {"googleAssistantEnableContext", IDS_ASSISTANT_SCREEN_CONTEXT_TITLE},
+ {"googleAssistantEnableContextDescription",
+ IDS_ASSISTANT_SCREEN_CONTEXT_DESC},
+ {"googleAssistantEnableHotword",
+ IDS_SETTINGS_GOOGLE_ASSISTANT_ENABLE_HOTWORD},
+ {"googleAssistantEnableHotwordDescription",
+ IDS_SETTINGS_GOOGLE_ASSISTANT_ENABLE_HOTWORD_DESCRIPTION},
+ {"googleAssistantVoiceSettings",
+ IDS_SETTINGS_GOOGLE_ASSISTANT_VOICE_SETTINGS},
+ {"googleAssistantVoiceSettingsDescription",
+ IDS_ASSISTANT_VOICE_MATCH_RECORDING},
+ {"googleAssistantVoiceSettingsRetrainButton",
+ IDS_SETTINGS_GOOGLE_ASSISTANT_VOICE_SETTINGS_RETRAIN},
+ {"googleAssistantEnableHotwordWithoutDspDescription",
+ IDS_SETTINGS_GOOGLE_ASSISTANT_ENABLE_HOTWORD_WITHOUT_DSP_DESCRIPTION},
+ {"googleAssistantEnableHotwordWithoutDspRecommended",
+ IDS_SETTINGS_GOOGLE_ASSISTANT_ENABLE_HOTWORD_WITHOUT_DSP_RECOMMENDED},
+ {"googleAssistantEnableHotwordWithoutDspAlwaysOn",
+ IDS_SETTINGS_GOOGLE_ASSISTANT_ENABLE_HOTWORD_WITHOUT_DSP_ALWAYS_ON},
+ {"googleAssistantEnableHotwordWithoutDspOff",
+ IDS_SETTINGS_GOOGLE_ASSISTANT_ENABLE_HOTWORD_WITHOUT_DSP_OFF},
+ {"googleAssistantEnableNotification",
+ IDS_SETTINGS_GOOGLE_ASSISTANT_ENABLE_NOTIFICATION},
+ {"googleAssistantEnableNotificationDescription",
+ IDS_SETTINGS_GOOGLE_ASSISTANT_ENABLE_NOTIFICATION_DESCRIPTION},
+ {"googleAssistantLaunchWithMicOpen",
+ IDS_SETTINGS_GOOGLE_ASSISTANT_LAUNCH_WITH_MIC_OPEN},
+ {"googleAssistantLaunchWithMicOpenDescription",
+ IDS_SETTINGS_GOOGLE_ASSISTANT_LAUNCH_WITH_MIC_OPEN_DESCRIPTION},
+ {"googleAssistantSettings", IDS_SETTINGS_GOOGLE_ASSISTANT_SETTINGS},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddBoolean("hotwordDspAvailable",
+ chromeos::IsHotwordDspAvailable());
+ html_source->AddBoolean(
+ "voiceMatchDisabled",
+ chromeos::assistant::features::IsVoiceMatchDisabled());
+}
+
+void AddPrintingStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"printingPageTitle", IDS_SETTINGS_PRINTING},
+ {"cupsPrintersTitle", IDS_SETTINGS_PRINTING_CUPS_PRINTERS},
+ {"cupsPrintersLearnMoreLabel",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTERS_LEARN_MORE_LABEL},
+ {"addCupsPrinter", IDS_SETTINGS_PRINTING_CUPS_PRINTERS_ADD_PRINTER},
+ {"editPrinter", IDS_SETTINGS_PRINTING_CUPS_PRINTERS_EDIT},
+ {"removePrinter", IDS_SETTINGS_PRINTING_CUPS_PRINTERS_REMOVE},
+ {"setupPrinter", IDS_SETTINGS_PRINTING_CUPS_PRINTER_SETUP_BUTTON},
+ {"setupPrinterAria",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_SETUP_BUTTON_ARIA},
+ {"savePrinter", IDS_SETTINGS_PRINTING_CUPS_PRINTER_SAVE_BUTTON},
+ {"savePrinterAria", IDS_SETTINGS_PRINTING_CUPS_PRINTER_SAVE_BUTTON_ARIA},
+ {"searchLabel", IDS_SETTINGS_PRINTING_CUPS_SEARCH_LABEL},
+ {"noSearchResults", IDS_SEARCH_NO_RESULTS},
+ {"printerDetailsTitle", IDS_SETTINGS_PRINTING_CUPS_PRINTER_DETAILS_TITLE},
+ {"printerName", IDS_SETTINGS_PRINTING_CUPS_PRINTER_DETAILS_NAME},
+ {"printerModel", IDS_SETTINGS_PRINTING_CUPS_PRINTER_DETAILS_MODEL},
+ {"printerQueue", IDS_SETTINGS_PRINTING_CUPS_PRINTER_DETAILS_QUEUE},
+ {"savedPrintersTitle", IDS_SETTINGS_PRINTING_CUPS_SAVED_PRINTERS_TITLE},
+ {"savedPrintersCountMany",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTERS_SAVED_PRINTERS_COUNT_MANY},
+ {"savedPrintersCountOne",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTERS_SAVED_PRINTERS_COUNT_ONE},
+ {"savedPrintersCountNone",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTERS_SAVED_PRINTERS_COUNT_NONE},
+ {"showMorePrinters", IDS_SETTINGS_PRINTING_CUPS_SHOW_MORE},
+ {"addPrintersNearbyTitle",
+ IDS_SETTINGS_PRINTING_CUPS_ADD_PRINTERS_NEARBY_TITLE},
+ {"addPrintersManuallyTitle",
+ IDS_SETTINGS_PRINTING_CUPS_ADD_PRINTERS_MANUALLY_TITLE},
+ {"manufacturerAndModelDialogTitle",
+ IDS_SETTINGS_PRINTING_CUPS_SELECT_MANUFACTURER_AND_MODEL_TITLE},
+ {"nearbyPrintersListTitle",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTERS_AVAILABLE_PRINTERS},
+ {"nearbyPrintersCountMany",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTERS_AVAILABLE_PRINTERS_COUNT_MANY},
+ {"nearbyPrintersCountOne",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTERS_AVAILABLE_PRINTER_COUNT_ONE},
+ {"nearbyPrintersCountNone",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTERS_AVAILABLE_PRINTER_COUNT_NONE},
+ {"nearbyPrintersListDescription",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTERS_ADD_DETECTED_OR_NEW_PRINTER},
+ {"manufacturerAndModelAdditionalInformation",
+ IDS_SETTINGS_PRINTING_CUPS_MANUFACTURER_MODEL_ADDITIONAL_INFORMATION},
+ {"addPrinterButtonText",
+ IDS_SETTINGS_PRINTING_CUPS_ADD_PRINTER_BUTTON_ADD},
+ {"printerDetailsAdvanced", IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADVANCED},
+ {"printerDetailsA11yLabel",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADVANCED_ACCESSIBILITY_LABEL},
+ {"printerAddress", IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADVANCED_ADDRESS},
+ {"printerProtocol", IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADVANCED_PROTOCOL},
+ {"printerURI", IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADVANCED_URI},
+ {"manuallyAddPrinterButtonText",
+ IDS_SETTINGS_PRINTING_CUPS_ADD_PRINTER_BUTTON_MANUAL_ADD},
+ {"discoverPrintersButtonText",
+ IDS_SETTINGS_PRINTING_CUPS_ADD_PRINTER_BUTTON_DISCOVER_PRINTERS},
+ {"printerProtocolIpp", IDS_SETTINGS_PRINTING_CUPS_PRINTER_PROTOCOL_IPP},
+ {"printerProtocolIpps", IDS_SETTINGS_PRINTING_CUPS_PRINTER_PROTOCOL_IPPS},
+ {"printerProtocolHttp", IDS_SETTINGS_PRINTING_CUPS_PRINTER_PROTOCOL_HTTP},
+ {"printerProtocolHttps",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_PROTOCOL_HTTPS},
+ {"printerProtocolAppSocket",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_PROTOCOL_APP_SOCKET},
+ {"printerProtocolLpd", IDS_SETTINGS_PRINTING_CUPS_PRINTER_PROTOCOL_LPD},
+ {"printerProtocolUsb", IDS_SETTINGS_PRINTING_CUPS_PRINTER_PROTOCOL_USB},
+ {"printerProtocolIppUsb",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_PROTOCOL_IPPUSB},
+ {"printerConfiguringMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_CONFIGURING_MESSAGE},
+ {"printerManufacturer", IDS_SETTINGS_PRINTING_CUPS_PRINTER_MANUFACTURER},
+ {"selectDriver", IDS_SETTINGS_PRINTING_CUPS_PRINTER_SELECT_DRIVER},
+ {"selectDriverButtonText",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_BUTTON_SELECT_DRIVER},
+ {"selectDriverButtonAriaLabel",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_BUTTON_SELECT_DRIVER_ARIA_LABEL},
+ {"selectDriverErrorMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_INVALID_DRIVER},
+ {"printerAddedSuccessfulMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_PRINTER_DONE_MESSAGE},
+ {"printerEditedSuccessfulMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_EDITED_PRINTER_DONE_MESSAGE},
+ {"printerUnavailableMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_UNAVAILABLE_MESSAGE},
+ {"noPrinterNearbyMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_NO_PRINTER_NEARBY},
+ {"searchingNearbyPrinters",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_SEARCHING_NEARBY_PRINTER},
+ {"printerAddedFailedMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_PRINTER_ERROR_MESSAGE},
+ {"printerAddedFatalErrorMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_PRINTER_FATAL_ERROR_MESSAGE},
+ {"printerAddedUnreachableMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_PRINTER_PRINTER_UNREACHABLE_MESSAGE},
+ {"printerAddedPpdTooLargeMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_PRINTER_PPD_TOO_LARGE_MESSAGE},
+ {"printerAddedInvalidPpdMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_PRINTER_INVALID_PPD_MESSAGE},
+ {"printerAddedPpdNotFoundMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_PRINTER_PPD_NOT_FOUND},
+ {"printerAddedPpdUnretrievableMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_PRINTER_PPD_UNRETRIEVABLE},
+ {"printerAddedNativePrintersNotAllowedMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_NATIVE_PRINTERS_NOT_ALLOWED_MESSAGE},
+ {"editPrinterInvalidPrinterUpdate",
+ IDS_SETTINGS_PRINTING_CUPS_EDIT_PRINTER_INVALID_PRINTER_UPDATE},
+ {"requireNetworkMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_REQUIRE_INTERNET_MESSAGE},
+ {"checkNetworkMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_CHECK_CONNECTION_MESSAGE},
+ {"noInternetConnection",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_NO_INTERNET_CONNECTION},
+ {"checkNetworkAndTryAgain",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_CONNECT_TO_NETWORK_SUBTEXT},
+ {"editPrinterDialogTitle",
+ IDS_SETTINGS_PRINTING_CUPS_EDIT_PRINTER_DIALOG_TITLE},
+ {"editPrinterButtonText", IDS_SETTINGS_PRINTING_CUPS_EDIT_PRINTER_BUTTON},
+ {"currentPpdMessage",
+ IDS_SETTINGS_PRINTING_CUPS_EDIT_PRINTER_CURRENT_PPD_MESSAGE},
+ {"printerEulaNotice", IDS_SETTINGS_PRINTING_CUPS_EULA_NOTICE},
+ {"ippPrinterUnreachable", IDS_SETTINGS_PRINTING_CUPS_IPP_URI_UNREACHABLE},
+ {"generalPrinterDialogError",
+ IDS_SETTINGS_PRINTING_CUPS_DIALOG_GENERAL_ERROR},
+ {"printServerButtonText", IDS_SETTINGS_PRINTING_CUPS_PRINT_SERVER},
+ {"addPrintServerTitle",
+ IDS_SETTINGS_PRINTING_CUPS_ADD_PRINT_SERVER_TITLE},
+ {"printServerAddress", IDS_SETTINGS_PRINTING_CUPS_PRINT_SERVER_ADDRESS},
+ {"printServerFoundZeroPrinters",
+ IDS_SETTINGS_PRINTING_CUPS_PRINT_SERVER_FOUND_ZERO_PRINTERS},
+ {"printServerFoundOnePrinter",
+ IDS_SETTINGS_PRINTING_CUPS_PRINT_SERVER_FOUND_ONE_PRINTER},
+ {"printServerFoundManyPrinters",
+ IDS_SETTINGS_PRINTING_CUPS_PRINT_SERVER_FOUND_MANY_PRINTERS},
+ {"printServerInvalidUrlAddress",
+ IDS_SETTINGS_PRINTING_CUPS_PRINT_SERVER_INVALID_URL_ADDRESS},
+ {"printServerConnectionError",
+ IDS_SETTINGS_PRINTING_CUPS_PRINT_SERVER_CONNECTION_ERROR},
+ {"printServerConfigurationErrorMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINT_SERVER_REACHABLE_BUT_CANNOT_ADD},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddString("printingCUPSPrintLearnMoreUrl",
+ GetHelpUrlWithBoard(chrome::kCupsPrintLearnMoreURL));
+ html_source->AddString(
+ "printingCUPSPrintPpdLearnMoreUrl",
+ GetHelpUrlWithBoard(chrome::kCupsPrintPPDLearnMoreURL));
+ html_source->AddBoolean(
+ "consumerPrintServerUiEnabled",
+ base::FeatureList::IsEnabled(::features::kPrintServerUi));
+}
+
+void AddSearchInSettingsStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"searchPrompt", IDS_SETTINGS_SEARCH_PROMPT},
+ {"searchNoResults", IDS_SEARCH_NO_RESULTS},
+ {"searchResults", IDS_SEARCH_RESULTS},
+ // TODO(dpapad): IDS_DOWNLOAD_CLEAR_SEARCH and IDS_HISTORY_CLEAR_SEARCH
+ // are identical, merge them to one and re-use here.
+ {"clearSearch", IDS_DOWNLOAD_CLEAR_SEARCH},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddString(
+ "searchNoOsResultsHelp",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_SEARCH_NO_RESULTS_HELP,
+ base::ASCIIToUTF16(chrome::kOsSettingsSearchHelpURL)));
+
+ html_source->AddBoolean(
+ "newOsSettingsSearch",
+ base::FeatureList::IsEnabled(chromeos::features::kNewOsSettingsSearch));
+}
+
+void AddDateTimeStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"dateTimePageTitle", IDS_SETTINGS_DATE_TIME},
+ {"timeZone", IDS_SETTINGS_TIME_ZONE},
+ {"selectTimeZoneResolveMethod",
+ IDS_SETTINGS_SELECT_TIME_ZONE_RESOLVE_METHOD},
+ {"timeZoneGeolocation", IDS_SETTINGS_TIME_ZONE_GEOLOCATION},
+ {"timeZoneButton", IDS_SETTINGS_TIME_ZONE_BUTTON},
+ {"timeZoneSubpageTitle", IDS_SETTINGS_TIME_ZONE_SUBPAGE_TITLE},
+ {"setTimeZoneAutomaticallyDisabled",
+ IDS_SETTINGS_TIME_ZONE_DETECTION_MODE_DISABLED},
+ {"setTimeZoneAutomaticallyOn",
+ IDS_SETTINGS_TIME_ZONE_DETECTION_SET_AUTOMATICALLY},
+ {"setTimeZoneAutomaticallyOff",
+ IDS_SETTINGS_TIME_ZONE_DETECTION_CHOOSE_FROM_LIST},
+ {"setTimeZoneAutomaticallyIpOnlyDefault",
+ IDS_SETTINGS_TIME_ZONE_DETECTION_MODE_IP_ONLY_DEFAULT},
+ {"setTimeZoneAutomaticallyWithWiFiAccessPointsData",
+ IDS_SETTINGS_TIME_ZONE_DETECTION_MODE_SEND_WIFI_AP},
+ {"setTimeZoneAutomaticallyWithAllLocationInfo",
+ IDS_SETTINGS_TIME_ZONE_DETECTION_MODE_SEND_ALL_INFO},
+ {"use24HourClock", IDS_SETTINGS_USE_24_HOUR_CLOCK},
+ {"setDateTime", IDS_SETTINGS_SET_DATE_TIME},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddString(
+ "timeZoneSettingsLearnMoreURL",
+ base::ASCIIToUTF16(base::StringPrintf(
+ chrome::kTimeZoneSettingsLearnMoreURL,
+ g_browser_process->GetApplicationLocale().c_str())));
+}
+
+void AddAboutStrings(content::WebUIDataSource* html_source, Profile* profile) {
+ // Top level About page strings.
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"aboutProductLogoAlt", IDS_SHORT_PRODUCT_LOGO_ALT_TEXT},
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
+ {"aboutReportAnIssue", IDS_SETTINGS_ABOUT_PAGE_REPORT_AN_ISSUE},
+#endif
+ {"aboutRelaunch", IDS_SETTINGS_ABOUT_PAGE_RELAUNCH},
+ {"aboutUpgradeCheckStarted", IDS_SETTINGS_ABOUT_UPGRADE_CHECK_STARTED},
+ {"aboutUpgradeRelaunch", IDS_SETTINGS_UPGRADE_SUCCESSFUL_RELAUNCH},
+ {"aboutUpgradeUpdating", IDS_SETTINGS_UPGRADE_UPDATING},
+ {"aboutUpgradeUpdatingPercent", IDS_SETTINGS_UPGRADE_UPDATING_PERCENT},
+ {"aboutGetHelpUsingChrome", IDS_SETTINGS_GET_HELP_USING_CHROME},
+ {"aboutPageTitle", IDS_SETTINGS_ABOUT_PROGRAM},
+ {"aboutProductTitle", IDS_PRODUCT_NAME},
+
+ {"aboutEndOfLifeTitle", IDS_SETTINGS_ABOUT_PAGE_END_OF_LIFE_TITLE},
+ {"aboutRelaunchAndPowerwash",
+ IDS_SETTINGS_ABOUT_PAGE_RELAUNCH_AND_POWERWASH},
+ {"aboutRollbackInProgress", IDS_SETTINGS_UPGRADE_ROLLBACK_IN_PROGRESS},
+ {"aboutRollbackSuccess", IDS_SETTINGS_UPGRADE_ROLLBACK_SUCCESS},
+ {"aboutUpgradeUpdatingChannelSwitch",
+ IDS_SETTINGS_UPGRADE_UPDATING_CHANNEL_SWITCH},
+ {"aboutUpgradeSuccessChannelSwitch",
+ IDS_SETTINGS_UPGRADE_SUCCESSFUL_CHANNEL_SWITCH},
+ {"aboutTPMFirmwareUpdateTitle",
+ IDS_SETTINGS_ABOUT_TPM_FIRMWARE_UPDATE_TITLE},
+ {"aboutTPMFirmwareUpdateDescription",
+ IDS_SETTINGS_ABOUT_TPM_FIRMWARE_UPDATE_DESCRIPTION},
+
+ // About page, channel switcher dialog.
+ {"aboutChangeChannel", IDS_SETTINGS_ABOUT_PAGE_CHANGE_CHANNEL},
+ {"aboutChangeChannelAndPowerwash",
+ IDS_SETTINGS_ABOUT_PAGE_CHANGE_CHANNEL_AND_POWERWASH},
+ {"aboutDelayedWarningMessage",
+ IDS_SETTINGS_ABOUT_PAGE_DELAYED_WARNING_MESSAGE},
+ {"aboutDelayedWarningTitle", IDS_SETTINGS_ABOUT_PAGE_DELAYED_WARNING_TITLE},
+ {"aboutPowerwashWarningMessage",
+ IDS_SETTINGS_ABOUT_PAGE_POWERWASH_WARNING_MESSAGE},
+ {"aboutPowerwashWarningTitle",
+ IDS_SETTINGS_ABOUT_PAGE_POWERWASH_WARNING_TITLE},
+ {"aboutUnstableWarningMessage",
+ IDS_SETTINGS_ABOUT_PAGE_UNSTABLE_WARNING_MESSAGE},
+ {"aboutUnstableWarningTitle",
+ IDS_SETTINGS_ABOUT_PAGE_UNSTABLE_WARNING_TITLE},
+ {"aboutChannelDialogBeta", IDS_SETTINGS_ABOUT_PAGE_DIALOG_CHANNEL_BETA},
+ {"aboutChannelDialogDev", IDS_SETTINGS_ABOUT_PAGE_DIALOG_CHANNEL_DEV},
+ {"aboutChannelDialogStable", IDS_SETTINGS_ABOUT_PAGE_DIALOG_CHANNEL_STABLE},
+
+ // About page, update warning dialog.
+ {"aboutUpdateWarningMessage",
+ IDS_SETTINGS_ABOUT_PAGE_UPDATE_WARNING_MESSAGE},
+ {"aboutUpdateWarningTitle", IDS_SETTINGS_ABOUT_PAGE_UPDATE_WARNING_TITLE},
+
+ // Detailed build information
+ {"aboutBuildDetailsTitle", IDS_OS_SETTINGS_ABOUT_PAGE_BUILD_DETAILS},
+ {"aboutChannelBeta", IDS_SETTINGS_ABOUT_PAGE_CURRENT_CHANNEL_BETA},
+ {"aboutChannelCanary", IDS_SETTINGS_ABOUT_PAGE_CURRENT_CHANNEL_CANARY},
+ {"aboutChannelDev", IDS_SETTINGS_ABOUT_PAGE_CURRENT_CHANNEL_DEV},
+ {"aboutChannelLabel", IDS_SETTINGS_ABOUT_PAGE_CHANNEL},
+ {"aboutChannelStable", IDS_SETTINGS_ABOUT_PAGE_CURRENT_CHANNEL_STABLE},
+ {"aboutCheckForUpdates", IDS_SETTINGS_ABOUT_PAGE_CHECK_FOR_UPDATES},
+ {"aboutCurrentlyOnChannel", IDS_SETTINGS_ABOUT_PAGE_CURRENT_CHANNEL},
+ {"aboutDetailedBuildInfo", IDS_SETTINGS_ABOUT_PAGE_DETAILED_BUILD_INFO},
+ {version_ui::kApplicationLabel, IDS_PRODUCT_NAME},
+ {version_ui::kPlatform, IDS_PLATFORM_LABEL},
+ {version_ui::kFirmwareVersion, IDS_VERSION_UI_FIRMWARE_VERSION},
+ {version_ui::kARC, IDS_ARC_LABEL},
+ {"aboutBuildDetailsCopyTooltipLabel",
+ IDS_OS_SETTINGS_ABOUT_PAGE_BUILD_DETAILS_COPY_TOOLTIP_LABEL},
+ {"aboutIsArcStatusTitle", IDS_OS_SETTINGS_ABOUT_ARC_STATUS_TITLE},
+ {"aboutIsDeveloperModeTitle", IDS_OS_SETTINGS_ABOUT_DEVELOPER_MODE},
+ {"isEnterpriseManagedTitle",
+ IDS_OS_SETTINGS_ABOUT_PAGE_ENTERPRISE_ENNROLLED_TITLE},
+ {"aboutOsPageTitle", IDS_SETTINGS_ABOUT_OS},
+ {"aboutGetHelpUsingChromeOs", IDS_SETTINGS_GET_HELP_USING_CHROME_OS},
+ {"aboutOsProductTitle", IDS_PRODUCT_OS_NAME},
+ {"aboutReleaseNotesOffline", IDS_SETTINGS_ABOUT_PAGE_RELEASE_NOTES},
+ {"aboutShowReleaseNotes", IDS_SETTINGS_ABOUT_PAGE_SHOW_RELEASE_NOTES},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddString("aboutTPMFirmwareUpdateLearnMoreURL",
+ chrome::kTPMFirmwareUpdateLearnMoreURL);
+ html_source->AddString(
+ "aboutUpgradeUpToDate",
+ ui::SubstituteChromeOSDeviceType(IDS_SETTINGS_UPGRADE_UP_TO_DATE));
+ html_source->AddString("managementPage",
+ ManagementUI::GetManagementPageSubtitle(profile));
+}
+
+void AddResetStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"resetPageTitle", IDS_SETTINGS_RESET},
+ {"powerwashTitle", IDS_SETTINGS_FACTORY_RESET},
+ {"powerwashDialogTitle", IDS_SETTINGS_FACTORY_RESET_HEADING},
+ {"powerwashDialogButton", IDS_SETTINGS_RESTART},
+ {"powerwashButton", IDS_SETTINGS_FACTORY_RESET_BUTTON_LABEL},
+ {"powerwashDialogExplanation", IDS_SETTINGS_FACTORY_RESET_WARNING},
+ {"powerwashLearnMoreUrl", IDS_FACTORY_RESET_HELP_URL},
+ {"powerwashButtonRoleDescription",
+ IDS_SETTINGS_FACTORY_RESET_BUTTON_ROLE},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddString(
+ "powerwashDescription",
+ l10n_util::GetStringFUTF16(IDS_SETTINGS_FACTORY_RESET_DESCRIPTION,
+ l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)));
+}
+
+void AddSearchStrings(content::WebUIDataSource* html_source, Profile* profile) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"osSearchEngineLabel", IDS_OS_SETTINGS_SEARCH_ENGINE_LABEL},
+ {"searchGoogleAssistant", IDS_SETTINGS_SEARCH_GOOGLE_ASSISTANT},
+ {"searchGoogleAssistantEnabled",
+ IDS_SETTINGS_SEARCH_GOOGLE_ASSISTANT_ENABLED},
+ {"searchGoogleAssistantDisabled",
+ IDS_SETTINGS_SEARCH_GOOGLE_ASSISTANT_DISABLED},
+ {"searchGoogleAssistantOn", IDS_SETTINGS_SEARCH_GOOGLE_ASSISTANT_ON},
+ {"searchGoogleAssistantOff", IDS_SETTINGS_SEARCH_GOOGLE_ASSISTANT_OFF},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ // NOTE: This will be false when the flag is disabled.
+ const bool is_assistant_allowed =
+ ::assistant::IsAssistantAllowedForProfile(profile) ==
+ ash::mojom::AssistantAllowedState::ALLOWED;
+ html_source->AddBoolean("isAssistantAllowed", is_assistant_allowed);
+ html_source->AddLocalizedString("osSearchPageTitle",
+ is_assistant_allowed
+ ? IDS_SETTINGS_SEARCH_AND_ASSISTANT
+ : IDS_SETTINGS_SEARCH);
+ html_source->AddString("searchExplanation",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_SEARCH_EXPLANATION,
+ base::ASCIIToUTF16(chrome::kOmniboxLearnMoreURL)));
+ html_source->AddString(
+ "osSearchEngineTooltip",
+ ui::SubstituteChromeOSDeviceType(IDS_OS_SETTINGS_SEARCH_ENGINE_TOOLTIP));
+}
+
+void AddPrivacyStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"privacyPageTitle", IDS_SETTINGS_PRIVACY},
+ {"enableLogging", IDS_SETTINGS_ENABLE_LOGGING_PREF},
+ {"enableLoggingDesc", IDS_SETTINGS_ENABLE_LOGGING_PREF_DESC},
+ {"wakeOnWifi", IDS_SETTINGS_WAKE_ON_WIFI_DESCRIPTION},
+ {"enableContentProtectionAttestation",
+ IDS_SETTINGS_ENABLE_CONTENT_PROTECTION_ATTESTATION},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddString("syncAndGoogleServicesLearnMoreURL",
+ chrome::kSyncAndGoogleServicesLearnMoreURL);
+ ::settings::AddPersonalizationOptionsStrings(html_source);
+}
+
+void AddPeoplePageStrings(content::WebUIDataSource* html_source,
+ Profile* profile) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"osPeoplePageTitle", IDS_OS_SETTINGS_PEOPLE},
+ {"accountManagerSubMenuLabel",
+ IDS_SETTINGS_ACCOUNT_MANAGER_SUBMENU_LABEL},
+ {"accountManagerPageTitle", IDS_SETTINGS_ACCOUNT_MANAGER_PAGE_TITLE},
+ {"kerberosAccountsSubMenuLabel",
+ IDS_SETTINGS_KERBEROS_ACCOUNTS_SUBMENU_LABEL},
+ {"accountManagerPageTitle", IDS_SETTINGS_ACCOUNT_MANAGER_PAGE_TITLE},
+ {"kerberosAccountsPageTitle", IDS_SETTINGS_KERBEROS_ACCOUNTS_PAGE_TITLE},
+ {"lockScreenFingerprintTitle",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_FINGERPRINT_SUBPAGE_TITLE},
+ {"manageOtherPeople", IDS_SETTINGS_PEOPLE_MANAGE_OTHER_PEOPLE},
+ {"osSyncPageTitle", IDS_OS_SETTINGS_SYNC_PAGE_TITLE},
+ {"syncAndNonPersonalizedServices",
+ IDS_SETTINGS_SYNC_SYNC_AND_NON_PERSONALIZED_SERVICES},
+ {"syncDisconnectConfirm", IDS_SETTINGS_SYNC_DISCONNECT_CONFIRM},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ // Toggles the Chrome OS Account Manager submenu in the People section.
+ html_source->AddBoolean("isAccountManagerEnabled",
+ chromeos::IsAccountManagerAvailable(profile));
+
+ if (chromeos::features::IsSplitSyncConsentEnabled()) {
+ static constexpr webui::LocalizedString kTurnOffStrings[] = {
+ {"syncDisconnect", IDS_SETTINGS_PEOPLE_SYNC_TURN_OFF},
+ {"syncDisconnectTitle",
+ IDS_SETTINGS_TURN_OFF_SYNC_AND_SIGN_OUT_DIALOG_TITLE},
+ };
+ AddLocalizedStringsBulk(html_source, kTurnOffStrings);
+ } else {
+ static constexpr webui::LocalizedString kSignOutStrings[] = {
+ {"syncDisconnect", IDS_SETTINGS_PEOPLE_SIGN_OUT},
+ {"syncDisconnectTitle", IDS_SETTINGS_SYNC_DISCONNECT_TITLE},
+ };
+ AddLocalizedStringsBulk(html_source, kSignOutStrings);
+ }
+
+ std::string sync_dashboard_url =
+ google_util::AppendGoogleLocaleParam(
+ GURL(chrome::kSyncGoogleDashboardURL),
+ g_browser_process->GetApplicationLocale())
+ .spec();
+
+ html_source->AddString(
+ "syncDisconnectExplanation",
+ l10n_util::GetStringFUTF8(IDS_SETTINGS_SYNC_DISCONNECT_EXPLANATION,
+ base::ASCIIToUTF16(sync_dashboard_url)));
+
+ AddAccountManagerPageStrings(html_source);
+ AddKerberosAccountsPageStrings(html_source);
+ AddKerberosAddAccountDialogStrings(html_source);
+ AddLockScreenPageStrings(html_source);
+ AddFingerprintListStrings(html_source);
+ AddFingerprintStrings(html_source);
+ AddSetupFingerprintDialogStrings(html_source);
+ AddSetupPinDialogStrings(html_source);
+ AddSyncControlsStrings(html_source);
+
+ ::settings::AddSyncControlsStrings(html_source);
+ ::settings::AddSyncAccountControlStrings(html_source);
+ ::settings::AddPasswordPromptDialogStrings(html_source);
+ ::settings::AddSyncPageStrings(html_source);
+}
+
+void AddPageVisibilityStrings(content::WebUIDataSource* html_source) {
+ PrefService* local_state = g_browser_process->local_state();
+ // Toggles the Chrome OS Kerberos Accounts submenu in the People section.
+ // Note that the handler is also dependent on this pref.
+ html_source->AddBoolean("isKerberosEnabled",
+ local_state->GetBoolean(prefs::kKerberosEnabled));
+}
+
+} // namespace
+
+OsSettingsLocalizedStringsProvider::OsSettingsLocalizedStringsProvider(
+ Profile* profile,
+ local_search_service::mojom::LocalSearchService* local_search_service) {
+ local_search_service->GetIndex(
+ local_search_service::mojom::LocalSearchService::IndexId::CROS_SETTINGS,
+ index_remote_.BindNewPipeAndPassReceiver());
+
+ // Add per-page string providers.
+ // TODO(khorimoto): Add providers for the remaining pages.
+ per_page_providers_.push_back(
+ std::make_unique<InternetStringsProvider>(profile, /*delegate=*/this));
+}
+
+OsSettingsLocalizedStringsProvider::~OsSettingsLocalizedStringsProvider() =
+ default;
+
+void OsSettingsLocalizedStringsProvider::AddOsLocalizedStrings(
+ content::WebUIDataSource* html_source,
+ Profile* profile) {
+ for (const auto& per_page_provider : per_page_providers_)
+ per_page_provider->AddUiStrings(html_source);
+
+ // TODO(khorimoto): Migrate these to OsSettingsPerPageStringsProvider
+ // instances.
+ AddAboutStrings(html_source, profile);
+ AddA11yStrings(html_source);
+ AddAndroidAppStrings(html_source);
+ AddAppManagementStrings(html_source);
+ AddAppsStrings(html_source);
+ AddBluetoothStrings(html_source);
+ AddChromeOSUserStrings(html_source, profile);
+ AddCommonStrings(html_source, profile);
+ AddCrostiniStrings(html_source, profile);
+ AddDateTimeStrings(html_source);
+ AddDeviceStrings(html_source);
+ AddFilesStrings(html_source);
+ AddGoogleAssistantStrings(html_source, profile);
+ AddLanguagesStrings(html_source);
+ AddMultideviceStrings(html_source);
+ AddParentalControlStrings(html_source, profile);
+ AddPageVisibilityStrings(html_source);
+ AddPeoplePageStrings(html_source, profile);
+ AddPersonalizationStrings(html_source);
+ AddPluginVmStrings(html_source, profile);
+ AddPrintingStrings(html_source);
+ AddPrivacyStrings(html_source);
+ AddResetStrings(html_source);
+ AddSearchInSettingsStrings(html_source);
+ AddSearchStrings(html_source, profile);
+ AddUsersStrings(html_source);
+
+ policy_indicator::AddLocalizedStrings(html_source);
+
+ html_source->UseStringsJs();
+}
+
+const SearchConcept*
+OsSettingsLocalizedStringsProvider::GetCanonicalTagMetadata(
+ int canonical_message_id) const {
+ const auto it = canonical_id_to_metadata_map_.find(canonical_message_id);
+ if (it == canonical_id_to_metadata_map_.end())
+ return nullptr;
+ return it->second;
+}
+
+void OsSettingsLocalizedStringsProvider::Shutdown() {
+ index_remote_.reset();
+}
+
+void OsSettingsLocalizedStringsProvider::AddSearchTags(
+ const std::vector<SearchConcept>& tags_group) {
+ index_remote_->AddOrUpdate(ConceptVectorToDataPtrVector(tags_group),
+ /*callback=*/base::DoNothing());
+
+ // Add each concept to the map. Note that it is safe to take the address of
+ // each concept because all concepts are allocated via static
+ // base::NoDestructor objects in the Get*SearchConcepts() helper functions.
+ for (const auto& concept : tags_group)
+ canonical_id_to_metadata_map_[concept.canonical_message_id] = &concept;
+}
+
+void OsSettingsLocalizedStringsProvider::RemoveSearchTags(
+ const std::vector<SearchConcept>& tags_group) {
+ std::vector<std::string> ids;
+ for (const auto& concept : tags_group) {
+ canonical_id_to_metadata_map_.erase(concept.canonical_message_id);
+ ids.push_back(base::NumberToString(concept.canonical_message_id));
+ }
+
+ index_remote_->Delete(ids, /*callback=*/base::DoNothing());
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.h b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.h
new file mode 100644
index 00000000000..c0d8c5adcd2
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.h
@@ -0,0 +1,91 @@
+// Copyright 2020 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 CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_OS_SETTINGS_LOCALIZED_STRINGS_PROVIDER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_OS_SETTINGS_LOCALIZED_STRINGS_PROVIDER_H_
+
+#include <memory>
+#include <unordered_map>
+#include <vector>
+
+#include "chrome/browser/ui/webui/settings/chromeos/os_settings_per_page_strings_provider.h"
+#include "chrome/services/local_search_service/public/mojom/local_search_service.mojom.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "mojo/public/cpp/bindings/remote.h"
+
+class Profile;
+
+namespace content {
+class WebUIDataSource;
+} // namespace content
+
+namespace chromeos {
+namespace settings {
+
+struct SearchConcept;
+
+// Provides two types of localized strings for OS settings:
+//
+// (1) UI strings: Strings displayed in the normal settings UI. This contains
+// strings such as headers, labels, instructional notes, etc. These strings
+// are added directly to the settings app's WebUIDataSource before the app
+// starts up via the static AddOsLocalizedStrings() function and are
+// accessible within settings via loadTimeData.
+//
+// (2) Search tags: Strings used as potential matches for user search queries
+// within settings. These strings don't appear in the normal UI; instead,
+// they specify actions which can be taken in settings. When a user types a
+// search query in settings, we compare the query against these strings to
+// look for potential matches. For each potential search result, there is a
+// "canonical" tag which represents a common phrase, and zero or more
+// alternate phrases (e.g., canonical: "Display settings", alternate:
+// "Monitor settings").
+//
+// Since some of the settings sections may be unavailable (e.g., we don't
+// show Bluetooth settings unless the device has Bluetooth capabilities),
+// these strings are added/removed according to the Add/Remove*SearchTags()
+// instance functions.
+class OsSettingsLocalizedStringsProvider
+ : public KeyedService,
+ public OsSettingsPerPageStringsProvider::Delegate {
+ public:
+ OsSettingsLocalizedStringsProvider(
+ Profile* profile,
+ local_search_service::mojom::LocalSearchService* local_search_service);
+ OsSettingsLocalizedStringsProvider(
+ const OsSettingsLocalizedStringsProvider& other) = delete;
+ OsSettingsLocalizedStringsProvider& operator=(
+ const OsSettingsLocalizedStringsProvider& other) = delete;
+ ~OsSettingsLocalizedStringsProvider() override;
+
+ // Adds the strings needed by the OS settings page to |html_source|
+ // This function causes |html_source| to expose a strings.js file from its
+ // source which contains a mapping from string's name to its translated value.
+ void AddOsLocalizedStrings(content::WebUIDataSource* html_source,
+ Profile* profile);
+
+ // Returns the tag metadata associated with |canonical_message_id|, which must
+ // be one of the canonical IDS_SETTINGS_TAG_* identifiers used for a search
+ // tag. If no metadata is available or if |canonical_message_id| instead
+ // refers to an alternate tag's ID, null is returned.
+ const SearchConcept* GetCanonicalTagMetadata(int canonical_message_id) const;
+
+ private:
+ // KeyedService:
+ void Shutdown() override;
+
+ // OsSettingsPerPageStringsProvider::Delegate:
+ void AddSearchTags(const std::vector<SearchConcept>& tags_group) override;
+ void RemoveSearchTags(const std::vector<SearchConcept>& tags_group) override;
+
+ std::vector<std::unique_ptr<OsSettingsPerPageStringsProvider>>
+ per_page_providers_;
+ mojo::Remote<local_search_service::mojom::Index> index_remote_;
+ std::unordered_map<int, const SearchConcept*> canonical_id_to_metadata_map_;
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_OS_SETTINGS_LOCALIZED_STRINGS_PROVIDER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_factory.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_factory.cc
new file mode 100644
index 00000000000..8375790e5ca
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_factory.cc
@@ -0,0 +1,66 @@
+// Copyright 2020 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 "chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_factory.h"
+
+#include "chrome/browser/local_search_service/local_search_service_proxy.h"
+#include "chrome/browser/local_search_service/local_search_service_proxy_factory.h"
+#include "chrome/browser/profiles/incognito_helpers.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+
+namespace chromeos {
+namespace settings {
+
+// static
+OsSettingsLocalizedStringsProvider*
+OsSettingsLocalizedStringsProviderFactory::GetForProfile(Profile* profile) {
+ return static_cast<OsSettingsLocalizedStringsProvider*>(
+ OsSettingsLocalizedStringsProviderFactory::GetInstance()
+ ->GetServiceForBrowserContext(profile, /*create=*/true));
+}
+
+// static
+OsSettingsLocalizedStringsProviderFactory*
+OsSettingsLocalizedStringsProviderFactory::GetInstance() {
+ return base::Singleton<OsSettingsLocalizedStringsProviderFactory>::get();
+}
+
+OsSettingsLocalizedStringsProviderFactory::
+ OsSettingsLocalizedStringsProviderFactory()
+ : BrowserContextKeyedServiceFactory(
+ "OsSettingsLocalizedStringsProvider",
+ BrowserContextDependencyManager::GetInstance()) {
+ DependsOn(
+ local_search_service::LocalSearchServiceProxyFactory::GetInstance());
+}
+
+OsSettingsLocalizedStringsProviderFactory::
+ ~OsSettingsLocalizedStringsProviderFactory() = default;
+
+KeyedService*
+OsSettingsLocalizedStringsProviderFactory::BuildServiceInstanceFor(
+ content::BrowserContext* context) const {
+ Profile* profile = Profile::FromBrowserContext(context);
+ return new OsSettingsLocalizedStringsProvider(
+ profile,
+ local_search_service::LocalSearchServiceProxyFactory::GetForProfile(
+ Profile::FromBrowserContext(profile))
+ ->GetLocalSearchService());
+}
+
+bool OsSettingsLocalizedStringsProviderFactory::ServiceIsNULLWhileTesting()
+ const {
+ return true;
+}
+
+content::BrowserContext*
+OsSettingsLocalizedStringsProviderFactory::GetBrowserContextToUse(
+ content::BrowserContext* context) const {
+ return chrome::GetBrowserContextOwnInstanceInIncognito(context);
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_factory.h b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_factory.h
new file mode 100644
index 00000000000..d1b7df331e2
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_factory.h
@@ -0,0 +1,47 @@
+// Copyright 2020 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 CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_OS_SETTINGS_LOCALIZED_STRINGS_PROVIDER_FACTORY_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_OS_SETTINGS_LOCALIZED_STRINGS_PROVIDER_FACTORY_H_
+
+#include "base/memory/singleton.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+
+class Profile;
+
+namespace chromeos {
+namespace settings {
+
+class OsSettingsLocalizedStringsProvider;
+
+class OsSettingsLocalizedStringsProviderFactory
+ : public BrowserContextKeyedServiceFactory {
+ public:
+ static OsSettingsLocalizedStringsProvider* GetForProfile(Profile* profile);
+ static OsSettingsLocalizedStringsProviderFactory* GetInstance();
+
+ private:
+ friend struct base::DefaultSingletonTraits<
+ OsSettingsLocalizedStringsProviderFactory>;
+
+ OsSettingsLocalizedStringsProviderFactory();
+ ~OsSettingsLocalizedStringsProviderFactory() override;
+
+ OsSettingsLocalizedStringsProviderFactory(
+ const OsSettingsLocalizedStringsProviderFactory&) = delete;
+ OsSettingsLocalizedStringsProviderFactory& operator=(
+ const OsSettingsLocalizedStringsProviderFactory&) = delete;
+
+ // BrowserContextKeyedServiceFactory:
+ KeyedService* BuildServiceInstanceFor(
+ content::BrowserContext* context) const override;
+ bool ServiceIsNULLWhileTesting() const override;
+ content::BrowserContext* GetBrowserContextToUse(
+ content::BrowserContext* context) const override;
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_OS_SETTINGS_LOCALIZED_STRINGS_PROVIDER_FACTORY_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_unittest.cc
new file mode 100644
index 00000000000..c8eb26b6746
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_unittest.cc
@@ -0,0 +1,104 @@
+// Copyright 2020 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 "chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.h"
+
+#include "base/run_loop.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/search_concept.h"
+#include "chrome/common/webui_url_constants.h"
+#include "chrome/grit/generated_resources.h"
+#include "chrome/services/local_search_service/local_search_service_impl.h"
+#include "chrome/services/local_search_service/public/mojom/local_search_service.mojom-test-utils.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "chrome/test/base/testing_profile.h"
+#include "chrome/test/base/testing_profile_manager.h"
+#include "chromeos/network/network_state_test_helper.h"
+#include "chromeos/services/network_config/public/cpp/cros_network_config_test_helper.h"
+#include "content/public/test/browser_task_environment.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/cros_system_api/dbus/shill/dbus-constants.h"
+
+namespace chromeos {
+namespace settings {
+
+class OsSettingsLocalizedStringsProviderTest : public testing::Test {
+ protected:
+ OsSettingsLocalizedStringsProviderTest()
+ : profile_manager_(TestingBrowserProcess::GetGlobal()) {}
+ ~OsSettingsLocalizedStringsProviderTest() override = default;
+
+ // testing::Test:
+ void SetUp() override {
+ ASSERT_TRUE(profile_manager_.SetUp());
+
+ provider_ = std::make_unique<OsSettingsLocalizedStringsProvider>(
+ profile_manager_.CreateTestingProfile("TestingProfile"),
+ &local_search_service_);
+
+ local_search_service_.GetIndex(
+ local_search_service::mojom::LocalSearchService::IndexId::CROS_SETTINGS,
+ index_remote_.BindNewPipeAndPassReceiver());
+
+ // Allow asynchronous networking code to complete (networking functionality
+ // is tested below).
+ base::RunLoop().RunUntilIdle();
+ }
+
+ content::BrowserTaskEnvironment task_environment_;
+ TestingProfileManager profile_manager_;
+ chromeos::network_config::CrosNetworkConfigTestHelper network_config_helper_;
+ mojo::Remote<local_search_service::mojom::Index> index_remote_;
+ local_search_service::LocalSearchServiceImpl local_search_service_;
+ std::unique_ptr<OsSettingsLocalizedStringsProvider> provider_;
+};
+
+// To prevent this from becoming a change-detector test, this test simply
+// verifies that when the provider starts up, it adds *some* strings without
+// checking the exact number. It also checks one specific canonical tag.
+TEST_F(OsSettingsLocalizedStringsProviderTest, WifiTags) {
+ uint64_t initial_num_items = 0;
+ local_search_service::mojom::IndexAsyncWaiter(index_remote_.get())
+ .GetSize(&initial_num_items);
+ EXPECT_GT(initial_num_items, 0u);
+
+ const SearchConcept* network_settings_concept =
+ provider_->GetCanonicalTagMetadata(IDS_SETTINGS_TAG_NETWORK_SETTINGS);
+ ASSERT_TRUE(network_settings_concept);
+ EXPECT_EQ(chrome::kNetworksSubPage,
+ network_settings_concept->url_path_with_parameters);
+ EXPECT_EQ(mojom::SearchResultIcon::kWifi, network_settings_concept->icon);
+
+ // Ethernet is not present by default, so no Ethernet concepts have yet been
+ // added.
+ const SearchConcept* ethernet_settings_concept =
+ provider_->GetCanonicalTagMetadata(IDS_SETTINGS_TAG_ETHERNET_SETTINGS);
+ ASSERT_FALSE(ethernet_settings_concept);
+
+ // Add Ethernet and let asynchronous handlers run. This should cause Ethernet
+ // tags to be added.
+ network_config_helper_.network_state_helper().device_test()->AddDevice(
+ "/device/stub_eth_device", shill::kTypeEthernet, "stub_eth_device");
+ base::RunLoop().RunUntilIdle();
+
+ uint64_t num_items_after_adding_ethernet = 0;
+ local_search_service::mojom::IndexAsyncWaiter(index_remote_.get())
+ .GetSize(&num_items_after_adding_ethernet);
+ EXPECT_GT(num_items_after_adding_ethernet, initial_num_items);
+
+ ethernet_settings_concept =
+ provider_->GetCanonicalTagMetadata(IDS_SETTINGS_TAG_ETHERNET_SETTINGS);
+ ASSERT_TRUE(ethernet_settings_concept);
+ EXPECT_EQ(chrome::kEthernetSettingsSubPage,
+ ethernet_settings_concept->url_path_with_parameters);
+ EXPECT_EQ(mojom::SearchResultIcon::kEthernet,
+ ethernet_settings_concept->icon);
+}
+
+// Note that other tests do not need to be added for different group of tags,
+// since these tests would only be verifying the contents of
+// os_settings_localized_strings_provider.cc.
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_per_page_strings_provider.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_per_page_strings_provider.cc
new file mode 100644
index 00000000000..26ac31b8cf6
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_per_page_strings_provider.cc
@@ -0,0 +1,32 @@
+// Copyright 2020 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 "chrome/browser/ui/webui/settings/chromeos/os_settings_per_page_strings_provider.h"
+
+#include "base/logging.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/system/sys_info.h"
+
+namespace chromeos {
+namespace settings {
+
+// static
+base::string16 OsSettingsPerPageStringsProvider::GetHelpUrlWithBoard(
+ const std::string& original_url) {
+ return base::ASCIIToUTF16(original_url +
+ "&b=" + base::SysInfo::GetLsbReleaseBoard());
+}
+
+OsSettingsPerPageStringsProvider::~OsSettingsPerPageStringsProvider() = default;
+
+OsSettingsPerPageStringsProvider::OsSettingsPerPageStringsProvider(
+ Profile* profile,
+ Delegate* delegate)
+ : profile_(profile), delegate_(delegate) {
+ DCHECK(profile);
+ DCHECK(delegate);
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_per_page_strings_provider.h b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_per_page_strings_provider.h
new file mode 100644
index 00000000000..c2a6771c85b
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_per_page_strings_provider.h
@@ -0,0 +1,73 @@
+// Copyright 2020 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 CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_OS_SETTINGS_PER_PAGE_STRINGS_PROVIDER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_OS_SETTINGS_PER_PAGE_STRINGS_PROVIDER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/strings/string16.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/search_concept.h"
+
+class Profile;
+
+namespace content {
+class WebUIDataSource;
+} // namespace content
+
+namespace chromeos {
+namespace settings {
+
+// Provides strings for an individual page in OS settings (i.e., each subpage is
+// expected to have its own implementation. Responsible for two types of
+// strings:
+//
+// (1) UI strings: Strings (e.g., headers, labels) displayed in the settings UI.
+// Added to a WebUIDataSource via the pure virtual AddUiStrings() function.
+//
+// (2) Search tags: Strings used as potential matches for user search queries
+// within settings. Added/removed via the {Add|Remove}SearchTagsGroup
+// delegate functions. Tags which are always searchable should be added in
+// the class' constructor; however, tags which apply to content which is
+// dynamically shown/hidden should be added when that content is visible and
+// removed when the content is no longer visible.
+class OsSettingsPerPageStringsProvider {
+ public:
+ class Delegate {
+ public:
+ ~Delegate() = default;
+ virtual void AddSearchTags(
+ const std::vector<SearchConcept>& tags_group) = 0;
+ virtual void RemoveSearchTags(
+ const std::vector<SearchConcept>& tags_group) = 0;
+ };
+
+ virtual ~OsSettingsPerPageStringsProvider();
+
+ OsSettingsPerPageStringsProvider(
+ const OsSettingsPerPageStringsProvider& other) = delete;
+ OsSettingsPerPageStringsProvider& operator=(
+ const OsSettingsPerPageStringsProvider& other) = delete;
+
+ // Adds strings to be displayed in the UI via loadTimeData.
+ virtual void AddUiStrings(content::WebUIDataSource* html_source) const = 0;
+
+ protected:
+ static base::string16 GetHelpUrlWithBoard(const std::string& original_url);
+
+ OsSettingsPerPageStringsProvider(Profile* profile, Delegate* delegate);
+
+ Profile* profile() { return profile_; }
+ Delegate* delegate() { return delegate_; }
+
+ private:
+ Profile* profile_;
+ Delegate* delegate_;
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_OS_SETTINGS_PER_PAGE_STRINGS_PROVIDER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc
index a91606bde11..dd4edc8807a 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc
@@ -11,14 +11,32 @@
#include <utility>
#include <vector>
+#include "ash/public/cpp/ash_features.h"
#include "ash/public/cpp/network_config_service.h"
#include "ash/public/cpp/resources/grit/ash_public_unscaled_resources.h"
+#include "ash/public/cpp/stylus_utils.h"
#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/feature_list.h"
+#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_functions.h"
#include "build/build_config.h"
-#include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/browser_process_platform_part.h"
+#include "chrome/browser/chromeos/account_manager/account_manager_util.h"
+#include "chrome/browser/chromeos/arc/arc_util.h"
+#include "chrome/browser/chromeos/crostini/crostini_features.h"
+#include "chrome/browser/chromeos/login/demo_mode/demo_session.h"
+#include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.h"
+#include "chrome/browser/chromeos/multidevice_setup/multidevice_setup_client_factory.h"
+#include "chrome/browser/chromeos/plugin_vm/plugin_vm_pref_names.h"
+#include "chrome/browser/chromeos/plugin_vm/plugin_vm_util.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
+#include "chrome/browser/signin/identity_manager_factory.h"
+#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/webui/app_management/app_management.mojom.h"
#include "chrome/browser/ui/webui/app_management/app_management_page_handler.h"
+#include "chrome/browser/ui/webui/chromeos/smb_shares/smb_handler.h"
#include "chrome/browser/ui/webui/chromeos/sync/os_sync_handler.h"
#include "chrome/browser/ui/webui/managed_ui_handler.h"
#include "chrome/browser/ui/webui/metrics_handler.h"
@@ -26,7 +44,33 @@
#include "chrome/browser/ui/webui/settings/about_handler.h"
#include "chrome/browser/ui/webui/settings/accessibility_main_handler.h"
#include "chrome/browser/ui/webui/settings/browser_lifetime_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/account_manager_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/android_apps_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/crostini_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/date_time_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/device_pointer_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/device_power_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/google_assistant_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/internet_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/kerberos_accounts_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.h"
+#include "chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_factory.h"
#include "chrome/browser/ui/webui/settings/chromeos/parental_controls_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/pref_names.h"
+#include "chrome/browser/ui/webui/settings/chromeos/quick_unlock_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/search_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/search_handler_factory.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker.h"
#include "chrome/browser/ui/webui/settings/chromeos/wallpaper_handler.h"
#include "chrome/browser/ui/webui/settings/downloads_handler.h"
#include "chrome/browser/ui/webui/settings/extension_control_handler.h"
@@ -40,7 +84,9 @@
#include "chrome/browser/ui/webui/settings/settings_cookies_view_handler.h"
#include "chrome/browser/ui/webui/settings/settings_localized_strings_provider.h"
#include "chrome/browser/ui/webui/settings/settings_media_devices_selection_handler.h"
-#include "chrome/browser/ui/webui/settings/settings_ui.h"
+#include "chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.h"
+#include "chrome/browser/ui/webui/settings/tts_handler.h"
+#include "chrome/browser/ui/webui/webui_util.h"
#include "chrome/browser/web_applications/system_web_app_manager.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/webui_url_constants.h"
@@ -48,17 +94,36 @@
#include "chrome/grit/generated_resources.h"
#include "chrome/grit/os_settings_resources.h"
#include "chrome/grit/os_settings_resources_map.h"
+#include "chromeos/components/account_manager/account_manager.h"
+#include "chromeos/components/account_manager/account_manager_factory.h"
+#include "chromeos/components/web_applications/manifest_request_filter.h"
#include "chromeos/constants/chromeos_features.h"
+#include "chromeos/constants/chromeos_pref_names.h"
+#include "chromeos/login/auth/password_visibility_utils.h"
+#include "chromeos/services/multidevice_setup/public/cpp/prefs.h"
#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h"
#include "components/password_manager/core/common/password_manager_features.h"
+#include "components/pref_registry/pref_registry_syncable.h"
+#include "components/prefs/pref_service.h"
#include "content/public/browser/web_ui_data_source.h"
+#include "media/base/media_switches.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "ui/base/webui/web_ui_util.h"
+#include "ui/chromeos/resources/grit/ui_chromeos_resources.h"
+#include "ui/resources/grit/webui_resources.h"
namespace chromeos {
namespace settings {
+// static
+void OSSettingsUI::RegisterProfilePrefs(
+ user_prefs::PrefRegistrySyncable* registry) {
+ registry->RegisterBooleanPref(prefs::kSyncOsWallpaper, false);
+}
+
OSSettingsUI::OSSettingsUI(content::WebUI* web_ui)
: ui::MojoWebUIController(web_ui, /*enable_chrome_send=*/true),
+ time_when_opened_(base::TimeTicks::Now()),
webui_load_timer_(web_ui->GetWebContents(),
"ChromeOS.Settings.LoadDocumentTime",
"ChromeOS.Settings.LoadCompletedTime") {
@@ -66,7 +131,7 @@ OSSettingsUI::OSSettingsUI(content::WebUI* web_ui)
content::WebUIDataSource* html_source =
content::WebUIDataSource::Create(chrome::kChromeUIOSSettingsHost);
- ::settings::SettingsUI::InitOSWebUIHandlers(profile, web_ui, html_source);
+ InitOSWebUIHandlers(html_source);
// This handler is for chrome://os-settings.
html_source->AddBoolean("isOSSettings", true);
@@ -78,6 +143,9 @@ OSSettingsUI::OSSettingsUI(content::WebUI* web_ui)
html_source->AddBoolean(
"showParentalControls",
chromeos::settings::ShouldShowParentalControls(profile));
+ html_source->AddBoolean(
+ "syncSetupFriendlySettings",
+ base::FeatureList::IsEnabled(::features::kSyncSetupFriendlySettings));
AddSettingsPageUIHandler(
std::make_unique<::settings::AccessibilityMainHandler>());
@@ -103,19 +171,17 @@ OSSettingsUI::OSSettingsUI(content::WebUI* web_ui)
std::make_unique<::settings::ProtocolHandlersHandler>());
AddSettingsPageUIHandler(
std::make_unique<::settings::SearchEnginesHandler>(profile));
- AddSettingsPageUIHandler(
- std::make_unique<chromeos::settings::WallpaperHandler>(web_ui));
html_source->AddBoolean("showAppManagement", base::FeatureList::IsEnabled(
::features::kAppManagement));
html_source->AddBoolean("splitSettingsSyncEnabled",
chromeos::features::IsSplitSettingsSyncEnabled());
+ html_source->AddBoolean("splitSyncConsent",
+ chromeos::features::IsSplitSyncConsentEnabled());
-#if defined(OS_CHROMEOS)
html_source->AddBoolean(
"isSupportedArcVersion",
AppManagementPageHandler::IsCurrentArcVersionSupported(profile));
-#endif // OS_CHROMEOS
AddSettingsPageUIHandler(
base::WrapUnique(::settings::AboutHandler::Create(html_source, profile)));
@@ -126,7 +192,6 @@ OSSettingsUI::OSSettingsUI(content::WebUI* web_ui)
web_ui->AddMessageHandler(std::make_unique<MetricsHandler>());
// Add the System Web App resources for Settings.
- // TODO(jamescook|calamity): Migrate to chromeos::settings::OSSettingsUI.
if (web_app::SystemWebAppManager::IsEnabled()) {
html_source->AddResourcePath("icon-192.png", IDR_SETTINGS_LOGO_192);
html_source->AddResourcePath("pwa.html", IDR_PWA_HTML);
@@ -151,18 +216,37 @@ OSSettingsUI::OSSettingsUI(content::WebUI* web_ui)
#endif
html_source->AddResourcePath("app-management/app_management.mojom-lite.js",
- IDR_APP_MANAGEMENT_MOJO_LITE_JS);
- html_source->AddResourcePath("app-management/types.mojom-lite.js",
- IDR_APP_MANAGEMENT_TYPES_MOJO_LITE_JS);
- html_source->AddResourcePath("app-management/bitmap.mojom-lite.js",
- IDR_APP_MANAGEMENT_BITMAP_MOJO_LITE_JS);
- html_source->AddResourcePath("app-management/image.mojom-lite.js",
- IDR_APP_MANAGEMENT_IMAGE_MOJO_LITE_JS);
- html_source->AddResourcePath("app-management/image_info.mojom-lite.js",
- IDR_APP_MANAGEMENT_IMAGE_INFO_MOJO_LITE_JS);
-
- ::settings::AddLocalizedStrings(html_source, profile,
- web_ui->GetWebContents());
+ IDR_OS_SETTINGS_APP_MANAGEMENT_MOJO_LITE_JS);
+ html_source->AddResourcePath(
+ "app-management/types.mojom-lite.js",
+ IDR_OS_SETTINGS_APP_MANAGEMENT_TYPES_MOJO_LITE_JS);
+ html_source->AddResourcePath(
+ "app-management/bitmap.mojom-lite.js",
+ IDR_OS_SETTINGS_APP_MANAGEMENT_BITMAP_MOJO_LITE_JS);
+ html_source->AddResourcePath(
+ "app-management/file_path.mojom-lite.js",
+ IDR_OS_SETTINGS_APP_MANAGEMENT_FILE_PATH_MOJO_LITE_JS);
+ html_source->AddResourcePath(
+ "app-management/image.mojom-lite.js",
+ IDR_OS_SETTINGS_APP_MANAGEMENT_IMAGE_MOJO_LITE_JS);
+ html_source->AddResourcePath(
+ "app-management/image_info.mojom-lite.js",
+ IDR_OS_SETTINGS_APP_MANAGEMENT_IMAGE_INFO_MOJO_LITE_JS);
+
+ html_source->AddResourcePath(
+ "search/user_action_recorder.mojom-lite.js",
+ IDR_OS_SETTINGS_USER_ACTION_RECORDER_MOJOM_LITE_JS);
+ html_source->AddResourcePath(
+ "search/search_result_icon.mojom-lite.js",
+ IDR_OS_SETTINGS_SEARCH_RESULT_ICON_MOJOM_LITE_JS);
+ html_source->AddResourcePath("search/search.mojom-lite.js",
+ IDR_OS_SETTINGS_SEARCH_MOJOM_LITE_JS);
+
+ // AddOsLocalizedStrings must be added after AddBrowserLocalizedStrings
+ // as repeated keys used by the OS strings should override the same keys
+ // that may be used in the Browser string provider.
+ OsSettingsLocalizedStringsProviderFactory::GetForProfile(profile)
+ ->AddOsLocalizedStrings(html_source, profile);
auto plural_string_handler = std::make_unique<PluralStringHandler>();
plural_string_handler->AddLocalizedString("profileLabel",
@@ -173,16 +257,210 @@ OSSettingsUI::OSSettingsUI(content::WebUI* web_ui)
content::WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(),
html_source);
+}
- AddHandlerToRegistry(base::BindRepeating(&OSSettingsUI::BindCrosNetworkConfig,
- base::Unretained(this)));
-
- AddHandlerToRegistry(
- base::BindRepeating(&OSSettingsUI::BindAppManagementPageHandlerFactory,
- base::Unretained(this)));
+OSSettingsUI::~OSSettingsUI() {
+ // Note: OSSettingsUI lifetime is tied to the lifetime of the browser window.
+ base::UmaHistogramCustomTimes("ChromeOS.Settings.WindowOpenDuration",
+ base::TimeTicks::Now() - time_when_opened_,
+ /*min=*/base::TimeDelta::FromMicroseconds(500),
+ /*max=*/base::TimeDelta::FromHours(1),
+ /*buckets=*/50);
}
-OSSettingsUI::~OSSettingsUI() = default;
+void OSSettingsUI::InitOSWebUIHandlers(content::WebUIDataSource* html_source) {
+ Profile* profile = Profile::FromWebUI(web_ui());
+
+ // TODO(jamescook): Sort out how account management is split between Chrome OS
+ // and browser settings.
+ if (chromeos::IsAccountManagerAvailable(profile)) {
+ chromeos::AccountManagerFactory* factory =
+ g_browser_process->platform_part()->GetAccountManagerFactory();
+ chromeos::AccountManager* account_manager =
+ factory->GetAccountManager(profile->GetPath().value());
+ DCHECK(account_manager);
+
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::AccountManagerUIHandler>(
+ account_manager, IdentityManagerFactory::GetForProfile(profile)));
+ html_source->AddBoolean(
+ "secondaryGoogleAccountSigninAllowed",
+ profile->GetPrefs()->GetBoolean(
+ chromeos::prefs::kSecondaryGoogleAccountSigninAllowed));
+ html_source->AddBoolean("isEduCoexistenceEnabled",
+ features::IsEduCoexistenceEnabled());
+ }
+
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::ChangePictureHandler>());
+
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::AccessibilityHandler>(profile));
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::AndroidAppsHandler>(profile));
+ if (crostini::CrostiniFeatures::Get()->IsUIAllowed(profile,
+ /*check_policy=*/false)) {
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::CrostiniHandler>(profile));
+ }
+ web_ui()->AddMessageHandler(
+ chromeos::settings::CupsPrintersHandler::Create(web_ui()));
+ web_ui()->AddMessageHandler(base::WrapUnique(
+ chromeos::settings::DateTimeHandler::Create(html_source)));
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::FingerprintHandler>(profile));
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::GoogleAssistantHandler>(profile));
+
+ std::unique_ptr<chromeos::settings::KerberosAccountsHandler>
+ kerberos_accounts_handler =
+ chromeos::settings::KerberosAccountsHandler::CreateIfKerberosEnabled(
+ profile);
+ if (kerberos_accounts_handler) {
+ // Note that the UI is enabled only if Kerberos is enabled.
+ web_ui()->AddMessageHandler(std::move(kerberos_accounts_handler));
+ }
+
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::KeyboardHandler>());
+
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::WallpaperHandler>(web_ui()));
+
+ // If |!allow_plugin_vm| we still want to |show_plugin_vm| if the VM image is
+ // on disk, so that users are still able to delete the image at will.
+ const bool allow_plugin_vm = plugin_vm::IsPluginVmAllowedForProfile(profile);
+ const bool show_plugin_vm =
+ allow_plugin_vm ||
+ profile->GetPrefs()->GetBoolean(plugin_vm::prefs::kPluginVmImageExists);
+
+ if (show_plugin_vm) {
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::PluginVmHandler>(profile));
+ }
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::PointerHandler>());
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::QuickUnlockHandler>());
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::StorageHandler>(profile,
+ html_source));
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::StylusHandler>());
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::InternetHandler>(profile));
+ web_ui()->AddMessageHandler(std::make_unique<::settings::TtsHandler>());
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::smb_dialog::SmbHandler>(profile,
+ base::DoNothing()));
+
+ if (!profile->IsGuestSession()) {
+ chromeos::android_sms::AndroidSmsService* android_sms_service =
+ chromeos::android_sms::AndroidSmsServiceFactory::GetForBrowserContext(
+ profile);
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::MultideviceHandler>(
+ profile->GetPrefs(),
+ chromeos::multidevice_setup::MultiDeviceSetupClientFactory::
+ GetForProfile(profile),
+ android_sms_service
+ ? android_sms_service->android_sms_pairing_state_tracker()
+ : nullptr,
+ android_sms_service ? android_sms_service->android_sms_app_manager()
+ : nullptr));
+ if (chromeos::settings::ShouldShowParentalControls(profile)) {
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::ParentalControlsHandler>(
+ profile));
+ }
+
+ if (chromeos::features::IsAmbientModeEnabled()) {
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::AmbientModeHandler>());
+ }
+ }
+
+ html_source->AddBoolean(
+ "privacySettingsRedesignEnabled",
+ base::FeatureList::IsEnabled(::features::kPrivacySettingsRedesign));
+
+ html_source->AddBoolean(
+ "multideviceAllowedByPolicy",
+ chromeos::multidevice_setup::AreAnyMultiDeviceFeaturesAllowed(
+ profile->GetPrefs()));
+ html_source->AddBoolean(
+ "quickUnlockEnabled",
+ chromeos::quick_unlock::IsPinEnabled(profile->GetPrefs()));
+ html_source->AddBoolean(
+ "quickUnlockDisabledByPolicy",
+ chromeos::quick_unlock::IsPinDisabledByPolicy(profile->GetPrefs()));
+ html_source->AddBoolean(
+ "userCannotManuallyEnterPassword",
+ !chromeos::password_visibility::AccountHasUserFacingPassword(
+ chromeos::ProfileHelper::Get()
+ ->GetUserByProfile(profile)
+ ->GetAccountId()));
+ const bool fingerprint_unlock_enabled =
+ chromeos::quick_unlock::IsFingerprintEnabled(profile);
+ html_source->AddBoolean("fingerprintUnlockEnabled",
+ fingerprint_unlock_enabled);
+ if (fingerprint_unlock_enabled) {
+ html_source->AddInteger(
+ "fingerprintReaderLocation",
+ static_cast<int32_t>(chromeos::quick_unlock::GetFingerprintLocation()));
+
+ // To use lottie, the worker-src CSP needs to be updated for the web ui that
+ // is using it. Since as of now there are only a couple of webuis using
+ // lottie animations, this update has to be performed manually. As the usage
+ // increases, set this as the default so manual override is no longer
+ // required.
+ html_source->OverrideContentSecurityPolicyWorkerSrc(
+ "worker-src blob: 'self';");
+ html_source->AddResourcePath("finger_print.json",
+ IDR_LOGIN_FINGER_PRINT_TABLET_ANIMATION);
+ }
+ html_source->AddBoolean("lockScreenNotificationsEnabled",
+ ash::features::IsLockScreenNotificationsEnabled());
+ html_source->AddBoolean(
+ "lockScreenHideSensitiveNotificationsSupported",
+ ash::features::IsLockScreenHideSensitiveNotificationsSupported());
+ html_source->AddBoolean("showTechnologyBadge",
+ !ash::features::IsSeparateNetworkIconsEnabled());
+ html_source->AddBoolean("hasInternalStylus",
+ ash::stylus_utils::HasInternalStylus());
+
+ html_source->AddBoolean("showCrostini",
+ crostini::CrostiniFeatures::Get()->IsUIAllowed(
+ profile, /*check_policy=*/false));
+
+ html_source->AddBoolean(
+ "allowCrostini", crostini::CrostiniFeatures::Get()->IsUIAllowed(profile));
+
+ html_source->AddBoolean("allowPluginVm", allow_plugin_vm);
+ html_source->AddBoolean("showPluginVm", show_plugin_vm);
+
+ html_source->AddBoolean("isDemoSession",
+ chromeos::DemoSession::IsDeviceInDemoMode());
+
+ // We have 2 variants of Android apps settings. Default case, when the Play
+ // Store app exists we show expandable section that allows as to
+ // enable/disable the Play Store and link to Android settings which is
+ // available once settings app is registered in the system.
+ // For AOSP images we don't have the Play Store app. In last case we Android
+ // apps settings consists only from root link to Android settings and only
+ // visible once settings app is registered.
+ html_source->AddBoolean("androidAppsVisible",
+ arc::IsArcAllowedForProfile(profile));
+ html_source->AddBoolean("havePlayStoreApp", arc::IsPlayStoreAvailable());
+
+ html_source->AddBoolean("enablePowerSettings", true);
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::PowerHandler>(profile->GetPrefs()));
+
+ html_source->AddBoolean(
+ "showParentalControlsSettings",
+ chromeos::settings::ShouldShowParentalControls(profile));
+}
void OSSettingsUI::AddSettingsPageUIHandler(
std::unique_ptr<content::WebUIMessageHandler> handler) {
@@ -190,12 +468,24 @@ void OSSettingsUI::AddSettingsPageUIHandler(
web_ui()->AddMessageHandler(std::move(handler));
}
-void OSSettingsUI::BindCrosNetworkConfig(
+void OSSettingsUI::BindInterface(
mojo::PendingReceiver<network_config::mojom::CrosNetworkConfig> receiver) {
ash::GetNetworkConfigService(std::move(receiver));
}
-void OSSettingsUI::BindAppManagementPageHandlerFactory(
+void OSSettingsUI::BindInterface(
+ mojo::PendingReceiver<mojom::UserActionRecorder> receiver) {
+ user_action_recorder_ =
+ std::make_unique<SettingsUserActionTracker>(std::move(receiver));
+}
+
+void OSSettingsUI::BindInterface(
+ mojo::PendingReceiver<mojom::SearchHandler> receiver) {
+ SearchHandlerFactory::GetForProfile(Profile::FromWebUI(web_ui()))
+ ->BindInterface(std::move(receiver));
+}
+
+void OSSettingsUI::BindInterface(
mojo::PendingReceiver<app_management::mojom::PageHandlerFactory> receiver) {
if (!app_management_page_handler_factory_) {
app_management_page_handler_factory_ =
@@ -205,5 +495,7 @@ void OSSettingsUI::BindAppManagementPageHandlerFactory(
app_management_page_handler_factory_->Bind(std::move(receiver));
}
+WEB_UI_CONTROLLER_TYPE_IMPL(OSSettingsUI)
+
} // namespace settings
} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.h b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.h
index ff325c20bc3..c72c6b57c22 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.h
@@ -8,40 +8,75 @@
#include <memory>
#include "base/macros.h"
+#include "base/time/time.h"
#include "chrome/browser/ui/webui/app_management/app_management.mojom-forward.h"
#include "chrome/browser/ui/webui/settings/chromeos/app_management/app_management_page_handler_factory.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/user_action_recorder.mojom-forward.h"
#include "chrome/browser/ui/webui/webui_load_timer.h"
#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom-forward.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "ui/webui/mojo_web_ui_controller.h"
namespace content {
+class WebUIDataSource;
class WebUIMessageHandler;
-}
+} // namespace content
+
+namespace user_prefs {
+class PrefRegistrySyncable;
+} // namespace user_prefs
namespace chromeos {
namespace settings {
+namespace mojom {
+class SearchHandler;
+} // namespace mojom
+
// The WebUI handler for chrome://os-settings.
class OSSettingsUI : public ui::MojoWebUIController {
public:
+ static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
+
explicit OSSettingsUI(content::WebUI* web_ui);
~OSSettingsUI() override;
- private:
- void AddSettingsPageUIHandler(
- std::unique_ptr<content::WebUIMessageHandler> handler);
- void BindCrosNetworkConfig(
+ // Initializes the WebUI message handlers for OS-specific settings.
+ void InitOSWebUIHandlers(content::WebUIDataSource* html_source);
+
+ // Instantiates implementor of the mojom::CrosNetworkConfig mojo interface
+ // passing the pending receiver that will be internally bound.
+ void BindInterface(
mojo::PendingReceiver<network_config::mojom::CrosNetworkConfig> receiver);
- void BindAppManagementPageHandlerFactory(
+
+ // Instantiates implementor of the mojom::UserActionRecorder mojo interface
+ // passing the pending receiver that will be internally bound.
+ void BindInterface(mojo::PendingReceiver<mojom::UserActionRecorder> receiver);
+
+ // Instantiates implementor of the mojom::SearchHandler mojo interface
+ // passing the pending receiver that will be internally bound.
+ void BindInterface(mojo::PendingReceiver<mojom::SearchHandler> receiver);
+
+ // Instantiates implementor of the mojom::PageHandlerFactory mojo interface
+ // passing the pending receiver that will be internally bound.
+ void BindInterface(
mojo::PendingReceiver<app_management::mojom::PageHandlerFactory>
receiver);
+ private:
+ void AddSettingsPageUIHandler(
+ std::unique_ptr<content::WebUIMessageHandler> handler);
+
+ base::TimeTicks time_when_opened_;
+
WebuiLoadTimer webui_load_timer_;
+ std::unique_ptr<mojom::UserActionRecorder> user_action_recorder_;
std::unique_ptr<AppManagementPageHandlerFactory>
app_management_page_handler_factory_;
+ WEB_UI_CONTROLLER_TYPE_DECL();
+
DISALLOW_COPY_AND_ASSIGN(OSSettingsUI);
};
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.cc
index 715782b0b11..db5d9d79e67 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.cc
@@ -12,6 +12,8 @@
#include "base/bind_helpers.h"
#include "chrome/browser/chromeos/file_manager/path_util.h"
#include "chrome/browser/chromeos/guest_os/guest_os_share_path.h"
+#include "chrome/browser/chromeos/plugin_vm/plugin_vm_manager.h"
+#include "chrome/browser/chromeos/plugin_vm/plugin_vm_util.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/browser_thread.h"
@@ -32,6 +34,14 @@ void PluginVmHandler::RegisterMessages() {
"removePluginVmSharedPath",
base::BindRepeating(&PluginVmHandler::HandleRemovePluginVmSharedPath,
weak_ptr_factory_.GetWeakPtr()));
+ web_ui()->RegisterMessageCallback(
+ "removePluginVm",
+ base::BindRepeating(&PluginVmHandler::HandleRemovePluginVm,
+ weak_ptr_factory_.GetWeakPtr()));
+ web_ui()->RegisterMessageCallback(
+ "requestPluginVmInstallerView",
+ base::BindRepeating(&PluginVmHandler::HandleRequestPluginVmInstallerView,
+ weak_ptr_factory_.GetWeakPtr()));
}
void PluginVmHandler::HandleGetPluginVmSharedPathsDisplayText(
@@ -68,5 +78,28 @@ void PluginVmHandler::HandleRemovePluginVmSharedPath(
path));
}
+void PluginVmHandler::HandleRemovePluginVm(const base::ListValue* args) {
+ CHECK_EQ(0U, args->GetSize());
+
+ auto* manager = plugin_vm::PluginVmManager::GetForProfile(profile_);
+ if (!manager) {
+ LOG(ERROR) << "removePluginVm called from an invalid profile.";
+ return;
+ }
+ manager->UninstallPluginVm();
+}
+
+void PluginVmHandler::HandleRequestPluginVmInstallerView(
+ const base::ListValue* args) {
+ CHECK(args->empty());
+
+ if (plugin_vm::IsPluginVmEnabled(profile_)) {
+ LOG(ERROR) << "requestPluginVmInstallerView called from a profile which "
+ "already has Plugin VM installed.";
+ return;
+ }
+ plugin_vm::ShowPluginVmInstallerView(profile_);
+}
+
} // namespace settings
} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.h
index d57b34da1db..b003a9e3e11 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.h
@@ -32,6 +32,10 @@ class PluginVmHandler : public ::settings::SettingsPageUIHandler {
void HandleGetPluginVmSharedPathsDisplayText(const base::ListValue* args);
// Remove a specified path from being shared.
void HandleRemovePluginVmSharedPath(const base::ListValue* args);
+ // Remove Plugin VM.
+ void HandleRemovePluginVm(const base::ListValue* args);
+ // Show the Plugin VM installer view if Plugin VM is not currently installed.
+ void HandleRequestPluginVmInstallerView(const base::ListValue* args);
Profile* profile_;
// weak_ptr_factory_ should always be last member.
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/pref_names.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/pref_names.cc
new file mode 100644
index 00000000000..c36221f6270
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/pref_names.cc
@@ -0,0 +1,20 @@
+// Copyright 2020 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 "chrome/browser/ui/webui/settings/chromeos/pref_names.h"
+
+namespace chromeos {
+namespace settings {
+namespace prefs {
+
+// Boolean specifying whether OS wallpaper sync is enabled. This is stored
+// separately from the other OS sync preferences because it's an edge case;
+// wallpaper does not have its own ModelType, so it cannot be part of
+// UserSelectableOsType like the other OS sync types.
+// TODO(https://crbug.com/967987): Break this dependency.
+const char kSyncOsWallpaper[] = "sync.os_wallpaper";
+
+} // namespace prefs
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/pref_names.h b/chromium/chrome/browser/ui/webui/settings/chromeos/pref_names.h
new file mode 100644
index 00000000000..df2e7dce599
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/pref_names.h
@@ -0,0 +1,18 @@
+// Copyright 2020 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 CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_PREF_NAMES_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_PREF_NAMES_H_
+
+namespace chromeos {
+namespace settings {
+namespace prefs {
+
+extern const char kSyncOsWallpaper[];
+
+} // namespace prefs
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_PREF_NAMES_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/quick_unlock_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/quick_unlock_handler.cc
new file mode 100644
index 00000000000..f74ec2b9c89
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/quick_unlock_handler.cc
@@ -0,0 +1,38 @@
+// Copyright 2020 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 "chrome/browser/ui/webui/settings/chromeos/quick_unlock_handler.h"
+
+#include "base/bind.h"
+#include "chrome/browser/chromeos/login/quick_unlock/pin_backend.h"
+#include "content/public/browser/web_ui.h"
+
+namespace chromeos {
+namespace settings {
+
+QuickUnlockHandler::QuickUnlockHandler() = default;
+
+QuickUnlockHandler::~QuickUnlockHandler() = default;
+
+void QuickUnlockHandler::RegisterMessages() {
+ web_ui()->RegisterMessageCallback(
+ "RequestPinLoginState",
+ base::BindRepeating(&QuickUnlockHandler::HandleRequestPinLoginState,
+ base::Unretained(this)));
+}
+
+void QuickUnlockHandler::HandleRequestPinLoginState(
+ const base::ListValue* args) {
+ AllowJavascript();
+ quick_unlock::PinBackend::GetInstance()->HasLoginSupport(
+ base::BindOnce(&QuickUnlockHandler::OnPinLoginAvailable,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void QuickUnlockHandler::OnPinLoginAvailable(bool is_available) {
+ FireWebUIListener("pin-login-available-changed", base::Value(is_available));
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/quick_unlock_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/quick_unlock_handler.h
new file mode 100644
index 00000000000..4796c99ce3c
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/quick_unlock_handler.h
@@ -0,0 +1,42 @@
+// Copyright 2020 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 CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_QUICK_UNLOCK_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_QUICK_UNLOCK_HANDLER_H_
+
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+
+namespace base {
+class ListValue;
+} // namespace base
+
+namespace chromeos {
+namespace settings {
+
+// Settings WebUI handler for quick unlock settings.
+class QuickUnlockHandler : public ::settings::SettingsPageUIHandler {
+ public:
+ QuickUnlockHandler();
+ QuickUnlockHandler(const QuickUnlockHandler&) = delete;
+ QuickUnlockHandler& operator=(const QuickUnlockHandler&) = delete;
+ ~QuickUnlockHandler() override;
+
+ // SettingsPageUIHandler:
+ void RegisterMessages() override;
+ void OnJavascriptAllowed() override {}
+ void OnJavascriptDisallowed() override {}
+
+ private:
+ void HandleRequestPinLoginState(const base::ListValue* args);
+
+ void OnPinLoginAvailable(bool is_available);
+
+ base::WeakPtrFactory<QuickUnlockHandler> weak_ptr_factory_{this};
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_QUICK_UNLOCK_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/BUILD.gn b/chromium/chrome/browser/ui/webui/settings/chromeos/search/BUILD.gn
new file mode 100644
index 00000000000..b4554acf90b
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/BUILD.gn
@@ -0,0 +1,17 @@
+# Copyright 2020 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.
+
+import("//mojo/public/tools/bindings/mojom.gni")
+
+assert(is_chromeos)
+
+mojom("mojo_bindings") {
+ sources = [
+ "search.mojom",
+ "search_result_icon.mojom",
+ "user_action_recorder.mojom",
+ ]
+
+ public_deps = [ "//mojo/public/mojom/base" ]
+}
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/OWNERS b/chromium/chrome/browser/ui/webui/settings/chromeos/search/OWNERS
new file mode 100644
index 00000000000..2d3d2668edc
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/OWNERS
@@ -0,0 +1,7 @@
+khorimoto@chromium.org
+zentaro@chromium.org
+
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
+
+# COMPONENT: OS>Systems>Settings
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search.mojom b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search.mojom
new file mode 100644
index 00000000000..d319e8d1079
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search.mojom
@@ -0,0 +1,33 @@
+// Copyright 2020 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.
+
+module chromeos.settings.mojom;
+
+import "chrome/browser/ui/webui/settings/chromeos/search/search_result_icon.mojom";
+import "mojo/public/mojom/base/string16.mojom";
+
+// Search result metadata.
+struct SearchResult {
+ // String to be displayed as a result in the UI. Meant to be displayed
+ // directly (i.e., not an ID but rather the actual text).
+ mojo_base.mojom.String16 result_text;
+
+ // The URL path containing the relevant setting, which may or may not contain
+ // URL parameters. For example, the Wi-Fi list settings page is
+ // chrome://os-settings/networks?type=WiFi, so the field would be
+ // "networks?type=WiFi" for this page.
+ string url_path_with_parameters;
+
+ // Icon to display for the search result.
+ SearchResultIcon icon;
+};
+
+// Provides settings search results. Implemented in the browser process;
+// intended to be called from settings JS and Launcher C++.
+interface SearchHandler {
+ // Searches settings for the given query and returns a list of results, sorted
+ // from most relevant to least relevant. An empty array indicates no relevant
+ // results.
+ Search(mojo_base.mojom.String16 query) => (array<SearchResult> results);
+};
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_concept.h b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_concept.h
new file mode 100644
index 00000000000..f6dc3b8c6f6
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_concept.h
@@ -0,0 +1,62 @@
+// Copyright 2020 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 CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_CONCEPT_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_CONCEPT_H_
+
+#include "chrome/browser/ui/webui/settings/chromeos/search/search_result_icon.mojom.h"
+
+namespace chromeos {
+namespace settings {
+
+// Represents a potential search result. In this context, "concept" refers to
+// the fact that this search result represents an idea which may be described
+// by more than just one phrase. For example, a concept of "Display settings"
+// may also be described as "Monitor settings".
+//
+// Each concept has a canonical description search tag as well as up to
+// |kMaxAltTagsPerConcept| alternate descriptions search tags.
+struct SearchConcept {
+ static constexpr size_t kMaxAltTagsPerConcept = 4;
+ static constexpr int kAltTagEnd = 0;
+
+ SearchConcept(const SearchConcept& other) = default;
+ SearchConcept& operator=(const SearchConcept& other) = default;
+
+ // Message ID (from os_settings_search_tag_strings.grdp) corresponding to the
+ // canonical search tag for this concept.
+ int canonical_message_id;
+
+ // URL path corresponding to the settings subpage at which the user can
+ // change a setting associated with the tag. This string can also contain
+ // URL parameters.
+ //
+ // Example 1 - Display settings (chrome://os-settings/device/display):
+ // ==> "device/display".
+ // Example 2 - Wi-Fi settings (chrome://os-settings/networks?type=WiFi):
+ // ==> "networks?type=WiFi"
+ const char* url_path_with_parameters;
+
+ // Icon to display for search results associated with this concept.
+ mojom::SearchResultIcon icon;
+
+ // Alternate message IDs (from os_settings_search_tag_strings.grdp)
+ // corresponding to this concept. These IDs refer to messages which represent
+ // an alternate way of describing the same concept (e.g., "Monitor settings"
+ // is an alternate phrase for "Display settings").
+ //
+ // This field provides up to |kMaxAltTagsPerConcept| alternate tags, but not
+ // all concepts will require this many. A value of kAltTagEnd is used to
+ // indicate that there are no further tags.
+ //
+ // Example 1 - Four alternate tags: [1234, 1235, 1236, 1237]
+ // Example 2 - Two alternate tags: [1234, 1235, kAltTagEnd, _]
+ // Example 3 - Zero alternate tags: [kAltTagEnd, _, _, _]
+ int alt_tag_ids[kMaxAltTagsPerConcept] = {kAltTagEnd};
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_CONCEPT_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc
new file mode 100644
index 00000000000..a94db926427
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc
@@ -0,0 +1,107 @@
+// Copyright 2020 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 "chrome/browser/ui/webui/settings/chromeos/search/search_handler.h"
+
+#include "base/strings/string_number_conversions.h"
+#include "chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/search_concept.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/search_result_icon.mojom.h"
+#include "chrome/services/local_search_service/local_search_service_impl.h"
+#include "chrome/services/local_search_service/public/mojom/types.mojom.h"
+#include "ui/base/l10n/l10n_util.h"
+
+namespace chromeos {
+namespace settings {
+namespace {
+
+const int32_t kLocalSearchServiceMaxResults = 10;
+
+} // namespace
+
+// static
+const size_t SearchHandler::kNumMaxResults = 5;
+
+SearchHandler::SearchHandler(
+ OsSettingsLocalizedStringsProvider* strings_provider,
+ local_search_service::LocalSearchServiceImpl* local_search_service)
+ : strings_provider_(strings_provider),
+ index_(local_search_service->GetIndexImpl(
+ local_search_service::IndexId::kCrosSettings)) {}
+
+SearchHandler::~SearchHandler() = default;
+
+void SearchHandler::BindInterface(
+ mojo::PendingReceiver<mojom::SearchHandler> pending_receiver) {
+ receivers_.Add(this, std::move(pending_receiver));
+}
+
+std::vector<mojom::SearchResultPtr> SearchHandler::Search(
+ const base::string16& query) {
+ std::vector<local_search_service::Result> local_search_service_results;
+ local_search_service::ResponseStatus response_status = index_->Find(
+ query, kLocalSearchServiceMaxResults, &local_search_service_results);
+
+ if (response_status != local_search_service::ResponseStatus::kSuccess) {
+ LOG(ERROR) << "Cannot search; LocalSearchService returned "
+ << static_cast<int>(response_status)
+ << ". Returning empty results array.";
+ return {};
+ }
+
+ return GenerateSearchResultsArray(local_search_service_results);
+}
+
+void SearchHandler::Search(const base::string16& query,
+ SearchCallback callback) {
+ std::move(callback).Run(Search(query));
+}
+
+std::vector<mojom::SearchResultPtr> SearchHandler::GenerateSearchResultsArray(
+ const std::vector<local_search_service::Result>&
+ local_search_service_results) {
+ std::vector<mojom::SearchResultPtr> search_results;
+ for (const auto& result : local_search_service_results) {
+ mojom::SearchResultPtr result_ptr = ResultToSearchResult(result);
+ if (result_ptr)
+ search_results.push_back(std::move(result_ptr));
+
+ // Limit the number of results to return.
+ if (search_results.size() == kNumMaxResults)
+ break;
+ }
+
+ return search_results;
+}
+
+mojom::SearchResultPtr SearchHandler::ResultToSearchResult(
+ const local_search_service::Result& result) {
+ int message_id;
+
+ // The result's ID is expected to be a stringified int.
+ if (!base::StringToInt(result.id, &message_id))
+ return nullptr;
+
+ const SearchConcept* concept =
+ strings_provider_->GetCanonicalTagMetadata(message_id);
+
+ // If the concept was not registered, no metadata is available. This can occur
+ // if the search tag was dynamically unregistered during the asynchronous
+ // Find() call.
+ if (!concept)
+ return nullptr;
+
+ return mojom::SearchResult::New(l10n_util::GetStringUTF16(message_id),
+ concept->url_path_with_parameters,
+ concept->icon);
+}
+
+void SearchHandler::Shutdown() {
+ strings_provider_ = nullptr;
+ index_ = nullptr;
+ receivers_.Clear();
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.h
new file mode 100644
index 00000000000..36df7ed4bb2
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.h
@@ -0,0 +1,77 @@
+// Copyright 2020 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 CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_HANDLER_H_
+
+#include <vector>
+
+#include "base/optional.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/search.mojom.h"
+#include "chrome/services/local_search_service/index_impl.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
+#include "mojo/public/cpp/bindings/remote.h"
+
+namespace local_search_service {
+class LocalSearchServiceImpl;
+} // namespace local_search_service
+
+namespace chromeos {
+namespace settings {
+
+class OsSettingsLocalizedStringsProvider;
+
+// Handles search queries for Chrome OS settings. Search() is expected to be
+// invoked by the settings UI as well as the the Launcher search UI. Search
+// results are obtained by matching the provided query against search tags
+// indexed in the LocalSearchService and cross-referencing results with
+// OsSettingsLocalizedStringsProvider.
+//
+// SearchHandler returns at most |kNumMaxResults| results; searches which do not
+// provide any matches result in an empty results array.
+class SearchHandler : public mojom::SearchHandler, public KeyedService {
+ public:
+ // Maximum number of results returned by a Search() call.
+ static const size_t kNumMaxResults;
+
+ SearchHandler(
+ OsSettingsLocalizedStringsProvider* strings_provider,
+ local_search_service::LocalSearchServiceImpl* local_search_service);
+ ~SearchHandler() override;
+
+ SearchHandler(const SearchHandler& other) = delete;
+ SearchHandler& operator=(const SearchHandler& other) = delete;
+
+ void BindInterface(
+ mojo::PendingReceiver<mojom::SearchHandler> pending_receiver);
+
+ // Synchronous search implementation (for in-process clients).
+ std::vector<mojom::SearchResultPtr> Search(const base::string16& query);
+
+ // mojom::SearchHandler:
+ void Search(const base::string16& query, SearchCallback callback) override;
+
+ private:
+ // KeyedService:
+ void Shutdown() override;
+
+ std::vector<mojom::SearchResultPtr> GenerateSearchResultsArray(
+ const std::vector<local_search_service::Result>&
+ local_search_service_results);
+ mojom::SearchResultPtr ResultToSearchResult(
+ const local_search_service::Result& result);
+
+ OsSettingsLocalizedStringsProvider* strings_provider_;
+ local_search_service::IndexImpl* index_;
+
+ // Note: Expected to have multiple clients, so a ReceiverSet is used.
+ mojo::ReceiverSet<mojom::SearchHandler> receivers_;
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_factory.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_factory.cc
new file mode 100644
index 00000000000..fba87783738
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_factory.cc
@@ -0,0 +1,61 @@
+// Copyright 2020 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 "chrome/browser/ui/webui/settings/chromeos/search/search_handler_factory.h"
+
+#include "chrome/browser/local_search_service/local_search_service_proxy.h"
+#include "chrome/browser/local_search_service/local_search_service_proxy_factory.h"
+#include "chrome/browser/profiles/incognito_helpers.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_factory.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/search_handler.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+
+namespace chromeos {
+namespace settings {
+
+// static
+SearchHandler* SearchHandlerFactory::GetForProfile(Profile* profile) {
+ return static_cast<SearchHandler*>(
+ SearchHandlerFactory::GetInstance()->GetServiceForBrowserContext(
+ profile, /*create=*/true));
+}
+
+// static
+SearchHandlerFactory* SearchHandlerFactory::GetInstance() {
+ return base::Singleton<SearchHandlerFactory>::get();
+}
+
+SearchHandlerFactory::SearchHandlerFactory()
+ : BrowserContextKeyedServiceFactory(
+ "SearchHandler",
+ BrowserContextDependencyManager::GetInstance()) {
+ DependsOn(
+ local_search_service::LocalSearchServiceProxyFactory::GetInstance());
+ DependsOn(OsSettingsLocalizedStringsProviderFactory::GetInstance());
+}
+
+SearchHandlerFactory::~SearchHandlerFactory() = default;
+
+KeyedService* SearchHandlerFactory::BuildServiceInstanceFor(
+ content::BrowserContext* context) const {
+ Profile* profile = Profile::FromBrowserContext(context);
+ return new SearchHandler(
+ OsSettingsLocalizedStringsProviderFactory::GetForProfile(profile),
+ local_search_service::LocalSearchServiceProxyFactory::GetForProfile(
+ Profile::FromBrowserContext(profile))
+ ->GetLocalSearchServiceImpl());
+}
+
+bool SearchHandlerFactory::ServiceIsNULLWhileTesting() const {
+ return true;
+}
+
+content::BrowserContext* SearchHandlerFactory::GetBrowserContextToUse(
+ content::BrowserContext* context) const {
+ return chrome::GetBrowserContextOwnInstanceInIncognito(context);
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_factory.h b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_factory.h
new file mode 100644
index 00000000000..9b69e5f161c
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_factory.h
@@ -0,0 +1,45 @@
+// Copyright 2020 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 CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_HANDLER_FACTORY_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_HANDLER_FACTORY_H_
+
+#include "base/memory/singleton.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+
+class Profile;
+
+namespace chromeos {
+namespace settings {
+
+class SearchHandler;
+
+// Factory for SearchHandler; available for incognito and multi-profile cases to
+// support settings search in those contexts.
+class SearchHandlerFactory : public BrowserContextKeyedServiceFactory {
+ public:
+ static SearchHandler* GetForProfile(Profile* profile);
+ static SearchHandlerFactory* GetInstance();
+
+ private:
+ friend struct base::DefaultSingletonTraits<SearchHandlerFactory>;
+
+ SearchHandlerFactory();
+ ~SearchHandlerFactory() override;
+
+ SearchHandlerFactory(const SearchHandlerFactory&) = delete;
+ SearchHandlerFactory& operator=(const SearchHandlerFactory&) = delete;
+
+ // BrowserContextKeyedServiceFactory:
+ KeyedService* BuildServiceInstanceFor(
+ content::BrowserContext* context) const override;
+ bool ServiceIsNULLWhileTesting() const override;
+ content::BrowserContext* GetBrowserContextToUse(
+ content::BrowserContext* context) const override;
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_HANDLER_FACTORY_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc
new file mode 100644
index 00000000000..cc04fb87193
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc
@@ -0,0 +1,78 @@
+// Copyright 2020 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 "chrome/browser/ui/webui/settings/chromeos/search/search_handler.h"
+
+#include "base/run_loop.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/search.mojom-test-utils.h"
+#include "chrome/common/webui_url_constants.h"
+#include "chrome/services/local_search_service/local_search_service_impl.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "chrome/test/base/testing_profile.h"
+#include "chrome/test/base/testing_profile_manager.h"
+#include "chromeos/services/network_config/public/cpp/cros_network_config_test_helper.h"
+#include "content/public/test/browser_task_environment.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+namespace settings {
+
+class SearchHandlerTest : public testing::Test {
+ protected:
+ SearchHandlerTest() : profile_manager_(TestingBrowserProcess::GetGlobal()) {}
+ ~SearchHandlerTest() override = default;
+
+ // testing::Test:
+ void SetUp() override {
+ ASSERT_TRUE(profile_manager_.SetUp());
+
+ provider_ = std::make_unique<OsSettingsLocalizedStringsProvider>(
+ profile_manager_.CreateTestingProfile("TestingProfile"),
+ &local_search_service_);
+
+ handler_ = std::make_unique<SearchHandler>(provider_.get(),
+ &local_search_service_);
+ handler_->BindInterface(handler_remote_.BindNewPipeAndPassReceiver());
+
+ // Allow asynchronous networking code to complete; specifically, let code
+ // which adds Wi-Fi to the system run so that Wi-Fi search tags can be
+ // queried below.
+ base::RunLoop().RunUntilIdle();
+ }
+
+ content::BrowserTaskEnvironment task_environment_;
+ TestingProfileManager profile_manager_;
+ chromeos::network_config::CrosNetworkConfigTestHelper network_config_helper_;
+ mojo::Remote<mojom::SearchHandler> handler_remote_;
+ local_search_service::LocalSearchServiceImpl local_search_service_;
+ std::unique_ptr<OsSettingsLocalizedStringsProvider> provider_;
+ std::unique_ptr<SearchHandler> handler_;
+};
+
+TEST_F(SearchHandlerTest, Success) {
+ // Search for "Wi-Fi".
+ std::vector<mojom::SearchResultPtr> search_results;
+ mojom::SearchHandlerAsyncWaiter(handler_remote_.get())
+ .Search(base::ASCIIToUTF16("Wi-Fi"), &search_results);
+
+ // Multiple results should be available, and they should have Wi-Fi metadata.
+ EXPECT_GT(search_results.size(), 0u);
+ for (const auto& result : search_results) {
+ EXPECT_EQ(chrome::kWiFiSettingsSubPage, result->url_path_with_parameters);
+ EXPECT_EQ(mojom::SearchResultIcon::kWifi, result->icon);
+ }
+}
+
+TEST_F(SearchHandlerTest, NoResults) {
+ std::vector<mojom::SearchResultPtr> search_results;
+ mojom::SearchHandlerAsyncWaiter(handler_remote_.get())
+ .Search(base::ASCIIToUTF16("QueryWithNoResults"), &search_results);
+ EXPECT_TRUE(search_results.empty());
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_result_icon.mojom b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_result_icon.mojom
new file mode 100644
index 00000000000..ea4605ed09f
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_result_icon.mojom
@@ -0,0 +1,14 @@
+// Copyright 2020 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.
+
+module chromeos.settings.mojom;
+
+// Icon types associated with a settings search result.
+enum SearchResultIcon {
+ kCellular,
+ kEthernet,
+ // Note: Wi-Fi icon is used by default for networking tasks which may not be
+ // specifically tied to Wi-Fi.
+ kWifi
+}; \ No newline at end of file
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker.cc
new file mode 100644
index 00000000000..49b774039a7
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker.cc
@@ -0,0 +1,131 @@
+// Copyright 2020 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 "chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker.h"
+
+#include "base/metrics/histogram_functions.h"
+
+namespace chromeos {
+namespace settings {
+
+namespace {
+
+// The maximum amount of time that the settings window can be blurred to be
+// considered short enough for the "first change" metric.
+constexpr base::TimeDelta kShortBlurTimeLimit = base::TimeDelta::FromMinutes(1);
+
+// The minimum amount of time between a setting change and a subsequent setting
+// change. If two changes occur les than this amount of time from each other,
+// they are ignored by metrics. See https://crbug.com/1073714 for details.
+constexpr base::TimeDelta kMinSubsequentChange =
+ base::TimeDelta::FromMilliseconds(200);
+
+// Min/max values for the duration metrics. Note that these values are tied to
+// the metrics defined below; if these ever change, the metric names must also
+// be updated.
+constexpr base::TimeDelta kMinDurationMetric =
+ base::TimeDelta::FromMilliseconds(100);
+constexpr base::TimeDelta kMaxDurationMetric = base::TimeDelta::FromMinutes(10);
+
+void LogDurationMetric(const char* metric_name, base::TimeDelta duration) {
+ base::UmaHistogramCustomTimes(metric_name, duration, kMinDurationMetric,
+ kMaxDurationMetric, /*buckets=*/50);
+}
+
+} // namespace
+
+SettingsUserActionTracker::SettingsUserActionTracker(
+ mojo::PendingReceiver<mojom::UserActionRecorder> pending_receiver)
+ : SettingsUserActionTracker() {
+ receiver_.Bind(std::move(pending_receiver));
+}
+
+SettingsUserActionTracker::SettingsUserActionTracker()
+ : metric_start_time_(base::TimeTicks::Now()) {}
+
+SettingsUserActionTracker::~SettingsUserActionTracker() = default;
+
+void SettingsUserActionTracker::RecordPageFocus() {
+ if (last_blur_timestamp_.is_null())
+ return;
+
+ // Log the duration of being blurred.
+ const base::TimeDelta blurred_duration =
+ base::TimeTicks::Now() - last_blur_timestamp_;
+ LogDurationMetric("ChromeOS.Settings.BlurredWindowDuration",
+ blurred_duration);
+
+ // If the window was blurred for more than |kShortBlurTimeLimit|,
+ // the user was away from the window for long enough that we consider the
+ // user coming back to the window a new session for the purpose of metrics.
+ if (blurred_duration >= kShortBlurTimeLimit) {
+ ResetMetricsCountersAndTimestamp();
+ last_record_setting_changed_timestamp_ = base::TimeTicks();
+ }
+}
+
+void SettingsUserActionTracker::RecordPageBlur() {
+ last_blur_timestamp_ = base::TimeTicks::Now();
+}
+
+void SettingsUserActionTracker::RecordClick() {
+ ++num_clicks_since_start_time_;
+}
+
+void SettingsUserActionTracker::RecordNavigation() {
+ ++num_navigations_since_start_time_;
+}
+
+void SettingsUserActionTracker::RecordSearch() {
+ ++num_searches_since_start_time_;
+}
+
+void SettingsUserActionTracker::RecordSettingChange() {
+ base::TimeTicks now = base::TimeTicks::Now();
+
+ if (!last_record_setting_changed_timestamp_.is_null()) {
+ // If it has been less than |kMinSubsequentChange| since the last recorded
+ // setting change, this change is discarded. See https://crbug.com/1073714
+ // for details.
+ if (now - last_record_setting_changed_timestamp_ < kMinSubsequentChange)
+ return;
+
+ base::UmaHistogramCounts1000(
+ "ChromeOS.Settings.NumClicksUntilChange.SubsequentChange",
+ num_clicks_since_start_time_);
+ base::UmaHistogramCounts1000(
+ "ChromeOS.Settings.NumNavigationsUntilChange.SubsequentChange",
+ num_navigations_since_start_time_);
+ base::UmaHistogramCounts1000(
+ "ChromeOS.Settings.NumSearchesUntilChange.SubsequentChange",
+ num_searches_since_start_time_);
+ LogDurationMetric("ChromeOS.Settings.TimeUntilChange.SubsequentChange",
+ now - metric_start_time_);
+ } else {
+ base::UmaHistogramCounts1000(
+ "ChromeOS.Settings.NumClicksUntilChange.FirstChange",
+ num_clicks_since_start_time_);
+ base::UmaHistogramCounts1000(
+ "ChromeOS.Settings.NumNavigationsUntilChange.FirstChange",
+ num_navigations_since_start_time_);
+ base::UmaHistogramCounts1000(
+ "ChromeOS.Settings.NumSearchesUntilChange.FirstChange",
+ num_searches_since_start_time_);
+ LogDurationMetric("ChromeOS.Settings.TimeUntilChange.FirstChange",
+ now - metric_start_time_);
+ }
+
+ ResetMetricsCountersAndTimestamp();
+ last_record_setting_changed_timestamp_ = now;
+}
+
+void SettingsUserActionTracker::ResetMetricsCountersAndTimestamp() {
+ metric_start_time_ = base::TimeTicks::Now();
+ num_clicks_since_start_time_ = 0u;
+ num_navigations_since_start_time_ = 0u;
+ num_searches_since_start_time_ = 0u;
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker.h b/chromium/chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker.h
new file mode 100644
index 00000000000..f355bcd524e
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker.h
@@ -0,0 +1,74 @@
+// Copyright 2020 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 CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SETTINGS_USER_ACTION_TRACKER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SETTINGS_USER_ACTION_TRACKER_H_
+
+#include "base/time/time.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/user_action_recorder.mojom.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+
+namespace chromeos {
+namespace settings {
+
+// Records user actions which measure the effort required to change a setting.
+// This class is only meant to track actions from an individual settings
+// session; if the settings window is closed and reopened again, a new instance
+// should be created for that new session.
+class SettingsUserActionTracker : public mojom::UserActionRecorder {
+ public:
+ explicit SettingsUserActionTracker(
+ mojo::PendingReceiver<mojom::UserActionRecorder> pending_receiver);
+ SettingsUserActionTracker(const SettingsUserActionTracker& other) = delete;
+ SettingsUserActionTracker& operator=(const SettingsUserActionTracker& other) =
+ delete;
+ ~SettingsUserActionTracker() override;
+
+ // mojom::UserActionRecorder:
+ void RecordPageFocus() override;
+ void RecordPageBlur() override;
+ void RecordClick() override;
+ void RecordNavigation() override;
+ void RecordSearch() override;
+ void RecordSettingChange() override;
+
+ private:
+ friend class SettingsUserActionTrackerTest;
+
+ // For unit tests.
+ SettingsUserActionTracker();
+
+ void ResetMetricsCountersAndTimestamp();
+
+ // Time at which the last setting change metric was recorded since the window
+ // has been focused, or null if no setting change has been recorded since the
+ // window has been focused. Note that if the user blurs the window then
+ // refocuses it in less than a minute, this value remains non-null; i.e., it
+ // flips back to null only when the user has blurred the window for over a
+ // minute.
+ base::TimeTicks last_record_setting_changed_timestamp_;
+
+ // Time at which recording the current metric has started. If
+ // |has_changed_setting_| is true, we're currently measuring the "subsequent
+ // setting change" metric; otherwise, we're measuring the "first setting
+ // change" metric.
+ base::TimeTicks metric_start_time_;
+
+ // Counters associated with the current metric.
+ size_t num_clicks_since_start_time_ = 0u;
+ size_t num_navigations_since_start_time_ = 0u;
+ size_t num_searches_since_start_time_ = 0u;
+
+ // The last time at which a page blur event was received; if no blur events
+ // have been received, this field is_null().
+ base::TimeTicks last_blur_timestamp_;
+
+ mojo::Receiver<mojom::UserActionRecorder> receiver_{this};
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SETTINGS_USER_ACTION_TRACKER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker_unittest.cc
new file mode 100644
index 00000000000..74a0c9cb0b2
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker_unittest.cc
@@ -0,0 +1,176 @@
+// Copyright 2020 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 "chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker.h"
+
+#include "base/test/metrics/histogram_tester.h"
+#include "base/test/task_environment.h"
+#include "base/time/time.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+namespace settings {
+
+class SettingsUserActionTrackerTest : public testing::Test {
+ protected:
+ SettingsUserActionTrackerTest() = default;
+ ~SettingsUserActionTrackerTest() override = default;
+
+ base::test::TaskEnvironment task_environment_{
+ base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+ base::HistogramTester histogram_tester_;
+ SettingsUserActionTracker tracker_;
+};
+
+TEST_F(SettingsUserActionTrackerTest, TestRecordMetrics) {
+ // Focus the page, perform some tasks, and change a setting.
+ tracker_.RecordPageFocus();
+ tracker_.RecordClick();
+ tracker_.RecordNavigation();
+ tracker_.RecordSearch();
+ task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(10));
+ tracker_.RecordSettingChange();
+
+ // The "first change" metrics should have been logged.
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumClicksUntilChange.FirstChange",
+ /*count=*/1);
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumNavigationsUntilChange.FirstChange",
+ /*count=*/1);
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumSearchesUntilChange.FirstChange",
+ /*count=*/1);
+ histogram_tester_.ExpectTimeBucketCount(
+ "ChromeOS.Settings.TimeUntilChange.FirstChange",
+ /*sample=*/base::TimeDelta::FromSeconds(10),
+ /*count=*/1);
+
+ // Without leaving the page, perform some more tasks, and change another
+ // setting.
+ tracker_.RecordClick();
+ tracker_.RecordNavigation();
+ tracker_.RecordSearch();
+ task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(10));
+ tracker_.RecordSettingChange();
+
+ // The "subsequent change" metrics should have been logged.
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumClicksUntilChange.SubsequentChange",
+ /*count=*/1);
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumNavigationsUntilChange.SubsequentChange",
+ /*count=*/1);
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumSearchesUntilChange.SubsequentChange",
+ /*count=*/1);
+ histogram_tester_.ExpectTimeBucketCount(
+ "ChromeOS.Settings.TimeUntilChange.SubsequentChange",
+ /*sample=*/base::TimeDelta::FromSeconds(10),
+ /*count=*/1);
+
+ // Repeat this, but only after 100ms. This is lower than the minimum value
+ // required for this metric, so it should be ignored.
+ tracker_.RecordClick();
+ tracker_.RecordNavigation();
+ tracker_.RecordSearch();
+ task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(100));
+ tracker_.RecordSettingChange();
+
+ // No additional logging should have occurred, so make the same verifications
+ // as above.
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumClicksUntilChange.SubsequentChange",
+ /*count=*/1);
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumNavigationsUntilChange.SubsequentChange",
+ /*count=*/1);
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumSearchesUntilChange.SubsequentChange",
+ /*count=*/1);
+ histogram_tester_.ExpectTimeBucketCount(
+ "ChromeOS.Settings.TimeUntilChange.SubsequentChange",
+ /*sample=*/base::TimeDelta::FromSeconds(10),
+ /*count=*/1);
+
+ // Repeat this once more, and verify that the counts increased.
+ tracker_.RecordClick();
+ tracker_.RecordNavigation();
+ tracker_.RecordSearch();
+ task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(10));
+ tracker_.RecordSettingChange();
+
+ // The "subsequent change" metrics should have been logged.
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumClicksUntilChange.SubsequentChange",
+ /*count=*/2);
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumNavigationsUntilChange.SubsequentChange",
+ /*count=*/2);
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumSearchesUntilChange.SubsequentChange",
+ /*count=*/2);
+ histogram_tester_.ExpectTimeBucketCount(
+ "ChromeOS.Settings.TimeUntilChange.SubsequentChange",
+ /*sample=*/base::TimeDelta::FromSeconds(10),
+ /*count=*/2);
+}
+
+TEST_F(SettingsUserActionTrackerTest, TestBlurAndFocus) {
+ // Focus the page, click, and change a setting.
+ tracker_.RecordPageFocus();
+ tracker_.RecordClick();
+ task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1));
+ tracker_.RecordSettingChange();
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumClicksUntilChange.FirstChange",
+ /*count=*/1);
+ histogram_tester_.ExpectTimeBucketCount(
+ "ChromeOS.Settings.TimeUntilChange.FirstChange",
+ /*sample=*/base::TimeDelta::FromSeconds(1),
+ /*count=*/1);
+
+ // Blur for 59 seconds (not quite a minute), click, and change a setting.
+ // Since the blur was under a minute, this should count for the "subsequent
+ // change" metrics.
+ tracker_.RecordPageBlur();
+ task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(59));
+ tracker_.RecordPageFocus();
+ tracker_.RecordClick();
+ tracker_.RecordSettingChange();
+ histogram_tester_.ExpectTimeBucketCount(
+ "ChromeOS.Settings.BlurredWindowDuration",
+ /*sample=*/base::TimeDelta::FromSeconds(59),
+ /*count=*/1);
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumClicksUntilChange.SubsequentChange",
+ /*count=*/1);
+ histogram_tester_.ExpectTimeBucketCount(
+ "ChromeOS.Settings.TimeUntilChange.SubsequentChange",
+ /*sample=*/base::TimeDelta::FromSeconds(59),
+ /*count=*/1);
+
+ // Now, blur for a full minute, click, and change a setting. Since the blur
+ // was a full minute, this should count for the "first change" metrics.
+ tracker_.RecordPageBlur();
+ task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
+ tracker_.RecordPageFocus();
+ task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(5));
+ tracker_.RecordClick();
+ tracker_.RecordSettingChange();
+ histogram_tester_.ExpectTimeBucketCount(
+ "ChromeOS.Settings.BlurredWindowDuration",
+ /*sample=*/base::TimeDelta::FromMinutes(1),
+ /*count=*/2);
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumClicksUntilChange.FirstChange",
+ /*count=*/2);
+ histogram_tester_.ExpectTimeBucketCount(
+ "ChromeOS.Settings.TimeUntilChange.FirstChange",
+ /*sample=*/base::TimeDelta::FromSeconds(5),
+ /*count=*/1);
+}
+
+} // namespace settings.
+} // namespace chromeos.
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/user_action_recorder.mojom b/chromium/chrome/browser/ui/webui/settings/chromeos/search/user_action_recorder.mojom
new file mode 100644
index 00000000000..1f151fc028d
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/user_action_recorder.mojom
@@ -0,0 +1,28 @@
+// Copyright 2020 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.
+
+module chromeos.settings.mojom;
+
+// Records user actions within OS settings. Implemented in the browser process;
+// intended to be called from settings JS.
+interface UserActionRecorder {
+ // Records that the settings window has been focused.
+ RecordPageFocus();
+
+ // Records that the settings window has been blurred (i.e., no longer
+ // focused).
+ RecordPageBlur();
+
+ // Records that the user has clicked within the settings page.
+ RecordClick();
+
+ // Records that the user has navigated to a settings subpage.
+ RecordNavigation();
+
+ // Records that the user has completed a search attempt.
+ RecordSearch();
+
+ // Records that the user has changed a setting.
+ RecordSettingChange();
+};
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/server_printer_url_util.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/server_printer_url_util.cc
new file mode 100644
index 00000000000..005d006a42c
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/server_printer_url_util.cc
@@ -0,0 +1,73 @@
+// Copyright 2020 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 "chrome/browser/ui/webui/settings/chromeos/server_printer_url_util.h"
+
+#include "url/gurl.h"
+
+namespace {
+
+// Returns an updated |gurl| with the specified components from the params. If
+// |scheme| is not empty, returns an updated GURL with the specified scheme. If
+// |replace_port| is true, returns an updated GURL with 631 as the port. 631 is
+// the default port for IPP.
+GURL UpdateServerPrinterGURL(const GURL& gurl,
+ const std::string& scheme,
+ bool replace_ipp_port) {
+ GURL::Replacements replacement;
+ if (!scheme.empty())
+ replacement.SetSchemeStr(scheme);
+ if (replace_ipp_port)
+ replacement.SetPortStr("631");
+ return gurl.ReplaceComponents(replacement);
+}
+
+} // namespace
+
+namespace chromeos {
+namespace settings {
+
+bool HasValidServerPrinterScheme(const GURL& gurl) {
+ return gurl.SchemeIsHTTPOrHTTPS() || gurl.SchemeIs("ipp") ||
+ gurl.SchemeIs("ipps");
+}
+
+base::Optional<GURL> GenerateServerPrinterUrlWithValidScheme(
+ const std::string& url) {
+ base::Optional<GURL> gurl = base::make_optional(GURL(url));
+ if (!HasValidServerPrinterScheme(*gurl)) {
+ // If we're missing a valid scheme, try querying with IPPS first.
+ gurl = GURL("ipps://" + url);
+ }
+
+ if (!gurl->is_valid())
+ return base::nullopt;
+
+ // Replaces IPP/IPPS by HTTP/HTTPS. IPP standard describes protocol built
+ // on top of HTTP, so both types of addresses have the same meaning in the
+ // context of IPP interface. Moreover, the URL must have HTTP/HTTPS scheme
+ // to pass IsStandard() test from GURL library (see "Validation of the URL
+ // address" below).
+ if (gurl->SchemeIs("ipp")) {
+ gurl = UpdateServerPrinterGURL(*gurl, "http",
+ /*replace_ipp_port=*/false);
+ // The default port for IPP is 631. If the schema IPP is replaced by HTTP
+ // and the port is not explicitly defined in the URL, we have to overwrite
+ // the default HTTP port with the default IPP port. For IPPS we do nothing
+ // because implementers use the same port for IPPS and HTTPS.
+ if (gurl->IntPort() == url::PORT_UNSPECIFIED) {
+ gurl = UpdateServerPrinterGURL(*gurl, /*scheme=*/"",
+ /*replace_ipp_port=*/true);
+ }
+ } else if (gurl->SchemeIs("ipps")) {
+ gurl = UpdateServerPrinterGURL(*gurl, "https",
+ /*replace_ipp_port=*/false);
+ }
+
+ // Check validation of the URL address and return |gurl| if valid.
+ return gurl->IsStandard() ? gurl : base::nullopt;
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/server_printer_url_util.h b/chromium/chrome/browser/ui/webui/settings/chromeos/server_printer_url_util.h
new file mode 100644
index 00000000000..ad118c14f4b
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/server_printer_url_util.h
@@ -0,0 +1,30 @@
+// Copyright 2020 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 CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SERVER_PRINTER_URL_UTIL_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SERVER_PRINTER_URL_UTIL_H_
+
+#include <string>
+
+#include "base/optional.h"
+
+class GURL;
+
+namespace chromeos {
+namespace settings {
+
+// Returns true if |gurl| has any the following scheme: HTTP, HTTPS, IPP, or
+// IPPS. Returns false for an empty or any other scheme.
+bool HasValidServerPrinterScheme(const GURL& gurl);
+
+// Returns a GURL from the input |url|. Returns base::nullopt if
+// either |url| is invalid or constructing the GURL failed. This will also
+// default the server printer URI to use HTTPS if it detects a missing scheme.
+base::Optional<GURL> GenerateServerPrinterUrlWithValidScheme(
+ const std::string& url);
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SERVER_PRINTER_URL_UTIL_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/server_printer_url_util_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/server_printer_url_util_unittest.cc
new file mode 100644
index 00000000000..26e2ec17433
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/server_printer_url_util_unittest.cc
@@ -0,0 +1,89 @@
+// Copyright 2020 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 "chrome/browser/ui/webui/settings/chromeos/server_printer_url_util.h"
+
+#include <string>
+
+#include "base/optional.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace chromeos {
+namespace settings {
+
+class ServerPrinterUrlUtilTest : public testing::Test {
+ public:
+ ServerPrinterUrlUtilTest() = default;
+ ~ServerPrinterUrlUtilTest() override = default;
+};
+
+TEST_F(ServerPrinterUrlUtilTest, IsValidScheme) {
+ GURL gurl1("ipp://123.123.11.11:123");
+ ASSERT_TRUE(HasValidServerPrinterScheme(gurl1));
+
+ GURL gurl2("http://123.123.11.11:123");
+ ASSERT_TRUE(HasValidServerPrinterScheme(gurl2));
+
+ GURL gurl3("ipps://123.123.11.11:123");
+ ASSERT_TRUE(HasValidServerPrinterScheme(gurl3));
+
+ GURL gurl4("https://123.123.11.11:123");
+ ASSERT_TRUE(HasValidServerPrinterScheme(gurl4));
+
+ // Missing scheme.
+ GURL gurl5("123.123.11.11:123");
+ ASSERT_FALSE(HasValidServerPrinterScheme(gurl5));
+
+ // Invalid scheme.
+ GURL gurl6("test://123.123.11.11:123");
+ ASSERT_FALSE(HasValidServerPrinterScheme(gurl6));
+}
+
+TEST_F(ServerPrinterUrlUtilTest, ConvertToGURL) {
+ // Test that a GURL is created with |gurl1| as its source.
+ std::string url1("http://123.123.11.11:631");
+ base::Optional<GURL> gurl1 = GenerateServerPrinterUrlWithValidScheme(url1);
+ DCHECK(gurl1);
+ ASSERT_EQ("http://123.123.11.11:631/", gurl1->spec());
+ ASSERT_EQ("http", gurl1->scheme());
+ ASSERT_EQ("631", gurl1->port());
+
+ // Test that HTTPS is the default scheme if a scheme is not provided.
+ std::string url2("123.123.11.11:631");
+ base::Optional<GURL> gurl2 = GenerateServerPrinterUrlWithValidScheme(url2);
+ DCHECK(gurl2);
+ ASSERT_EQ("https", gurl2->scheme());
+ ASSERT_EQ("https://123.123.11.11:631/", gurl2->spec());
+
+ // Test that if a URL has IPP as its scheme, it will create a new GURL with
+ // HTTP as its scheme and 631 as its port.
+ std::string url3("ipp://123.123.11.11");
+ base::Optional<GURL> gurl3 = GenerateServerPrinterUrlWithValidScheme(url3);
+ DCHECK(gurl3);
+ ASSERT_EQ("http", gurl3->scheme());
+ ASSERT_EQ("631", gurl3->port());
+ ASSERT_EQ("http://123.123.11.11:631/", gurl3->spec());
+
+ // Test that if a URL has IPP as its scheme and a specified port, it will
+ // create a new GURL with HTTP as the scheme and keeps the same port.
+ std::string url4("ipp://123.123.11.11:321");
+ base::Optional<GURL> gurl4 = GenerateServerPrinterUrlWithValidScheme(url4);
+ DCHECK(gurl4);
+ ASSERT_EQ("http", gurl4->scheme());
+ ASSERT_EQ("321", gurl4->port());
+ ASSERT_EQ("http://123.123.11.11:321/", gurl4->spec());
+
+ // Test that if a URL has IPPS as its scheme and a specified port, a new GURL
+ // is created with the scheme as HTTPS and keeps the same port.
+ std::string url5("ipps://123.123.11.11:555");
+ base::Optional<GURL> gurl5 = GenerateServerPrinterUrlWithValidScheme(url5);
+ DCHECK(gurl5);
+ ASSERT_EQ("https", gurl5->scheme());
+ ASSERT_EQ("555", gurl5->port());
+ ASSERT_EQ("https://123.123.11.11:555/", gurl5->spec());
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/font_handler.cc b/chromium/chrome/browser/ui/webui/settings/font_handler.cc
index 062eb45fb0f..8fac7613e07 100644
--- a/chromium/chrome/browser/ui/webui/settings/font_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/font_handler.cc
@@ -13,28 +13,17 @@
#include "base/bind_helpers.h"
#include "base/i18n/rtl.h"
#include "chrome/browser/browser_process.h"
-#include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/font_list_async.h"
#include "content/public/browser/web_ui.h"
-#include "extensions/browser/extension_system.h"
-#include "extensions/common/extension_urls.h"
#if defined(OS_MACOSX)
#include "chrome/browser/ui/webui/settings_utils.h"
#endif
-namespace {
-
-const char kAdvancedFontSettingsExtensionId[] =
- "caclkomlalccbpcdllchkeecicepbmbm";
-
-} // namespace
-
namespace settings {
FontHandler::FontHandler(content::WebUI* webui)
@@ -51,78 +40,23 @@ void FontHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(
"fetchFontsData", base::BindRepeating(&FontHandler::HandleFetchFontsData,
base::Unretained(this)));
- web_ui()->RegisterMessageCallback(
- "observeAdvancedFontExtensionAvailable",
- base::BindRepeating(
- &FontHandler::HandleObserveAdvancedFontExtensionAvailable,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback(
- "openAdvancedFontSettings",
- base::BindRepeating(&FontHandler::HandleOpenAdvancedFontSettings,
- base::Unretained(this)));
}
-void FontHandler::OnJavascriptAllowed() {
- extension_registry_observer_.Add(
- extensions::ExtensionRegistry::Get(profile_));
-}
+void FontHandler::OnJavascriptAllowed() {}
-void FontHandler::OnJavascriptDisallowed() {
- extension_registry_observer_.RemoveAll();
-}
+void FontHandler::OnJavascriptDisallowed() {}
void FontHandler::HandleFetchFontsData(const base::ListValue* args) {
CHECK_EQ(1U, args->GetSize());
std::string callback_id;
CHECK(args->GetString(0, &callback_id));
+ AllowJavascript();
content::GetFontListAsync(base::Bind(&FontHandler::FontListHasLoaded,
weak_ptr_factory_.GetWeakPtr(),
callback_id));
}
-void FontHandler::HandleObserveAdvancedFontExtensionAvailable(
- const base::ListValue* /*args*/) {
- AllowJavascript();
- NotifyAdvancedFontSettingsAvailability();
-}
-
-void FontHandler::HandleOpenAdvancedFontSettings(
- const base::ListValue* /*args*/) {
- const extensions::Extension* extension = GetAdvancedFontSettingsExtension();
- if (!extension)
- return;
- extensions::ExtensionTabUtil::OpenOptionsPage(
- extension,
- chrome::FindBrowserWithWebContents(web_ui()->GetWebContents()));
-}
-
-const extensions::Extension* FontHandler::GetAdvancedFontSettingsExtension() {
- extensions::ExtensionService* service =
- extensions::ExtensionSystem::Get(profile_)->extension_service();
- if (!service->IsExtensionEnabled(kAdvancedFontSettingsExtensionId))
- return nullptr;
- extensions::ExtensionRegistry* registry =
- extensions::ExtensionRegistry::Get(profile_);
- return registry->GetInstalledExtension(kAdvancedFontSettingsExtensionId);
-}
-
-void FontHandler::NotifyAdvancedFontSettingsAvailability() {
- FireWebUIListener("advanced-font-settings-installed",
- base::Value(GetAdvancedFontSettingsExtension() != nullptr));
-}
-
-void FontHandler::OnExtensionLoaded(content::BrowserContext*,
- const extensions::Extension*) {
- NotifyAdvancedFontSettingsAvailability();
-}
-
-void FontHandler::OnExtensionUnloaded(content::BrowserContext*,
- const extensions::Extension*,
- extensions::UnloadedExtensionReason) {
- NotifyAdvancedFontSettingsAvailability();
-}
-
void FontHandler::FontListHasLoaded(std::string callback_id,
std::unique_ptr<base::ListValue> list) {
// Font list. Selects the directionality for the fonts in the given list.
@@ -142,11 +76,6 @@ void FontHandler::FontListHasLoaded(std::string callback_id,
base::DictionaryValue response;
response.Set("fontList", std::move(list));
- GURL extension_url(extension_urls::GetWebstoreItemDetailURLPrefix());
- response.SetString(
- "extensionUrl",
- extension_url.Resolve(kAdvancedFontSettingsExtensionId).spec());
-
ResolveJavascriptCallback(base::Value(callback_id), response);
}
diff --git a/chromium/chrome/browser/ui/webui/settings/font_handler.h b/chromium/chrome/browser/ui/webui/settings/font_handler.h
index 3c0a284ca9e..6864cb5381c 100644
--- a/chromium/chrome/browser/ui/webui/settings/font_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/font_handler.h
@@ -12,8 +12,6 @@
#include "base/memory/weak_ptr.h"
#include "base/scoped_observer.h"
#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
-#include "extensions/browser/extension_registry.h"
-#include "extensions/browser/extension_registry_observer.h"
namespace base {
class ListValue;
@@ -23,17 +21,12 @@ namespace content {
class WebUI;
}
-namespace extensions {
-class Extension;
-}
-
class Profile;
namespace settings {
// Handle OS font list and font preference settings.
-class FontHandler : public SettingsPageUIHandler,
- public extensions::ExtensionRegistryObserver {
+class FontHandler : public SettingsPageUIHandler {
public:
explicit FontHandler(content::WebUI* webui);
~FontHandler() override;
@@ -43,36 +36,14 @@ class FontHandler : public SettingsPageUIHandler,
void OnJavascriptAllowed() override;
void OnJavascriptDisallowed() override;
- // ExtensionRegistryObserver implementation.
- void OnExtensionLoaded(content::BrowserContext* browser_context,
- const extensions::Extension* extension) override;
- void OnExtensionUnloaded(content::BrowserContext* browser_context,
- const extensions::Extension* extension,
- extensions::UnloadedExtensionReason reason) override;
-
private:
// Handler for script asking for font information.
void HandleFetchFontsData(const base::ListValue* args);
- // Listen for changes to whether the advanced font extension is available.
- // An initial update will be sent when observation begins.
- void HandleObserveAdvancedFontExtensionAvailable(const base::ListValue* args);
-
- // Open the advanced font settings page.
- void HandleOpenAdvancedFontSettings(const base::ListValue* args);
-
// Callback to handle fonts loading.
void FontListHasLoaded(std::string callback_id,
std::unique_ptr<base::ListValue> list);
- const extensions::Extension* GetAdvancedFontSettingsExtension();
-
- void NotifyAdvancedFontSettingsAvailability();
-
- ScopedObserver<extensions::ExtensionRegistry,
- extensions::ExtensionRegistryObserver>
- extension_registry_observer_{this};
-
Profile* profile_; // Weak pointer.
base::WeakPtrFactory<FontHandler> weak_ptr_factory_{this};
diff --git a/chromium/chrome/browser/ui/webui/settings/hats_handler.cc b/chromium/chrome/browser/ui/webui/settings/hats_handler.cc
new file mode 100644
index 00000000000..74723f1b870
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/hats_handler.cc
@@ -0,0 +1,37 @@
+// Copyright 2020 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 "chrome/browser/ui/webui/settings/hats_handler.h"
+
+#include "base/bind.h"
+#include "base/threading/sequenced_task_runner_handle.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/hats/hats_service.h"
+#include "chrome/browser/ui/hats/hats_service_factory.h"
+#include "content/public/browser/visibility.h"
+#include "content/public/browser/web_contents.h"
+
+namespace settings {
+
+HatsHandler::HatsHandler() = default;
+
+HatsHandler::~HatsHandler() = default;
+
+void HatsHandler::RegisterMessages() {
+ web_ui()->RegisterMessageCallback(
+ "tryShowHatsSurvey",
+ base::BindRepeating(&HatsHandler::HandleTryShowHatsSurvey,
+ base::Unretained(this)));
+}
+
+void HatsHandler::HandleTryShowHatsSurvey(const base::ListValue* args) {
+ HatsService* hats_service = HatsServiceFactory::GetForProfile(
+ Profile::FromWebUI(web_ui()), /* create_if_necessary = */ true);
+ if (hats_service) {
+ hats_service->LaunchDelayedSurveyForWebContents(
+ kHatsSurveyTriggerSettingsPrivacy, web_ui()->GetWebContents(), 20000);
+ }
+}
+
+} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/hats_handler.h b/chromium/chrome/browser/ui/webui/settings/hats_handler.h
new file mode 100644
index 00000000000..f2e22b4a0c5
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/hats_handler.h
@@ -0,0 +1,39 @@
+// Copyright 2020 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 CHROME_BROWSER_UI_WEBUI_SETTINGS_HATS_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_HATS_HANDLER_H_
+
+#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+
+namespace settings {
+
+// Settings page UI handler that shows HaTS surveys.
+class HatsHandler : public SettingsPageUIHandler {
+ public:
+ HatsHandler();
+
+ // Not copyable or movable
+ HatsHandler(const HatsHandler&) = delete;
+ HatsHandler& operator=(const HatsHandler&) = delete;
+
+ ~HatsHandler() override;
+
+ // WebUIMessageHandler implementation.
+ void RegisterMessages() override;
+
+ void HandleTryShowHatsSurvey(const base::ListValue* args);
+
+ private:
+ friend class HatsHandlerTest;
+ FRIEND_TEST_ALL_PREFIXES(HatsHandlerTest, HandleTryShowHatsSurvey);
+
+ // SettingsPageUIHandler implementation.
+ void OnJavascriptAllowed() override {}
+ void OnJavascriptDisallowed() override {}
+};
+
+} // namespace settings
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_HATS_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/hats_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/hats_handler_unittest.cc
new file mode 100644
index 00000000000..dc459945792
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/hats_handler_unittest.cc
@@ -0,0 +1,65 @@
+// Copyright 2020 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 "chrome/browser/ui/webui/settings/hats_handler.h"
+
+#include <memory>
+#include <string>
+
+#include "base/values.h"
+#include "chrome/browser/ui/hats/hats_service.h"
+#include "chrome/browser/ui/hats/hats_service_factory.h"
+#include "chrome/browser/ui/hats/mock_hats_service.h"
+#include "chrome/test/base/chrome_render_view_host_test_harness.h"
+#include "content/public/test/test_web_ui.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+class Profile;
+
+namespace settings {
+
+class HatsHandlerTest : public ChromeRenderViewHostTestHarness {
+ public:
+ void SetUp() override {
+ ChromeRenderViewHostTestHarness::SetUp();
+
+ web_ui_ = std::make_unique<content::TestWebUI>();
+ web_ui_->set_web_contents(web_contents());
+ handler_ = std::make_unique<HatsHandler>();
+ handler_->set_web_ui(web_ui());
+ handler_->AllowJavascript();
+ web_ui_->ClearTrackedCalls();
+
+ mock_hats_service_ = static_cast<MockHatsService*>(
+ HatsServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+ profile(), base::BindRepeating(&BuildMockHatsService)));
+ }
+
+ void TearDown() override {
+ handler_->set_web_ui(nullptr);
+ handler_.reset();
+ web_ui_.reset();
+
+ ChromeRenderViewHostTestHarness::TearDown();
+ }
+
+ content::TestWebUI* web_ui() { return web_ui_.get(); }
+ HatsHandler* handler() { return handler_.get(); }
+ MockHatsService* mock_hats_service_;
+
+ private:
+ std::unique_ptr<content::TestWebUI> web_ui_;
+ std::unique_ptr<HatsHandler> handler_;
+};
+
+TEST_F(HatsHandlerTest, HandleTryShowHatsSurvey) {
+ EXPECT_CALL(*mock_hats_service_,
+ LaunchDelayedSurveyForWebContents(
+ kHatsSurveyTriggerSettingsPrivacy, web_contents(), 20000));
+ base::ListValue args;
+ handler()->HandleTryShowHatsSurvey(&args);
+ task_environment()->RunUntilIdle();
+}
+
+} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/settings_import_data_handler.cc b/chromium/chrome/browser/ui/webui/settings/import_data_handler.cc
index b2e78bd722b..1637dc014a7 100644
--- a/chromium/chrome/browser/ui/webui/settings/settings_import_data_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/import_data_handler.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/ui/webui/settings/settings_import_data_handler.h"
+#include "chrome/browser/ui/webui/settings/import_data_handler.h"
#include <stddef.h>
@@ -38,10 +38,10 @@ namespace {
const char kImportStatusInProgress[] = "inProgress";
const char kImportStatusSucceeded[] = "succeeded";
const char kImportStatusFailed[] = "failed";
-}
+} // namespace
ImportDataHandler::ImportDataHandler()
- : importer_host_(NULL), import_did_succeed_(false) {
+ : importer_host_(nullptr), import_did_succeed_(false) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
}
@@ -49,7 +49,7 @@ ImportDataHandler::~ImportDataHandler() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (importer_host_)
- importer_host_->set_observer(NULL);
+ importer_host_->set_observer(nullptr);
if (select_file_dialog_.get())
select_file_dialog_->ListenerDestroyed();
@@ -60,14 +60,14 @@ void ImportDataHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(
"initializeImportDialog",
- base::BindRepeating(&ImportDataHandler::InitializeDialog,
+ base::BindRepeating(&ImportDataHandler::HandleInitializeImportDialog,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
- "importData", base::BindRepeating(&ImportDataHandler::ImportData,
+ "importData", base::BindRepeating(&ImportDataHandler::HandleImportData,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"importFromBookmarksFile",
- base::BindRepeating(&ImportDataHandler::HandleChooseBookmarksFile,
+ base::BindRepeating(&ImportDataHandler::HandleImportFromBookmarksFile,
base::Unretained(this)));
}
@@ -77,7 +77,7 @@ void ImportDataHandler::OnJavascriptDisallowed() {
// Stops listening to updates from any ongoing imports.
if (importer_host_)
- importer_host_->set_observer(NULL);
+ importer_host_->set_observer(nullptr);
}
void ImportDataHandler::StartImport(
@@ -90,7 +90,7 @@ void ImportDataHandler::StartImport(
// If another import is already ongoing, let it finish silently.
if (importer_host_)
- importer_host_->set_observer(NULL);
+ importer_host_->set_observer(nullptr);
FireWebUIListener("import-data-status-changed",
base::Value(kImportStatusInProgress));
@@ -99,32 +99,32 @@ void ImportDataHandler::StartImport(
importer_host_ = new ExternalProcessImporterHost();
importer_host_->set_observer(this);
Profile* profile = Profile::FromWebUI(web_ui());
- importer_host_->StartImportSettings(source_profile, profile,
- imported_items,
+ importer_host_->StartImportSettings(source_profile, profile, imported_items,
new ProfileWriter(profile));
importer::LogImporterUseToMetrics("ImportDataHandler",
source_profile.importer_type);
}
-void ImportDataHandler::ImportData(const base::ListValue* args) {
+void ImportDataHandler::HandleImportData(const base::ListValue* args) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
int browser_index;
CHECK(args->GetInteger(0, &browser_index));
- PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs();
+ const base::DictionaryValue* types = nullptr;
+ CHECK(args->GetDictionary(1, &types));
uint16_t selected_items = importer::NONE;
- if (prefs->GetBoolean(prefs::kImportDialogAutofillFormData))
+ if (*types->FindBoolKey(prefs::kImportDialogAutofillFormData))
selected_items |= importer::AUTOFILL_FORM_DATA;
- if (prefs->GetBoolean(prefs::kImportDialogBookmarks))
+ if (*types->FindBoolKey(prefs::kImportDialogBookmarks))
selected_items |= importer::FAVORITES;
- if (prefs->GetBoolean(prefs::kImportDialogHistory))
+ if (*types->FindBoolKey(prefs::kImportDialogHistory))
selected_items |= importer::HISTORY;
- if (prefs->GetBoolean(prefs::kImportDialogSavedPasswords))
+ if (*types->FindBoolKey(prefs::kImportDialogSavedPasswords))
selected_items |= importer::PASSWORDS;
- if (prefs->GetBoolean(prefs::kImportDialogSearchEngine))
+ if (*types->FindBoolKey(prefs::kImportDialogSearchEngine))
selected_items |= importer::SEARCH_ENGINES;
const importer::SourceProfile& source_profile =
@@ -136,11 +136,12 @@ void ImportDataHandler::ImportData(const base::ListValue* args) {
StartImport(source_profile, imported_items);
} else {
LOG(WARNING) << "There were no settings to import from '"
- << source_profile.importer_name << "'.";
+ << source_profile.importer_name << "'.";
}
}
-void ImportDataHandler::InitializeDialog(const base::ListValue* args) {
+void ImportDataHandler::HandleInitializeImportDialog(
+ const base::ListValue* args) {
AllowJavascript();
CHECK_EQ(1U, args->GetSize());
@@ -155,6 +156,28 @@ void ImportDataHandler::InitializeDialog(const base::ListValue* args) {
base::Unretained(this), callback_id));
}
+void ImportDataHandler::HandleImportFromBookmarksFile(
+ const base::ListValue* args) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ DCHECK(args && args->empty());
+ select_file_dialog_ = ui::SelectFileDialog::Create(
+ this,
+ std::make_unique<ChromeSelectFilePolicy>(web_ui()->GetWebContents()));
+
+ ui::SelectFileDialog::FileTypeInfo file_type_info;
+ file_type_info.extensions.resize(1);
+ file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("html"));
+
+ Browser* browser =
+ chrome::FindBrowserWithWebContents(web_ui()->GetWebContents());
+
+ select_file_dialog_->SelectFile(
+ ui::SelectFileDialog::SELECT_OPEN_FILE, base::string16(),
+ base::FilePath(), &file_type_info, 0, base::FilePath::StringType(),
+ browser->window()->GetNativeWindow(), nullptr);
+}
+
void ImportDataHandler::SendBrowserProfileData(const std::string& callback_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -168,14 +191,15 @@ void ImportDataHandler::SendBrowserProfileData(const std::string& callback_id) {
new base::DictionaryValue());
browser_profile->SetString("name", source_profile.importer_name);
browser_profile->SetInteger("index", i);
+ browser_profile->SetString("profileName", source_profile.profile);
browser_profile->SetBoolean("history",
- (browser_services & importer::HISTORY) != 0);
+ (browser_services & importer::HISTORY) != 0);
browser_profile->SetBoolean("favorites",
- (browser_services & importer::FAVORITES) != 0);
+ (browser_services & importer::FAVORITES) != 0);
browser_profile->SetBoolean("passwords",
- (browser_services & importer::PASSWORDS) != 0);
- browser_profile->SetBoolean("search",
- (browser_services & importer::SEARCH_ENGINES) != 0);
+ (browser_services & importer::PASSWORDS) != 0);
+ browser_profile->SetBoolean(
+ "search", (browser_services & importer::SEARCH_ENGINES) != 0);
browser_profile->SetBoolean(
"autofillFormData",
(browser_services & importer::AUTOFILL_FORM_DATA) != 0);
@@ -206,8 +230,8 @@ void ImportDataHandler::ImportItemEnded(importer::ImportItem item) {
void ImportDataHandler::ImportEnded() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- importer_host_->set_observer(NULL);
- importer_host_ = NULL;
+ importer_host_->set_observer(nullptr);
+ importer_host_ = nullptr;
FireWebUIListener("import-data-status-changed",
base::Value(import_did_succeed_ ? kImportStatusSucceeded
@@ -226,29 +250,4 @@ void ImportDataHandler::FileSelected(const base::FilePath& path,
StartImport(source_profile, importer::FAVORITES);
}
-void ImportDataHandler::HandleChooseBookmarksFile(const base::ListValue* args) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- DCHECK(args && args->empty());
- select_file_dialog_ = ui::SelectFileDialog::Create(
- this,
- std::make_unique<ChromeSelectFilePolicy>(web_ui()->GetWebContents()));
-
- ui::SelectFileDialog::FileTypeInfo file_type_info;
- file_type_info.extensions.resize(1);
- file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("html"));
-
- Browser* browser =
- chrome::FindBrowserWithWebContents(web_ui()->GetWebContents());
-
- select_file_dialog_->SelectFile(ui::SelectFileDialog::SELECT_OPEN_FILE,
- base::string16(),
- base::FilePath(),
- &file_type_info,
- 0,
- base::FilePath::StringType(),
- browser->window()->GetNativeWindow(),
- NULL);
-}
-
} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/settings_import_data_handler.h b/chromium/chrome/browser/ui/webui/settings/import_data_handler.h
index 68c9c7519e5..6ee9d1a99a8 100644
--- a/chromium/chrome/browser/ui/webui/settings/settings_import_data_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/import_data_handler.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_SETTINGS_IMPORT_DATA_HANDLER_H_
-#define CHROME_BROWSER_UI_WEBUI_SETTINGS_SETTINGS_IMPORT_DATA_HANDLER_H_
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_IMPORT_DATA_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_IMPORT_DATA_HANDLER_H_
#include <stdint.h>
@@ -38,9 +38,18 @@ class ImportDataHandler : public SettingsPageUIHandler,
void StartImport(const importer::SourceProfile& source_profile,
uint16_t imported_items);
- void ImportData(const base::ListValue* args);
+ // Handler for the "importData" message. First argument is the selected
+ // browser index, and second argument is the types of data to import.
+ void HandleImportData(const base::ListValue* args);
+
+ // Handler for the "initializeImportDialog" message. First argument is a
+ // callback id.
+ void HandleInitializeImportDialog(const base::ListValue* args);
+
+ // Handler for the "importFromBookmarksFile" message. Opens a file selection
+ // dialog to choose the bookmarks HTML file.
+ void HandleImportFromBookmarksFile(const base::ListValue* args);
- void InitializeDialog(const base::ListValue* args);
void SendBrowserProfileData(const std::string& callback_id);
// importer::ImporterProgressObserver:
@@ -54,9 +63,6 @@ class ImportDataHandler : public SettingsPageUIHandler,
int index,
void* params) override;
- // Opens a file selection dialog to choose the bookmarks HTML file.
- void HandleChooseBookmarksFile(const base::ListValue* args);
-
std::unique_ptr<ImporterList> importer_list_;
// If non-null it means importing is in progress. ImporterHost takes care
@@ -72,4 +78,4 @@ class ImportDataHandler : public SettingsPageUIHandler,
} // namespace settings
-#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_SETTINGS_IMPORT_DATA_HANDLER_H_
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_IMPORT_DATA_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/people_handler.cc b/chromium/chrome/browser/ui/webui/settings/people_handler.cc
index 6dc8e03ca5a..57cd1e34ebb 100644
--- a/chromium/chrome/browser/ui/webui/settings/people_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/people_handler.cc
@@ -18,11 +18,13 @@
#include "build/build_config.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_avatar_icon_util.h"
#include "chrome/browser/profiles/profile_metrics.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/signin/signin_error_controller_factory.h"
#include "chrome/browser/signin/signin_promo.h"
#include "chrome/browser/signin/signin_ui_util.h"
+#include "chrome/browser/signin/signin_util.h"
#include "chrome/browser/sync/profile_sync_service_factory.h"
#include "chrome/browser/sync/sync_ui_util.h"
#include "chrome/browser/ui/browser_finder.h"
@@ -32,6 +34,7 @@
#include "chrome/browser/ui/webui/signin/login_ui_service.h"
#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
#include "chrome/common/url_constants.h"
+#include "chrome/common/webui_url_constants.h"
#include "chrome/grit/generated_resources.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/prefs/pref_service.h"
@@ -39,6 +42,7 @@
#include "components/signin/public/base/signin_metrics.h"
#include "components/signin/public/base/signin_pref_names.h"
#include "components/signin/public/identity_manager/accounts_mutator.h"
+#include "components/signin/public/identity_manager/consent_level.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/signin/public/identity_manager/primary_account_mutator.h"
#include "components/strings/grit/components_strings.h"
@@ -51,26 +55,23 @@
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
#include "google_apis/gaia/gaia_auth_util.h"
+#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/webui/web_ui_util.h"
+#include "ui/gfx/image/image.h"
-#if defined(OS_CHROMEOS)
-#include "chrome/browser/chromeos/login/quick_unlock/pin_backend.h"
-#else
-#include "chrome/browser/signin/signin_util.h"
+#if !defined(OS_CHROMEOS)
#include "chrome/browser/ui/webui/profile_helper.h"
#endif
#if BUILDFLAG(ENABLE_DICE_SUPPORT)
-#include "chrome/browser/profiles/profile_avatar_icon_util.h"
#include "chrome/browser/signin/account_consistency_mode_manager.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "ui/gfx/image/image.h"
#endif
using content::WebContents;
using l10n_util::GetStringFUTF16;
using l10n_util::GetStringUTF16;
+using signin::ConsentLevel;
namespace {
@@ -88,11 +89,7 @@ struct SyncConfigInfo {
};
bool IsSyncSubpage(const GURL& current_url) {
- return (current_url == chrome::GetSettingsUrl(chrome::kSyncSetupSubPage)
-#if defined(OS_CHROMEOS)
- || current_url == chrome::GetOSSettingsUrl(chrome::kSyncSetupSubPage)
-#endif // defined(OS_CHROMEOS)
- );
+ return current_url == chrome::GetSettingsUrl(chrome::kSyncSetupSubPage);
}
SyncConfigInfo::SyncConfigInfo()
@@ -182,7 +179,6 @@ std::string GetSyncErrorAction(sync_ui_util::ActionType action_type) {
}
}
-#if BUILDFLAG(ENABLE_DICE_SUPPORT)
// Returns the base::Value associated with the account, to use in the stored
// accounts list.
base::Value GetAccountValue(const AccountInfo& account) {
@@ -198,7 +194,6 @@ base::Value GetAccountValue(const AccountInfo& account) {
}
return dictionary;
}
-#endif // BUILDFLAG(ENABLE_DICE_SUPPORT)
base::string16 GetEnterPassphraseBody(syncer::PassphraseType passphrase_type,
base::Time passphrase_time) {
@@ -254,9 +249,7 @@ base::string16 GetFullEncryptionBody(syncer::PassphraseType passphrase_type,
namespace settings {
// static
-const char PeopleHandler::kSpinnerPageStatus[] = "spinner";
const char PeopleHandler::kConfigurePageStatus[] = "configure";
-const char PeopleHandler::kTimeoutPageStatus[] = "timeout";
const char PeopleHandler::kDonePageStatus[] = "done";
const char PeopleHandler::kPassphraseFailedPageStatus[] = "passphraseFailed";
@@ -308,9 +301,11 @@ void PeopleHandler::RegisterMessages() {
base::BindRepeating(&PeopleHandler::HandleAttemptUserExit,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
- "RequestPinLoginState",
- base::BindRepeating(&PeopleHandler::HandleRequestPinLoginState,
- base::Unretained(this)));
+ "TurnOnSync", base::BindRepeating(&PeopleHandler::HandleTurnOnSync,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "TurnOffSync", base::BindRepeating(&PeopleHandler::HandleTurnOffSync,
+ base::Unretained(this)));
#else
web_ui()->RegisterMessageCallback(
"SyncSetupSignout", base::BindRepeating(&PeopleHandler::HandleSignout,
@@ -323,7 +318,6 @@ void PeopleHandler::RegisterMessages() {
base::BindRepeating(&PeopleHandler::HandleStartSignin,
base::Unretained(this)));
#endif
-#if BUILDFLAG(ENABLE_DICE_SUPPORT)
web_ui()->RegisterMessageCallback(
"SyncSetupGetStoredAccounts",
base::BindRepeating(&PeopleHandler::HandleGetStoredAccounts,
@@ -332,7 +326,6 @@ void PeopleHandler::RegisterMessages() {
"SyncSetupStartSyncingWithEmail",
base::BindRepeating(&PeopleHandler::HandleStartSyncingWithEmail,
base::Unretained(this)));
-#endif
web_ui()->RegisterMessageCallback(
"SyncStartKeyRetrieval",
base::BindRepeating(&PeopleHandler::HandleStartKeyRetrieval,
@@ -415,12 +408,6 @@ void PeopleHandler::DisplayGaiaLoginInNewTabOrWindow(
}
#endif
-#if defined(OS_CHROMEOS)
-void PeopleHandler::OnPinLoginAvailable(bool is_available) {
- FireWebUIListener("pin-login-available-changed", base::Value(is_available));
-}
-#endif
-
void PeopleHandler::OnDidClosePage(const base::ListValue* args) {
// Don't mark setup as complete if "didAbort" is true, or if authentication
// is still needed.
@@ -432,7 +419,7 @@ void PeopleHandler::OnDidClosePage(const base::ListValue* args) {
}
syncer::SyncService* PeopleHandler::GetSyncService() const {
- return profile_->IsSyncAllowed()
+ return ProfileSyncServiceFactory::IsSyncAllowed(profile_)
? ProfileSyncServiceFactory::GetForProfile(profile_)
: nullptr;
}
@@ -457,6 +444,11 @@ void PeopleHandler::HandleSetDatatypes(const base::ListValue* args) {
return;
}
+ // Don't enable non-registered types (for example, kApps may not be registered
+ // on Chrome OS).
+ configuration.selected_types.RetainAll(
+ service->GetUserSettings()->GetRegisteredSelectableTypes());
+
service->GetUserSettings()->SetSelectedTypes(configuration.sync_everything,
configuration.selected_types);
@@ -468,8 +460,8 @@ void PeopleHandler::HandleSetDatatypes(const base::ListValue* args) {
ProfileMetrics::LogProfileSyncInfo(ProfileMetrics::SYNC_CHOOSE);
}
-#if BUILDFLAG(ENABLE_DICE_SUPPORT)
void PeopleHandler::HandleGetStoredAccounts(const base::ListValue* args) {
+ AllowJavascript();
CHECK_EQ(1U, args->GetSize());
const base::Value* callback_id;
CHECK(args->Get(0, &callback_id));
@@ -487,30 +479,33 @@ void PeopleHandler::OnExtendedAccountInfoRemoved(const AccountInfo& info) {
base::Value PeopleHandler::GetStoredAccountsList() {
base::Value accounts(base::Value::Type::LIST);
- const bool dice_enabled =
- AccountConsistencyModeManager::IsDiceEnabledForProfile(profile_);
-
- if (dice_enabled) {
+#if BUILDFLAG(ENABLE_DICE_SUPPORT)
+ if (AccountConsistencyModeManager::IsDiceEnabledForProfile(profile_)) {
// If dice is enabled, show all the accounts.
- for (auto const& account :
+ for (const auto& account :
signin_ui_util::GetAccountsForDicePromos(profile_)) {
accounts.Append(GetAccountValue(account));
}
- } else {
- // If dice is disabled (and unified consent enabled), show only the primary
- // account.
- auto* identity_manager = IdentityManagerFactory::GetForProfile(profile_);
- base::Optional<AccountInfo> primary_account_info =
- identity_manager->FindExtendedAccountInfoForAccountWithRefreshToken(
- identity_manager->GetPrimaryAccountInfo());
- if (primary_account_info.has_value())
- accounts.Append(GetAccountValue(primary_account_info.value()));
+ return accounts;
}
-
+#endif
+ // Guest mode does not have a primary account (or an IdentityManager).
+ if (profile_->IsGuestSession())
+ return base::ListValue();
+ // If DICE is disabled for this profile or unsupported on this platform (e.g.
+ // Chrome OS), then show only the primary account, whether or not that account
+ // has consented to sync.
+ auto* identity_manager = IdentityManagerFactory::GetForProfile(profile_);
+ base::Optional<AccountInfo> primary_account_info =
+ identity_manager->FindExtendedAccountInfoForAccountWithRefreshToken(
+ identity_manager->GetPrimaryAccountInfo(ConsentLevel::kNotRequired));
+ if (primary_account_info.has_value())
+ accounts.Append(GetAccountValue(primary_account_info.value()));
return accounts;
}
void PeopleHandler::HandleStartSyncingWithEmail(const base::ListValue* args) {
+#if BUILDFLAG(ENABLE_DICE_SUPPORT)
DCHECK(AccountConsistencyModeManager::IsDiceEnabledForProfile(profile_));
const base::Value* email;
const base::Value* is_default_promo_account;
@@ -530,8 +525,11 @@ void PeopleHandler::HandleStartSyncingWithEmail(const base::ListValue* args) {
maybe_account.has_value() ? maybe_account.value() : AccountInfo(),
signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS,
is_default_promo_account->GetBool());
-}
+#else
+ // TODO(jamescook): Enable sync on non-DICE platforms (e.g. Chrome OS).
+ NOTIMPLEMENTED();
#endif
+}
void PeopleHandler::HandleSetEncryption(const base::ListValue* args) {
SyncConfigInfo configuration;
@@ -577,6 +575,11 @@ void PeopleHandler::HandleSetEncryption(const base::ListValue* args) {
// data types.
passphrase_failed = !service->GetUserSettings()->SetDecryptionPassphrase(
configuration.passphrase);
+ } else if (service->GetUserSettings()->IsTrustedVaultKeyRequired()) {
+ // There are pending keys due to trusted vault keys being required, likely
+ // because something changed since the UI was displayed. A passphrase
+ // cannot be set in such circumstances.
+ passphrase_failed = true;
} else {
// OK, the user sent us a passphrase, but we don't have pending keys. So
// it either means that the pending keys were resolved somehow since the
@@ -646,13 +649,22 @@ void PeopleHandler::HandleAttemptUserExit(const base::ListValue* args) {
chrome::AttemptUserExit();
}
-void PeopleHandler::HandleRequestPinLoginState(const base::ListValue* args) {
- AllowJavascript();
- chromeos::quick_unlock::PinBackend::GetInstance()->HasLoginSupport(
- base::BindOnce(&PeopleHandler::OnPinLoginAvailable,
- weak_factory_.GetWeakPtr()));
+void PeopleHandler::HandleTurnOnSync(const base::ListValue* args) {
+ // TODO(https://crbug.com/1050677)
+ NOTIMPLEMENTED();
}
-#endif
+
+void PeopleHandler::HandleTurnOffSync(const base::ListValue* args) {
+ auto* identity_manager = IdentityManagerFactory::GetForProfile(profile_);
+ DCHECK(identity_manager->HasPrimaryAccount(ConsentLevel::kSync));
+ DCHECK(signin_util::IsUserSignoutAllowedForProfile(profile_));
+
+ if (GetSyncService())
+ syncer::RecordSyncEvent(syncer::STOP_FROM_OPTIONS);
+
+ identity_manager->GetPrimaryAccountMutator()->RevokeSyncConsent();
+}
+#endif // defined(OS_CHROMEOS)
#if !defined(OS_CHROMEOS)
void PeopleHandler::HandleStartSignin(const base::ListValue* args) {
@@ -807,6 +819,10 @@ void PeopleHandler::InitializeSyncBlocker() {
if (!service)
return;
+ // The user opened settings directly to the syncSetup sub-page, because they
+ // clicked "Settings" in the browser sync consent dialog or because they
+ // clicked "Review sync options" in the Chrome OS out-of-box experience.
+ // Don't start syncing until they finish setup.
if (IsSyncSubpage(web_contents->GetVisibleURL())) {
sync_blocker_ = service->GetSetupInProgressHandle();
}
@@ -860,7 +876,6 @@ std::unique_ptr<base::DictionaryValue> PeopleHandler::GetSyncStatusDictionary()
if (profile_->IsGuestSession()) {
// Cannot display signin status when running in guest mode on chromeos
// because there is no IdentityManager.
- sync_status->SetBoolean("signinAllowed", false);
return sync_status;
}
@@ -870,7 +885,6 @@ std::unique_ptr<base::DictionaryValue> PeopleHandler::GetSyncStatusDictionary()
auto* identity_manager = IdentityManagerFactory::GetForProfile(profile_);
DCHECK(identity_manager);
-#if !defined(OS_CHROMEOS)
// Signout is not allowed if the user has policy (crbug.com/172204).
if (!signin_util::IsUserSignoutAllowedForProfile(profile_)) {
std::string username = identity_manager->GetPrimaryAccountInfo().email;
@@ -880,7 +894,6 @@ std::unique_ptr<base::DictionaryValue> PeopleHandler::GetSyncStatusDictionary()
if (!username.empty())
sync_status->SetString("domain", gaia::ExtractDomainName(username));
}
-#endif
// This is intentionally not using GetSyncService(), in order to access more
// nuanced information, since GetSyncService() returns nullptr if anything
@@ -890,8 +903,6 @@ std::unique_ptr<base::DictionaryValue> PeopleHandler::GetSyncStatusDictionary()
bool disallowed_by_policy =
service && service->HasDisableReason(
syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY);
- sync_status->SetBoolean(
- "signinAllowed", profile_->GetPrefs()->GetBoolean(prefs::kSigninAllowed));
sync_status->SetBoolean("syncSystemEnabled", (service != nullptr));
sync_status->SetBoolean(
"firstSetupInProgress",
@@ -906,7 +917,7 @@ std::unique_ptr<base::DictionaryValue> PeopleHandler::GetSyncStatusDictionary()
sync_status->SetString("statusText",
GetStringUTF16(status_labels.status_label_string_id));
sync_status->SetString("statusActionText",
- GetStringUTF16(status_labels.link_label_string_id));
+ GetStringUTF16(status_labels.button_string_id));
sync_status->SetBoolean(
"hasError", status_labels.message_type == sync_ui_util::SYNC_ERROR ||
status_labels.message_type ==
@@ -921,6 +932,8 @@ std::unique_ptr<base::DictionaryValue> PeopleHandler::GetSyncStatusDictionary()
sync_status->SetBoolean(
"disabled", !service || disallowed_by_policy ||
!service->GetUserSettings()->IsSyncAllowedByPlatform());
+ // NOTE: This means signed-in for *sync*. It can be false when the user is
+ // signed-in to the content area or to the browser.
sync_status->SetBoolean("signedIn", identity_manager->HasPrimaryAccount());
sync_status->SetString("signedInUsername",
signin_ui_util::GetAuthenticatedUsername(profile_));
@@ -964,13 +977,10 @@ void PeopleHandler::PushSyncPrefs() {
sync_user_settings->GetRegisteredSelectableTypes();
const syncer::UserSelectableTypeSet selected_types =
sync_user_settings->GetSelectedTypes();
- const syncer::UserSelectableTypeSet enforced_types =
- sync_user_settings->GetForcedTypes();
for (syncer::UserSelectableType type : syncer::UserSelectableTypeSet::All()) {
const std::string type_name = syncer::GetUserSelectableTypeName(type);
args.SetBoolean(type_name + "Registered", registered_types.Has(type));
args.SetBoolean(type_name + "Synced", selected_types.Has(type));
- args.SetBoolean(type_name + "Enforced", enforced_types.Has(type));
}
args.SetBoolean("syncAllDataTypes",
sync_user_settings->IsSyncEverythingEnabled());
@@ -988,9 +998,10 @@ void PeopleHandler::PushSyncPrefs() {
args.SetBoolean("passphraseRequired",
sync_user_settings->IsPassphraseRequired());
- args.SetBoolean(
- "trustedVaultKeysRequired",
- sync_user_settings->IsTrustedVaultKeyRequiredForPreferredDataTypes());
+ // Same as above, we call IsTrustedVaultKeyRequired() here instead of.
+ // IsTrustedVaultKeyRequiredForPreferredDataTypes().
+ args.SetBoolean("trustedVaultKeysRequired",
+ sync_user_settings->IsTrustedVaultKeyRequired());
syncer::PassphraseType passphrase_type =
sync_user_settings->GetPassphraseType();
diff --git a/chromium/chrome/browser/ui/webui/settings/people_handler.h b/chromium/chrome/browser/ui/webui/settings/people_handler.h
index 1573a3ce552..50093e129c3 100644
--- a/chromium/chrome/browser/ui/webui/settings/people_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/people_handler.h
@@ -47,13 +47,9 @@ class PeopleHandler : public SettingsPageUIHandler,
public:
// TODO(tommycli): Remove these strings and instead use WebUIListener events.
// These string constants are used from JavaScript (sync_browser_proxy.js).
- static const char kSpinnerPageStatus[];
static const char kConfigurePageStatus[];
- static const char kTimeoutPageStatus[];
static const char kDonePageStatus[];
static const char kPassphraseFailedPageStatus[];
- // TODO(crbug.com/): Remove kSpinnerPageStatus and kTimeoutPageStatus (plus
- // their JS-side handling); they're unused.
explicit PeopleHandler(Profile* profile);
~PeopleHandler() override;
@@ -89,6 +85,7 @@ class PeopleHandler : public SettingsPageUIHandler,
FRIEND_TEST_ALL_PREFIXES(PeopleHandlerTest, ShowSyncSetup);
FRIEND_TEST_ALL_PREFIXES(PeopleHandlerTest, TestSyncEverything);
FRIEND_TEST_ALL_PREFIXES(PeopleHandlerTest, TestSyncAllManually);
+ FRIEND_TEST_ALL_PREFIXES(PeopleHandlerTest, NonRegisteredType);
FRIEND_TEST_ALL_PREFIXES(PeopleHandlerTest, TestPassphraseStillRequired);
FRIEND_TEST_ALL_PREFIXES(PeopleHandlerTest, TestSyncIndividualTypes);
FRIEND_TEST_ALL_PREFIXES(PeopleHandlerTest,
@@ -97,10 +94,10 @@ class PeopleHandler : public SettingsPageUIHandler,
FRIEND_TEST_ALL_PREFIXES(PeopleHandlerTest, EnterWrongExistingPassphrase);
FRIEND_TEST_ALL_PREFIXES(PeopleHandlerTest, EnterBlankExistingPassphrase);
FRIEND_TEST_ALL_PREFIXES(PeopleHandlerTest, TurnOnEncryptAllDisallowed);
- FRIEND_TEST_ALL_PREFIXES(PeopleHandlerNonCrosTest,
+ FRIEND_TEST_ALL_PREFIXES(PeopleHandlerTest,
UnrecoverableErrorInitializingSync);
- FRIEND_TEST_ALL_PREFIXES(PeopleHandlerNonCrosTest, GaiaErrorInitializingSync);
- FRIEND_TEST_ALL_PREFIXES(PeopleHandlerFirstSigninTest, DisplayBasicLogin);
+ FRIEND_TEST_ALL_PREFIXES(PeopleHandlerTest, GaiaErrorInitializingSync);
+ FRIEND_TEST_ALL_PREFIXES(PeopleHandlerTest, DisplayBasicLogin);
FRIEND_TEST_ALL_PREFIXES(PeopleHandlerTest,
AcquireSyncBlockerWhenLoadingSyncSettingsSubpage);
FRIEND_TEST_ALL_PREFIXES(PeopleHandlerTest, RestartSyncAfterDashboardClear);
@@ -113,6 +110,9 @@ class PeopleHandler : public SettingsPageUIHandler,
DashboardClearWhileSettingsOpen_ConfirmLater);
FRIEND_TEST_ALL_PREFIXES(PeopleHandlerDiceUnifiedConsentTest,
StoredAccountsList);
+ FRIEND_TEST_ALL_PREFIXES(PeopleHandlerGuestModeTest, GetStoredAccountsList);
+ FRIEND_TEST_ALL_PREFIXES(PeopleHandlerTest, TurnOffSync);
+ FRIEND_TEST_ALL_PREFIXES(PeopleHandlerTest, GetStoredAccountsList);
// SettingsPageUIHandler implementation.
void RegisterMessages() override;
@@ -127,10 +127,8 @@ class PeopleHandler : public SettingsPageUIHandler,
const CoreAccountInfo& primary_account_info) override;
void OnPrimaryAccountCleared(
const CoreAccountInfo& previous_primary_account_info) override;
-#if BUILDFLAG(ENABLE_DICE_SUPPORT)
void OnExtendedAccountInfoUpdated(const AccountInfo& info) override;
void OnExtendedAccountInfoRemoved(const AccountInfo& info) override;
-#endif
// syncer::SyncServiceObserver implementation.
void OnStateChanged(syncer::SyncService* sync) override;
@@ -155,10 +153,11 @@ class PeopleHandler : public SettingsPageUIHandler,
void HandleSetDatatypes(const base::ListValue* args);
void HandleSetEncryption(const base::ListValue* args);
void HandleShowSetupUI(const base::ListValue* args);
- void HandleAttemptUserExit(const base::ListValue* args);
void HandleSyncPrefsDispatch(const base::ListValue* args);
#if defined(OS_CHROMEOS)
- void HandleRequestPinLoginState(const base::ListValue* args);
+ void HandleAttemptUserExit(const base::ListValue* args);
+ void HandleTurnOnSync(const base::ListValue* args);
+ void HandleTurnOffSync(const base::ListValue* args);
#endif
#if !defined(OS_CHROMEOS)
void HandleStartSignin(const base::ListValue* args);
@@ -178,15 +177,9 @@ class PeopleHandler : public SettingsPageUIHandler,
signin_metrics::AccessPoint access_point);
#endif
-#if defined(OS_CHROMEOS)
- void OnPinLoginAvailable(bool is_available);
-#endif
-
-#if BUILDFLAG(ENABLE_DICE_SUPPORT)
void HandleGetStoredAccounts(const base::ListValue* args);
void HandleStartSyncingWithEmail(const base::ListValue* args);
base::Value GetStoredAccountsList();
-#endif
// Pushes the updated sync prefs to JavaScript.
void PushSyncPrefs();
@@ -233,9 +226,7 @@ class PeopleHandler : public SettingsPageUIHandler,
ScopedObserver<syncer::SyncService, syncer::SyncServiceObserver>
sync_service_observer_{this};
-#if defined(OS_CHROMEOS)
base::WeakPtrFactory<PeopleHandler> weak_factory_{this};
-#endif
DISALLOW_COPY_AND_ASSIGN(PeopleHandler);
};
diff --git a/chromium/chrome/browser/ui/webui/settings/people_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/people_handler_unittest.cc
index 60c758ab17d..f2ecedd6377 100644
--- a/chromium/chrome/browser/ui/webui/settings/people_handler_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/people_handler_unittest.cc
@@ -14,6 +14,7 @@
#include "base/json/json_writer.h"
#include "base/macros.h"
#include "base/stl_util.h"
+#include "base/test/mock_callback.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/defaults.h"
@@ -35,9 +36,11 @@
#include "chrome/test/base/testing_profile.h"
#include "components/prefs/pref_service.h"
#include "components/signin/public/identity_manager/accounts_mutator.h"
+#include "components/signin/public/identity_manager/consent_level.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/signin/public/identity_manager/identity_test_utils.h"
#include "components/sync/base/passphrase_enums.h"
+#include "components/sync/base/user_selectable_type.h"
#include "components/sync/driver/mock_sync_service.h"
#include "components/sync/driver/sync_user_settings_impl.h"
#include "components/sync/driver/sync_user_settings_mock.h"
@@ -50,6 +53,7 @@
#include "content/public/test/web_contents_tester.h"
#include "testing/gtest/include/gtest/gtest.h"
+using signin::ConsentLevel;
using ::testing::_;
using ::testing::ByMove;
using ::testing::Const;
@@ -211,19 +215,15 @@ class TestWebUIProvider
class PeopleHandlerTest : public ChromeRenderViewHostTestHarness {
public:
- PeopleHandlerTest() {}
+ PeopleHandlerTest() = default;
+ ~PeopleHandlerTest() override = default;
void SetUp() override {
ChromeRenderViewHostTestHarness::SetUp();
- // Sign in the user.
identity_test_env_adaptor_ =
std::make_unique<IdentityTestEnvironmentProfileAdaptor>(profile());
- std::string username = GetTestUser();
- if (!username.empty())
- identity_test_env()->SetPrimaryAccount(username);
-
mock_sync_service_ = static_cast<syncer::MockSyncService*>(
ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse(
profile(), base::BindRepeating(&BuildMockSyncService)));
@@ -241,13 +241,7 @@ class PeopleHandlerTest : public ChromeRenderViewHostTestHarness {
ON_CALL(*mock_sync_service_, GetSetupInProgressHandle())
.WillByDefault(
Return(ByMove(std::make_unique<syncer::SyncSetupInProgressHandle>(
- base::BindRepeating(
- &PeopleHandlerTest::OnSetupInProgressHandleDestroyed,
- base::Unretained(this))))));
-
- handler_ = std::make_unique<TestingPeopleHandler>(&web_ui_, profile());
- handler_->AllowJavascript();
- web_ui_.set_web_contents(web_contents());
+ mock_on_setup_in_progress_handle_destroyed_.Get()))));
}
void TearDown() override {
@@ -262,10 +256,18 @@ class PeopleHandlerTest : public ChromeRenderViewHostTestHarness {
GetIdentityTestEnvironmentFactories();
}
+ void SigninUser() { identity_test_env()->SetPrimaryAccount(kTestUser); }
+
+ void CreatePeopleHandler() {
+ handler_ = std::make_unique<TestingPeopleHandler>(&web_ui_, profile());
+ handler_->AllowJavascript();
+ web_ui_.set_web_contents(web_contents());
+ }
+
// Setup the expectations for calls made when displaying the config page.
void SetDefaultExpectationsForConfigPage() {
ON_CALL(*mock_sync_service_, GetDisableReasons())
- .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NONE));
+ .WillByDefault(Return(syncer::SyncService::DisableReasonSet()));
ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsSyncRequested())
.WillByDefault(Return(true));
ON_CALL(*mock_sync_service_->GetMockUserSettings(),
@@ -305,17 +307,6 @@ class PeopleHandlerTest : public ChromeRenderViewHostTestHarness {
EXPECT_EQ(expected_status, status);
}
- void ExpectPageStatusChanged(const std::string& expected_status) {
- auto& data = *web_ui_.call_data().back();
- EXPECT_EQ("cr.webUIListenerCallback", data.function_name());
- std::string event;
- ASSERT_TRUE(data.arg1()->GetAsString(&event));
- EXPECT_EQ("page-status-changed", event);
- std::string status;
- ASSERT_TRUE(data.arg2()->GetAsString(&status));
- EXPECT_EQ(expected_status, status);
- }
-
const base::DictionaryValue* ExpectSyncPrefsChanged() {
const content::TestWebUI::CallData& data1 = *web_ui_.call_data().back();
EXPECT_EQ("cr.webUIListenerCallback", data1.function_name());
@@ -329,20 +320,33 @@ class PeopleHandlerTest : public ChromeRenderViewHostTestHarness {
return dictionary;
}
- void NotifySyncStateChanged() {
- handler_->OnStateChanged(mock_sync_service_);
+ const base::DictionaryValue* ExpectSyncStatusChanged() {
+ const content::TestWebUI::CallData& data = *web_ui_.call_data().back();
+ EXPECT_EQ("cr.webUIListenerCallback", data.function_name());
+
+ std::string event;
+ EXPECT_TRUE(data.arg1()->GetAsString(&event));
+ EXPECT_EQ(event, "sync-status-changed");
+
+ const base::DictionaryValue* dictionary = nullptr;
+ EXPECT_TRUE(data.arg2()->GetAsDictionary(&dictionary));
+ return dictionary;
}
- virtual std::string GetTestUser() {
- return std::string(kTestUser);
+ void NotifySyncStateChanged() {
+ handler_->OnStateChanged(mock_sync_service_);
}
signin::IdentityTestEnvironment* identity_test_env() {
return identity_test_env_adaptor_->identity_test_env();
}
- MOCK_METHOD0(OnSetupInProgressHandleDestroyed, void());
+ signin::IdentityManager* identity_manager() {
+ return identity_test_env()->identity_manager();
+ }
+ testing::NiceMock<base::MockCallback<base::RepeatingClosure>>
+ mock_on_setup_in_progress_handle_destroyed_;
syncer::MockSyncService* mock_sync_service_;
std::unique_ptr<IdentityTestEnvironmentProfileAdaptor>
identity_test_env_adaptor_;
@@ -354,12 +358,11 @@ class PeopleHandlerTest : public ChromeRenderViewHostTestHarness {
DISALLOW_COPY_AND_ASSIGN(PeopleHandlerTest);
};
-class PeopleHandlerFirstSigninTest : public PeopleHandlerTest {
- std::string GetTestUser() override { return std::string(); }
-};
-
#if !defined(OS_CHROMEOS)
-TEST_F(PeopleHandlerFirstSigninTest, DisplayBasicLogin) {
+TEST_F(PeopleHandlerTest, DisplayBasicLogin) {
+ ASSERT_FALSE(identity_test_env()->identity_manager()->HasPrimaryAccount(
+ ConsentLevel::kSync));
+ CreatePeopleHandler();
// Test that the HandleStartSignin call enables JavaScript.
handler_->DisallowJavascript();
@@ -374,22 +377,24 @@ TEST_F(PeopleHandlerFirstSigninTest, DisplayBasicLogin) {
// Sync setup hands off control to the gaia login tab.
EXPECT_EQ(
- NULL,
+ nullptr,
LoginUIServiceFactory::GetForProfile(profile())->current_login_ui());
ASSERT_FALSE(handler_->is_configuring_sync());
handler_->CloseSyncSetup();
EXPECT_EQ(
- NULL,
+ nullptr,
LoginUIServiceFactory::GetForProfile(profile())->current_login_ui());
}
#endif // !defined(OS_CHROMEOS)
TEST_F(PeopleHandlerTest, DisplayConfigureWithEngineDisabledAndCancel) {
+ SigninUser();
+ CreatePeopleHandler();
ON_CALL(*mock_sync_service_, GetDisableReasons())
- .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NONE));
+ .WillByDefault(Return(syncer::SyncService::DisableReasonSet()));
ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsSyncRequested())
.WillByDefault(Return(true));
ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsFirstSetupComplete())
@@ -414,7 +419,7 @@ TEST_F(PeopleHandlerTest, DisplayConfigureWithEngineDisabledAndCancel) {
handler_->CloseSyncSetup();
EXPECT_EQ(
- NULL,
+ nullptr,
LoginUIServiceFactory::GetForProfile(profile())->current_login_ui());
}
@@ -422,10 +427,12 @@ TEST_F(PeopleHandlerTest, DisplayConfigureWithEngineDisabledAndCancel) {
// initialized.
TEST_F(PeopleHandlerTest,
DisplayConfigureWithEngineDisabledAndSyncStartupCompleted) {
+ SigninUser();
+ CreatePeopleHandler();
ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsFirstSetupComplete())
.WillByDefault(Return(false));
ON_CALL(*mock_sync_service_, GetDisableReasons())
- .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NONE));
+ .WillByDefault(Return(syncer::SyncService::DisableReasonSet()));
ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsSyncRequested())
.WillByDefault(Return(true));
// Sync engine is stopped initially, and will start up.
@@ -463,8 +470,10 @@ TEST_F(PeopleHandlerTest,
// initialized.
TEST_F(PeopleHandlerTest,
DisplayConfigureWithEngineDisabledAndCancelAfterSigninSuccess) {
+ SigninUser();
+ CreatePeopleHandler();
ON_CALL(*mock_sync_service_, GetDisableReasons())
- .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NONE));
+ .WillByDefault(Return(syncer::SyncService::DisableReasonSet()));
ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsSyncRequested())
.WillByDefault(Return(true));
ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsFirstSetupComplete())
@@ -484,15 +493,17 @@ TEST_F(PeopleHandlerTest,
// tell it we're through with the setup progress.
testing::InSequence seq;
EXPECT_CALL(*mock_sync_service_, StopAndClear());
- EXPECT_CALL(*this, OnSetupInProgressHandleDestroyed());
+ EXPECT_CALL(mock_on_setup_in_progress_handle_destroyed_, Run());
handler_->CloseSyncSetup();
EXPECT_EQ(
- NULL,
+ nullptr,
LoginUIServiceFactory::GetForProfile(profile())->current_login_ui());
}
TEST_F(PeopleHandlerTest, RestartSyncAfterDashboardClear) {
+ SigninUser();
+ CreatePeopleHandler();
// Clearing sync from the dashboard results in DISABLE_REASON_USER_CHOICE
// being set.
ON_CALL(*mock_sync_service_, GetDisableReasons())
@@ -507,7 +518,7 @@ TEST_F(PeopleHandlerTest, RestartSyncAfterDashboardClear) {
// SetSyncRequested(true) clears DISABLE_REASON_USER_CHOICE, and
// immediately starts initializing the engine.
ON_CALL(*mock_sync_service_, GetDisableReasons())
- .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NONE));
+ .WillByDefault(Return(syncer::SyncService::DisableReasonSet()));
ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsSyncRequested())
.WillByDefault(Return(true));
ON_CALL(*mock_sync_service_, GetTransportState())
@@ -523,6 +534,8 @@ TEST_F(PeopleHandlerTest, RestartSyncAfterDashboardClear) {
TEST_F(PeopleHandlerTest,
RestartSyncAfterDashboardClearWithStandaloneTransport) {
+ SigninUser();
+ CreatePeopleHandler();
// Clearing sync from the dashboard results in DISABLE_REASON_USER_CHOICE
// being set. However, the sync engine has restarted in standalone transport
// mode.
@@ -538,7 +551,7 @@ TEST_F(PeopleHandlerTest,
// SetSyncRequested(true) clears DISABLE_REASON_USER_CHOICE. Since the
// engine is already running, it just gets reconfigured.
ON_CALL(*mock_sync_service_, GetDisableReasons())
- .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NONE));
+ .WillByDefault(Return(syncer::SyncService::DisableReasonSet()));
ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsSyncRequested())
.WillByDefault(Return(true));
ON_CALL(*mock_sync_service_, GetTransportState())
@@ -555,6 +568,8 @@ TEST_F(PeopleHandlerTest,
// Tests that signals not related to user intention to configure sync don't
// trigger sync engine start.
TEST_F(PeopleHandlerTest, OnlyStartEngineWhenConfiguringSync) {
+ SigninUser();
+ CreatePeopleHandler();
ON_CALL(*mock_sync_service_, GetTransportState())
.WillByDefault(Return(syncer::SyncService::TransportState::INITIALIZING));
EXPECT_CALL(*mock_sync_service_->GetMockUserSettings(),
@@ -564,6 +579,8 @@ TEST_F(PeopleHandlerTest, OnlyStartEngineWhenConfiguringSync) {
}
TEST_F(PeopleHandlerTest, AcquireSyncBlockerWhenLoadingSyncSettingsSubpage) {
+ SigninUser();
+ CreatePeopleHandler();
// We set up a factory override here to prevent a new web ui from being
// created when we navigate to a page that would normally create one.
test_factory_ = std::make_unique<TestChromeWebUIControllerFactory>();
@@ -584,15 +601,9 @@ TEST_F(PeopleHandlerTest, AcquireSyncBlockerWhenLoadingSyncSettingsSubpage) {
EXPECT_TRUE(handler_->sync_blocker_);
}
-#if !defined(OS_CHROMEOS)
-
-class PeopleHandlerNonCrosTest : public PeopleHandlerTest {
- public:
- PeopleHandlerNonCrosTest() {}
-};
-
-// TODO(kochi): We need equivalent tests for ChromeOS.
-TEST_F(PeopleHandlerNonCrosTest, UnrecoverableErrorInitializingSync) {
+TEST_F(PeopleHandlerTest, UnrecoverableErrorInitializingSync) {
+ SigninUser();
+ CreatePeopleHandler();
ON_CALL(*mock_sync_service_, GetDisableReasons())
.WillByDefault(
Return(syncer::SyncService::DISABLE_REASON_UNRECOVERABLE_ERROR));
@@ -604,7 +615,9 @@ TEST_F(PeopleHandlerNonCrosTest, UnrecoverableErrorInitializingSync) {
ASSERT_FALSE(handler_->is_configuring_sync());
}
-TEST_F(PeopleHandlerNonCrosTest, GaiaErrorInitializingSync) {
+TEST_F(PeopleHandlerTest, GaiaErrorInitializingSync) {
+ SigninUser();
+ CreatePeopleHandler();
ON_CALL(*mock_sync_service_, GetDisableReasons())
.WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN));
ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsFirstSetupComplete())
@@ -615,11 +628,11 @@ TEST_F(PeopleHandlerNonCrosTest, GaiaErrorInitializingSync) {
ASSERT_FALSE(handler_->is_configuring_sync());
}
-#endif // #if !defined(OS_CHROMEOS)
-
TEST_F(PeopleHandlerTest, TestSyncEverything) {
- std::string args = GetConfiguration(
- NULL, SYNC_ALL_DATA, GetAllTypes(), std::string(), ENCRYPT_PASSWORDS);
+ SigninUser();
+ CreatePeopleHandler();
+ std::string args = GetConfiguration(nullptr, SYNC_ALL_DATA, GetAllTypes(),
+ std::string(), ENCRYPT_PASSWORDS);
base::ListValue list_args;
list_args.AppendString(kTestCallbackId);
list_args.AppendString(args);
@@ -637,8 +650,10 @@ TEST_F(PeopleHandlerTest, TestSyncEverything) {
}
TEST_F(PeopleHandlerTest, TestPassphraseStillRequired) {
- std::string args = GetConfiguration(
- NULL, SYNC_ALL_DATA, GetAllTypes(), std::string(), ENCRYPT_PASSWORDS);
+ SigninUser();
+ CreatePeopleHandler();
+ std::string args = GetConfiguration(nullptr, SYNC_ALL_DATA, GetAllTypes(),
+ std::string(), ENCRYPT_PASSWORDS);
base::ListValue list_args;
list_args.AppendString(kTestCallbackId);
list_args.AppendString(args);
@@ -659,6 +674,8 @@ TEST_F(PeopleHandlerTest, TestPassphraseStillRequired) {
}
TEST_F(PeopleHandlerTest, EnterExistingFrozenImplicitPassword) {
+ SigninUser();
+ CreatePeopleHandler();
base::DictionaryValue dict;
dict.SetBoolean("setNewPassphrase", false);
std::string args = GetConfiguration(&dict, SYNC_ALL_DATA, GetAllTypes(),
@@ -687,6 +704,8 @@ TEST_F(PeopleHandlerTest, EnterExistingFrozenImplicitPassword) {
}
TEST_F(PeopleHandlerTest, SetNewCustomPassphrase) {
+ SigninUser();
+ CreatePeopleHandler();
base::DictionaryValue dict;
dict.SetBoolean("setNewPassphrase", true);
std::string args = GetConfiguration(&dict, SYNC_ALL_DATA, GetAllTypes(),
@@ -714,6 +733,8 @@ TEST_F(PeopleHandlerTest, SetNewCustomPassphrase) {
}
TEST_F(PeopleHandlerTest, EnterWrongExistingPassphrase) {
+ SigninUser();
+ CreatePeopleHandler();
base::DictionaryValue dict;
dict.SetBoolean("setNewPassphrase", false);
std::string args = GetConfiguration(&dict, SYNC_ALL_DATA, GetAllTypes(),
@@ -742,6 +763,8 @@ TEST_F(PeopleHandlerTest, EnterWrongExistingPassphrase) {
}
TEST_F(PeopleHandlerTest, EnterBlankExistingPassphrase) {
+ SigninUser();
+ CreatePeopleHandler();
base::DictionaryValue dict;
dict.SetBoolean("setNewPassphrase", false);
std::string args = GetConfiguration(&dict,
@@ -772,14 +795,15 @@ TEST_F(PeopleHandlerTest, EnterBlankExistingPassphrase) {
// Walks through each user selectable type, and tries to sync just that single
// data type.
TEST_F(PeopleHandlerTest, TestSyncIndividualTypes) {
+ SigninUser();
+ CreatePeopleHandler();
+ SetDefaultExpectationsForConfigPage();
for (syncer::UserSelectableType type : GetAllTypes()) {
syncer::UserSelectableTypeSet type_to_set;
type_to_set.Put(type);
- std::string args = GetConfiguration(NULL,
- CHOOSE_WHAT_TO_SYNC,
- type_to_set,
- std::string(),
- ENCRYPT_PASSWORDS);
+ std::string args =
+ GetConfiguration(nullptr, CHOOSE_WHAT_TO_SYNC, type_to_set,
+ std::string(), ENCRYPT_PASSWORDS);
base::ListValue list_args;
list_args.AppendString(kTestCallbackId);
list_args.AppendString(args);
@@ -799,11 +823,12 @@ TEST_F(PeopleHandlerTest, TestSyncIndividualTypes) {
}
TEST_F(PeopleHandlerTest, TestSyncAllManually) {
- std::string args = GetConfiguration(NULL,
- CHOOSE_WHAT_TO_SYNC,
- GetAllTypes(),
- std::string(),
- ENCRYPT_PASSWORDS);
+ SigninUser();
+ CreatePeopleHandler();
+ SetDefaultExpectationsForConfigPage();
+ std::string args =
+ GetConfiguration(nullptr, CHOOSE_WHAT_TO_SYNC, GetAllTypes(),
+ std::string(), ENCRYPT_PASSWORDS);
base::ListValue list_args;
list_args.AppendString(kTestCallbackId);
list_args.AppendString(args);
@@ -820,7 +845,37 @@ TEST_F(PeopleHandlerTest, TestSyncAllManually) {
ExpectPageStatusResponse(PeopleHandler::kConfigurePageStatus);
}
+TEST_F(PeopleHandlerTest, NonRegisteredType) {
+ SigninUser();
+ CreatePeopleHandler();
+ SetDefaultExpectationsForConfigPage();
+
+ // Simulate apps not being registered.
+ syncer::UserSelectableTypeSet registered_types = GetAllTypes();
+ registered_types.Remove(syncer::UserSelectableType::kApps);
+ ON_CALL(*mock_sync_service_->GetMockUserSettings(),
+ GetRegisteredSelectableTypes())
+ .WillByDefault(Return(registered_types));
+ SetupInitializedSyncService();
+
+ // Simulate "Sync everything" being turned off, but all individual
+ // toggles left on.
+ std::string config =
+ GetConfiguration(/*extra_values=*/nullptr, CHOOSE_WHAT_TO_SYNC,
+ GetAllTypes(), std::string(), ENCRYPT_PASSWORDS);
+ base::ListValue list_args;
+ list_args.AppendString(kTestCallbackId);
+ list_args.AppendString(config);
+
+ // Only the registered types are selected.
+ EXPECT_CALL(*mock_sync_service_->GetMockUserSettings(),
+ SetSelectedTypes(/*sync_everything=*/false, registered_types));
+ handler_->HandleSetDatatypes(&list_args);
+}
+
TEST_F(PeopleHandlerTest, ShowSyncSetup) {
+ SigninUser();
+ CreatePeopleHandler();
ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsPassphraseRequired())
.WillByDefault(Return(false));
ON_CALL(*mock_sync_service_->GetMockUserSettings(),
@@ -835,6 +890,8 @@ TEST_F(PeopleHandlerTest, ShowSyncSetup) {
}
TEST_F(PeopleHandlerTest, ShowSetupSyncEverything) {
+ SigninUser();
+ CreatePeopleHandler();
ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsPassphraseRequired())
.WillByDefault(Return(false));
ON_CALL(*mock_sync_service_->GetMockUserSettings(),
@@ -863,6 +920,8 @@ TEST_F(PeopleHandlerTest, ShowSetupSyncEverything) {
}
TEST_F(PeopleHandlerTest, ShowSetupManuallySyncAll) {
+ SigninUser();
+ CreatePeopleHandler();
ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsPassphraseRequired())
.WillByDefault(Return(false));
ON_CALL(*mock_sync_service_->GetMockUserSettings(),
@@ -880,6 +939,8 @@ TEST_F(PeopleHandlerTest, ShowSetupManuallySyncAll) {
}
TEST_F(PeopleHandlerTest, ShowSetupSyncForAllTypesIndividually) {
+ SigninUser();
+ CreatePeopleHandler();
for (syncer::UserSelectableType type : GetAllTypes()) {
ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsPassphraseRequired())
.WillByDefault(Return(false));
@@ -911,6 +972,8 @@ TEST_F(PeopleHandlerTest, ShowSetupSyncForAllTypesIndividually) {
}
TEST_F(PeopleHandlerTest, ShowSetupOldGaiaPassphraseRequired) {
+ SigninUser();
+ CreatePeopleHandler();
ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsPassphraseRequired())
.WillByDefault(Return(true));
ON_CALL(*mock_sync_service_->GetMockUserSettings(), GetPassphraseType())
@@ -927,6 +990,8 @@ TEST_F(PeopleHandlerTest, ShowSetupOldGaiaPassphraseRequired) {
}
TEST_F(PeopleHandlerTest, ShowSetupCustomPassphraseRequired) {
+ SigninUser();
+ CreatePeopleHandler();
ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsPassphraseRequired())
.WillByDefault(Return(true));
ON_CALL(*mock_sync_service_->GetMockUserSettings(), GetPassphraseType())
@@ -943,8 +1008,10 @@ TEST_F(PeopleHandlerTest, ShowSetupCustomPassphraseRequired) {
}
TEST_F(PeopleHandlerTest, ShowSetupTrustedVaultKeysRequired) {
+ SigninUser();
+ CreatePeopleHandler();
ON_CALL(*mock_sync_service_->GetMockUserSettings(),
- IsTrustedVaultKeyRequiredForPreferredDataTypes())
+ IsTrustedVaultKeyRequired())
.WillByDefault(Return(true));
ON_CALL(*mock_sync_service_->GetMockUserSettings(), GetPassphraseType())
.WillByDefault(Return(syncer::PassphraseType::kTrustedVaultPassphrase));
@@ -958,11 +1025,11 @@ TEST_F(PeopleHandlerTest, ShowSetupTrustedVaultKeysRequired) {
CheckBool(dictionary, "passphraseRequired", false);
CheckBool(dictionary, "trustedVaultKeysRequired", true);
EXPECT_FALSE(dictionary->FindKey("enterPassphraseBody"));
- // TODO: See how to verify the appropriate action, once it's actually
- // implemented.
}
TEST_F(PeopleHandlerTest, ShowSetupEncryptAll) {
+ SigninUser();
+ CreatePeopleHandler();
ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsPassphraseRequired())
.WillByDefault(Return(false));
ON_CALL(*mock_sync_service_->GetMockUserSettings(),
@@ -982,6 +1049,8 @@ TEST_F(PeopleHandlerTest, ShowSetupEncryptAll) {
}
TEST_F(PeopleHandlerTest, ShowSetupEncryptAllDisallowed) {
+ SigninUser();
+ CreatePeopleHandler();
ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsPassphraseRequired())
.WillByDefault(Return(false));
ON_CALL(*mock_sync_service_->GetMockUserSettings(),
@@ -1002,6 +1071,8 @@ TEST_F(PeopleHandlerTest, ShowSetupEncryptAllDisallowed) {
}
TEST_F(PeopleHandlerTest, TurnOnEncryptAllDisallowed) {
+ SigninUser();
+ CreatePeopleHandler();
ON_CALL(*mock_sync_service_->GetMockUserSettings(),
IsPassphraseRequiredForPreferredDataTypes())
.WillByDefault(Return(false));
@@ -1033,6 +1104,8 @@ TEST_F(PeopleHandlerTest, TurnOnEncryptAllDisallowed) {
}
TEST_F(PeopleHandlerTest, DashboardClearWhileSettingsOpen_ConfirmSoon) {
+ SigninUser();
+ CreatePeopleHandler();
// Sync starts out fully enabled.
SetDefaultExpectationsForConfigPage();
@@ -1062,7 +1135,7 @@ TEST_F(PeopleHandlerTest, DashboardClearWhileSettingsOpen_ConfirmSoon) {
// SetSyncRequested(true) clears DISABLE_REASON_USER_CHOICE, and
// immediately starts initializing the engine.
ON_CALL(*mock_sync_service_, GetDisableReasons())
- .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NONE));
+ .WillByDefault(Return(syncer::SyncService::DisableReasonSet()));
ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsSyncRequested())
.WillByDefault(Return(true));
ON_CALL(*mock_sync_service_, GetTransportState())
@@ -1086,6 +1159,8 @@ TEST_F(PeopleHandlerTest, DashboardClearWhileSettingsOpen_ConfirmSoon) {
}
TEST_F(PeopleHandlerTest, DashboardClearWhileSettingsOpen_ConfirmLater) {
+ SigninUser();
+ CreatePeopleHandler();
// Sync starts out fully enabled.
SetDefaultExpectationsForConfigPage();
@@ -1128,7 +1203,7 @@ TEST_F(PeopleHandlerTest, DashboardClearWhileSettingsOpen_ConfirmLater) {
// SetSyncRequested(true) clears DISABLE_REASON_USER_CHOICE, and
// immediately starts initializing the engine.
ON_CALL(*mock_sync_service_, GetDisableReasons())
- .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NONE));
+ .WillByDefault(Return(syncer::SyncService::DisableReasonSet()));
ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsSyncRequested())
.WillByDefault(Return(true));
ON_CALL(*mock_sync_service_, GetTransportState())
@@ -1195,7 +1270,44 @@ TEST(PeopleHandlerDiceUnifiedConsentTest, StoredAccountsList) {
EXPECT_EQ("a@gmail.com", accounts_list[0].FindKey("email")->GetString());
EXPECT_EQ("b@gmail.com", accounts_list[1].FindKey("email")->GetString());
}
-
#endif // BUILDFLAG(ENABLE_DICE_SUPPORT)
+#if defined(OS_CHROMEOS)
+// Regression test for crash in guest mode. https://crbug.com/1040476
+TEST(PeopleHandlerGuestModeTest, GetStoredAccountsList) {
+ content::BrowserTaskEnvironment task_environment;
+ TestingProfile::Builder builder;
+ builder.SetGuestSession();
+ std::unique_ptr<Profile> profile = builder.Build();
+
+ PeopleHandler handler(profile.get());
+ base::Value accounts = handler.GetStoredAccountsList();
+ EXPECT_TRUE(accounts.GetList().empty());
+}
+
+TEST_F(PeopleHandlerTest, TurnOffSync) {
+ // Simulate a user who previously turned on sync.
+ identity_test_env()->MakePrimaryAccountAvailable("user@gmail.com");
+ ASSERT_TRUE(identity_manager()->HasPrimaryAccount(ConsentLevel::kSync));
+
+ CreatePeopleHandler();
+ handler_->HandleTurnOffSync(nullptr);
+ EXPECT_FALSE(identity_manager()->HasPrimaryAccount(ConsentLevel::kSync));
+ const base::DictionaryValue* status = ExpectSyncStatusChanged();
+ CheckBool(status, "signedIn", false);
+}
+
+TEST_F(PeopleHandlerTest, GetStoredAccountsList) {
+ // Chrome OS sets an unconsented primary account on login.
+ identity_test_env()->MakeUnconsentedPrimaryAccountAvailable("user@gmail.com");
+ ASSERT_FALSE(identity_manager()->HasPrimaryAccount(ConsentLevel::kSync));
+
+ CreatePeopleHandler();
+ base::Value accounts = handler_->GetStoredAccountsList();
+ base::Value::ListView accounts_list = accounts.GetList();
+ ASSERT_EQ(1u, accounts_list.size());
+ EXPECT_EQ("user@gmail.com", accounts_list[0].FindKey("email")->GetString());
+}
+#endif // defined(OS_CHROMEOS)
+
} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/profile_info_handler.cc b/chromium/chrome/browser/ui/webui/settings/profile_info_handler.cc
index 139f2034b19..922bfc02a41 100644
--- a/chromium/chrome/browser/ui/webui/settings/profile_info_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/profile_info_handler.cc
@@ -150,10 +150,7 @@ ProfileInfoHandler::GetAccountNameAndIcon() const {
if (g_browser_process->profile_manager()
->GetProfileAttributesStorage()
.GetProfileAttributesWithPath(profile_->GetPath(), &entry)) {
- name = base::UTF16ToUTF8(
- ProfileAttributesEntry::ShouldConcatenateGaiaAndProfileName()
- ? entry->GetLocalProfileName()
- : entry->GetName());
+ name = base::UTF16ToUTF8(entry->GetLocalProfileName());
// TODO(crbug.com/710660): return chrome://theme/IDR_PROFILE_AVATAR_*
// and update theme_source.cc to get high res avatar icons. This does less
// work here, sends less over IPC, and is more stable with returned results.
diff --git a/chromium/chrome/browser/ui/webui/settings/safe_browsing_handler.cc b/chromium/chrome/browser/ui/webui/settings/safe_browsing_handler.cc
new file mode 100644
index 00000000000..7403e565a5a
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/safe_browsing_handler.cc
@@ -0,0 +1,130 @@
+// Copyright 2020 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 "chrome/browser/ui/webui/settings/safe_browsing_handler.h"
+
+#include "components/prefs/pref_change_registrar.h"
+#include "components/prefs/pref_service.h"
+#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
+#include "components/safe_browsing/core/features.h"
+
+namespace settings {
+
+SafeBrowsingHandler::SafeBrowsingHandler(Profile* profile)
+ : profile_(profile) {}
+SafeBrowsingHandler::~SafeBrowsingHandler() = default;
+
+void SafeBrowsingHandler::RegisterMessages() {
+ web_ui()->RegisterMessageCallback(
+ "getSafeBrowsingRadioManagedState",
+ base::BindRepeating(
+ &SafeBrowsingHandler::HandleGetSafeBrowsingRadioManagedState,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "validateSafeBrowsingEnhanced",
+ base::BindRepeating(
+ &SafeBrowsingHandler::HandleValidateSafeBrowsingEnhanced,
+ base::Unretained(this)));
+}
+
+void SafeBrowsingHandler::HandleGetSafeBrowsingRadioManagedState(
+ const base::ListValue* args) {
+ AllowJavascript();
+ CHECK_EQ(1U, args->GetList().size());
+ std::string callback_id = args->GetList()[0].GetString();
+
+ auto state = GetSafeBrowsingRadioManagedState(profile_);
+
+ base::Value result(base::Value::Type::DICTIONARY);
+ // TODO(crbug.com/1063265): Move managed state functions out of site_settings.
+ result.SetKey(kSafeBrowsingEnhanced,
+ site_settings::GetValueForManagedState(state.enhanced));
+ result.SetKey(kSafeBrowsingStandard,
+ site_settings::GetValueForManagedState(state.standard));
+ result.SetKey(kSafeBrowsingDisabled,
+ site_settings::GetValueForManagedState(state.disabled));
+
+ ResolveJavascriptCallback(base::Value(callback_id), result);
+}
+
+void SafeBrowsingHandler::HandleValidateSafeBrowsingEnhanced(
+ const base::ListValue* args) {
+ // TODO(crbug.com/1074499) Remove this logic when Enhanced protection is
+ // considered stable.
+ if (!base::FeatureList::IsEnabled(safe_browsing::kEnhancedProtection))
+ profile_->GetPrefs()->SetBoolean(prefs::kSafeBrowsingEnhanced, false);
+}
+
+SafeBrowsingRadioManagedState
+SafeBrowsingHandler::GetSafeBrowsingRadioManagedState(Profile* profile) {
+ // Create a default managed state that is updated based on preferences.
+ SafeBrowsingRadioManagedState managed_state;
+
+ // Computing the effective Safe Browsing managed state requires inspecting
+ // three different preferences. It is possible that these may be in
+ // temporarily conflicting managed states. The enabled preference is always
+ // taken as the canonical source of management.
+ const PrefService::Preference* enabled_pref =
+ profile->GetPrefs()->FindPreference(prefs::kSafeBrowsingEnabled);
+ const bool enabled_enforced = !enabled_pref->IsUserModifiable();
+ const bool enabled_recommended =
+ (enabled_pref && enabled_pref->GetRecommendedValue());
+ const bool enabled_recommended_on =
+ enabled_recommended && enabled_pref->GetRecommendedValue()->GetBool();
+ const auto enabled_policy_indicator =
+ site_settings::GetPolicyIndicatorFromPref(enabled_pref);
+
+ // The enhanced preference may have a recommended setting. This only takes
+ // effect if the enabled preference also has a recommended setting.
+ const PrefService::Preference* enhanced_pref =
+ profile->GetPrefs()->FindPreference(prefs::kSafeBrowsingEnhanced);
+ const bool enhanced_recommended_on =
+ enhanced_pref->GetRecommendedValue() &&
+ enhanced_pref->GetRecommendedValue()->GetBool();
+
+ // A forcefully disabled reporting preference will disallow enhanced from
+ // being selected and thus it must also be considered.
+ const PrefService::Preference* reporting_pref =
+ profile->GetPrefs()->FindPreference(
+ prefs::kSafeBrowsingScoutReportingEnabled);
+ const bool reporting_on = reporting_pref->GetValue()->GetBool();
+ const bool reporting_enforced = !reporting_pref->IsUserModifiable();
+ const auto reporting_policy_indicator =
+ site_settings::GetPolicyIndicatorFromPref(reporting_pref);
+
+ if (!enabled_enforced && !enabled_recommended && !reporting_enforced) {
+ // No relevant policies are applied, return the default state.
+ return managed_state;
+ }
+ if (enabled_enforced) {
+ // All radio controls are managed.
+ managed_state.enhanced.disabled = true;
+ managed_state.enhanced.indicator = enabled_policy_indicator;
+ managed_state.standard.disabled = true;
+ managed_state.standard.indicator = enabled_policy_indicator;
+ managed_state.disabled.disabled = true;
+ managed_state.disabled.indicator = enabled_policy_indicator;
+ return managed_state;
+ }
+ if (enabled_recommended) {
+ if (enhanced_recommended_on) {
+ managed_state.enhanced.indicator = enabled_policy_indicator;
+ } else if (enabled_recommended_on) {
+ managed_state.standard.indicator = enabled_policy_indicator;
+ } else {
+ managed_state.disabled.indicator = enabled_policy_indicator;
+ }
+ return managed_state;
+ }
+ if (reporting_enforced && !reporting_on) {
+ // Disable enhanced protection when reporting has been enforced off.
+ managed_state.enhanced.disabled = true;
+ managed_state.enhanced.indicator = reporting_policy_indicator;
+ return managed_state;
+ }
+
+ return managed_state;
+}
+
+} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/safe_browsing_handler.h b/chromium/chrome/browser/ui/webui/settings/safe_browsing_handler.h
new file mode 100644
index 00000000000..4c27dae0c27
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/safe_browsing_handler.h
@@ -0,0 +1,62 @@
+// Copyright 2020 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 CHROME_BROWSER_UI_WEBUI_SETTINGS_SAFE_BROWSING_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_SAFE_BROWSING_HANDLER_H_
+
+#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+#include "chrome/browser/ui/webui/site_settings_helper.h"
+
+#include "chrome/browser/profiles/profile.h"
+
+namespace settings {
+
+constexpr char kSafeBrowsingEnhanced[] = "enhanced";
+constexpr char kSafeBrowsingStandard[] = "standard";
+constexpr char kSafeBrowsingDisabled[] = "disabled";
+
+struct SafeBrowsingRadioManagedState {
+ site_settings::ManagedState enhanced;
+ site_settings::ManagedState standard;
+ site_settings::ManagedState disabled;
+};
+
+// Settings page UI handler that provides representation of Safe Browsing
+// settings.
+class SafeBrowsingHandler : public SettingsPageUIHandler {
+ public:
+ explicit SafeBrowsingHandler(Profile* profile);
+ ~SafeBrowsingHandler() override;
+
+ // WebUIMessageHandler implementation.
+ void RegisterMessages() override;
+
+ // Calculate and return the current Safe Browsing radio buttons.
+ void HandleGetSafeBrowsingRadioManagedState(const base::ListValue* args);
+
+ // Confirm that the current Safe Browsing Enhanced preference is appropriate
+ // for the currently enabled features, updating it if required.
+ void HandleValidateSafeBrowsingEnhanced(const base::ListValue* args);
+
+ private:
+ friend class SafeBrowsingHandlerTest;
+ FRIEND_TEST_ALL_PREFIXES(SafeBrowsingHandlerTest, GenerateRadioManagedState);
+ FRIEND_TEST_ALL_PREFIXES(SafeBrowsingHandlerTest, ProvideRadioManagedState);
+
+ // SettingsPageUIHandler implementation.
+ void OnJavascriptAllowed() override {}
+ void OnJavascriptDisallowed() override {}
+
+ // Calculate the current Safe Browsing control state for the provided profile.
+ static SafeBrowsingRadioManagedState GetSafeBrowsingRadioManagedState(
+ Profile* profile);
+
+ Profile* profile_;
+
+ DISALLOW_COPY_AND_ASSIGN(SafeBrowsingHandler);
+};
+
+} // namespace settings
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_SAFE_BROWSING_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/safe_browsing_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/safe_browsing_handler_unittest.cc
new file mode 100644
index 00000000000..3065bc295e2
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/safe_browsing_handler_unittest.cc
@@ -0,0 +1,248 @@
+// Copyright 2020 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 "chrome/browser/ui/webui/settings/safe_browsing_handler.h"
+
+#include <memory>
+#include <string>
+
+#include "base/test/scoped_feature_list.h"
+#include "base/values.h"
+#include "chrome/test/base/chrome_render_view_host_test_harness.h"
+#include "chrome/test/base/testing_profile.h"
+#include "components/prefs/pref_service.h"
+#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
+#include "components/safe_browsing/core/features.h"
+#include "components/sync_preferences/testing_pref_service_syncable.h"
+#include "content/public/test/browser_task_environment.h"
+#include "content/public/test/test_web_ui.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace settings {
+
+class SafeBrowsingHandlerTest : public testing::Test {
+ public:
+ void SetUp() override {
+ handler_ = std::make_unique<SafeBrowsingHandler>(profile());
+ handler()->set_web_ui(web_ui());
+ handler()->AllowJavascript();
+ web_ui()->ClearTrackedCalls();
+ }
+
+ TestingProfile* profile() { return &profile_; }
+ content::TestWebUI* web_ui() { return &web_ui_; }
+ SafeBrowsingHandler* handler() { return handler_.get(); }
+
+ private:
+ content::BrowserTaskEnvironment task_environment_;
+ std::unique_ptr<SafeBrowsingHandler> handler_;
+ TestingProfile profile_;
+ content::TestWebUI web_ui_;
+};
+
+// All of the possible managed states for a boolean preference that can be
+// both enforced and recommended.
+// TODO(crbug.com/1063265): Remove duplication with site_settings_helper.
+enum class PrefSetting {
+ kEnforcedOff,
+ kEnforcedOn,
+ kRecommendedOff,
+ kRecommendedOn,
+ kNotSet,
+};
+
+// Possible preference sources supported by TestingPrefService.
+// TODO(crbug.com/1063265): Remove duplication with site_settings_helper.
+enum class PrefSource {
+ kExtension,
+ kDevicePolicy,
+ kRecommended,
+ kNone,
+};
+
+void AssertRadioManagedStateEqual(const SafeBrowsingRadioManagedState& a,
+ const SafeBrowsingRadioManagedState& b) {
+ ASSERT_EQ(a.enhanced.disabled, b.enhanced.disabled);
+ ASSERT_EQ(a.enhanced.indicator, b.enhanced.indicator);
+ ASSERT_EQ(a.standard.disabled, b.standard.disabled);
+ ASSERT_EQ(a.standard.indicator, b.standard.indicator);
+ ASSERT_EQ(a.disabled.disabled, b.disabled.disabled);
+ ASSERT_EQ(a.disabled.indicator, b.disabled.indicator);
+}
+
+struct RadioManagedStateTestCase {
+ PrefSetting safe_browsing_enhanced;
+ PrefSetting safe_browsing_enabled;
+ PrefSetting safe_browsing_reporting;
+ PrefSource preference_source;
+ SafeBrowsingRadioManagedState expected_result;
+};
+
+const std::vector<RadioManagedStateTestCase> test_cases = {
+ {PrefSetting::kNotSet,
+ PrefSetting::kNotSet,
+ PrefSetting::kNotSet,
+ PrefSource::kNone,
+ {{false, site_settings::PolicyIndicatorType::kNone},
+ {false, site_settings::PolicyIndicatorType::kNone},
+ {false, site_settings::PolicyIndicatorType::kNone}}},
+ {PrefSetting::kEnforcedOn,
+ PrefSetting::kEnforcedOn,
+ PrefSetting::kNotSet,
+ PrefSource::kExtension,
+ {{true, site_settings::PolicyIndicatorType::kExtension},
+ {true, site_settings::PolicyIndicatorType::kExtension},
+ {true, site_settings::PolicyIndicatorType::kExtension}}},
+ {PrefSetting::kEnforcedOff,
+ PrefSetting::kEnforcedOff,
+ PrefSetting::kNotSet,
+ PrefSource::kDevicePolicy,
+ {{true, site_settings::PolicyIndicatorType::kDevicePolicy},
+ {true, site_settings::PolicyIndicatorType::kDevicePolicy},
+ {true, site_settings::PolicyIndicatorType::kDevicePolicy}}},
+ {PrefSetting::kEnforcedOff,
+ PrefSetting::kEnforcedOn,
+ PrefSetting::kNotSet,
+ PrefSource::kExtension,
+ {{true, site_settings::PolicyIndicatorType::kExtension},
+ {true, site_settings::PolicyIndicatorType::kExtension},
+ {true, site_settings::PolicyIndicatorType::kExtension}}},
+ {PrefSetting::kRecommendedOn,
+ PrefSetting::kRecommendedOn,
+ PrefSetting::kNotSet,
+ PrefSource::kRecommended,
+ {{false, site_settings::PolicyIndicatorType::kRecommended},
+ {false, site_settings::PolicyIndicatorType::kNone},
+ {false, site_settings::PolicyIndicatorType::kNone}}},
+ {PrefSetting::kRecommendedOff,
+ PrefSetting::kRecommendedOn,
+ PrefSetting::kNotSet,
+ PrefSource::kRecommended,
+ {{false, site_settings::PolicyIndicatorType::kNone},
+ {false, site_settings::PolicyIndicatorType::kRecommended},
+ {false, site_settings::PolicyIndicatorType::kNone}}},
+ {PrefSetting::kRecommendedOff,
+ PrefSetting::kRecommendedOff,
+ PrefSetting::kNotSet,
+ PrefSource::kRecommended,
+ {{false, site_settings::PolicyIndicatorType::kNone},
+ {false, site_settings::PolicyIndicatorType::kNone},
+ {false, site_settings::PolicyIndicatorType::kRecommended}}},
+ {PrefSetting::kNotSet,
+ PrefSetting::kNotSet,
+ PrefSetting::kEnforcedOff,
+ PrefSource::kDevicePolicy,
+ {{true, site_settings::PolicyIndicatorType::kDevicePolicy},
+ {false, site_settings::PolicyIndicatorType::kNone},
+ {false, site_settings::PolicyIndicatorType::kNone}}}};
+
+void SetupTestConditions(TestingProfile* profile,
+ const RadioManagedStateTestCase& test_case) {
+ sync_preferences::TestingPrefServiceSyncable* prefs =
+ profile->GetTestingPrefService();
+ const std::map<const char*, PrefSetting> pref_to_setting = {
+ {prefs::kSafeBrowsingEnhanced, test_case.safe_browsing_enhanced},
+ {prefs::kSafeBrowsingEnabled, test_case.safe_browsing_enabled},
+ {prefs::kSafeBrowsingScoutReportingEnabled,
+ test_case.safe_browsing_reporting}};
+
+ for (const auto& pref_setting : pref_to_setting) {
+ if (pref_setting.second == PrefSetting::kNotSet) {
+ continue;
+ }
+ auto pref_value = std::make_unique<base::Value>(
+ pref_setting.second == PrefSetting::kRecommendedOn ||
+ pref_setting.second == PrefSetting::kEnforcedOn);
+ if (test_case.preference_source == PrefSource::kExtension) {
+ prefs->SetExtensionPref(pref_setting.first, std::move(pref_value));
+ } else if (test_case.preference_source == PrefSource::kDevicePolicy) {
+ prefs->SetManagedPref(pref_setting.first, std::move(pref_value));
+ } else if (test_case.preference_source == PrefSource::kRecommended) {
+ prefs->SetRecommendedPref(pref_setting.first, std::move(pref_value));
+ }
+ }
+}
+
+TEST_F(SafeBrowsingHandlerTest, GenerateRadioManagedState) {
+ int count = 0;
+ for (const auto& test_case : test_cases) {
+ TestingProfile profile;
+ SCOPED_TRACE(base::StringPrintf("Test case %d", count++));
+ SetupTestConditions(&profile, test_case);
+ AssertRadioManagedStateEqual(
+ handler()->GetSafeBrowsingRadioManagedState(&profile),
+ test_case.expected_result);
+ }
+}
+
+TEST_F(SafeBrowsingHandlerTest, ProvideRadioManagedState) {
+ // Test that the handler correctly wraps the generated result.
+ const std::string kNone = "none";
+ const std::string kDevicePolicy = "devicePolicy";
+ const std::string kCallbackId = "callback";
+ const std::vector<std::string> kRadioNames = {"enhanced", "standard",
+ "disabled"};
+
+ // Check that the default radio state is handled correctly.
+ base::ListValue get_args;
+ get_args.AppendString(kCallbackId);
+ handler()->HandleGetSafeBrowsingRadioManagedState(&get_args);
+ {
+ const content::TestWebUI::CallData& data = *web_ui()->call_data().back();
+ EXPECT_EQ("cr.webUIResponse", data.function_name());
+ EXPECT_EQ(kCallbackId, data.arg1()->GetString());
+ ASSERT_TRUE(data.arg2()->GetBool());
+ for (const auto& control_name : kRadioNames) {
+ auto* control_state = data.arg3()->FindPath(control_name);
+ ASSERT_FALSE(control_state->FindKey("disabled")->GetBool());
+ ASSERT_EQ(kNone, control_state->FindKey("indicator")->GetString());
+ }
+ }
+
+ // Create a fully managed state and check it is returned correctly.
+ sync_preferences::TestingPrefServiceSyncable* pref_service =
+ profile()->GetTestingPrefService();
+ pref_service->SetManagedPref(prefs::kSafeBrowsingEnhanced,
+ std::make_unique<base::Value>(true));
+ pref_service->SetManagedPref(prefs::kSafeBrowsingEnabled,
+ std::make_unique<base::Value>(true));
+
+ handler()->HandleGetSafeBrowsingRadioManagedState(&get_args);
+ {
+ const content::TestWebUI::CallData& data = *web_ui()->call_data().back();
+ EXPECT_EQ("cr.webUIResponse", data.function_name());
+ EXPECT_EQ(kCallbackId, data.arg1()->GetString());
+ ASSERT_TRUE(data.arg2()->GetBool());
+ for (const auto& control_name : kRadioNames) {
+ auto* control_state = data.arg3()->FindPath(control_name);
+ ASSERT_TRUE(control_state->FindKey("disabled")->GetBool());
+ ASSERT_EQ(kDevicePolicy,
+ control_state->FindKey("indicator")->GetString());
+ }
+ }
+}
+
+TEST_F(SafeBrowsingHandlerTest, ValidateSafeBrowsingPrefs) {
+ base::ListValue args;
+ base::test::ScopedFeatureList scoped_feature_list_;
+ sync_preferences::TestingPrefServiceSyncable* pref_service =
+ profile()->GetTestingPrefService();
+
+ pref_service->SetBoolean(prefs::kSafeBrowsingEnhanced, true);
+
+ // Ensure the preference is not changed when the Enhanced feature is enabled.
+ scoped_feature_list_.InitWithFeatures({safe_browsing::kEnhancedProtection},
+ {});
+ handler()->HandleValidateSafeBrowsingEnhanced(&args);
+ EXPECT_TRUE(pref_service->GetBoolean(prefs::kSafeBrowsingEnhanced));
+ scoped_feature_list_.Reset();
+
+ // Ensure the preference is disabled when the Enhanced feature is disabled.
+ scoped_feature_list_.InitWithFeatures({},
+ {safe_browsing::kEnhancedProtection});
+ handler()->HandleValidateSafeBrowsingEnhanced(&args);
+ EXPECT_FALSE(pref_service->GetBoolean(prefs::kSafeBrowsingEnhanced));
+}
+
+} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/safety_check_handler.cc b/chromium/chrome/browser/ui/webui/settings/safety_check_handler.cc
index be365ff4489..8e954398304 100644
--- a/chromium/chrome/browser/ui/webui/settings/safety_check_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/safety_check_handler.cc
@@ -5,23 +5,238 @@
#include "chrome/browser/ui/webui/settings/safety_check_handler.h"
#include "base/bind.h"
+#include "base/i18n/number_formatting.h"
+#include "base/metrics/histogram_functions.h"
+#include "base/metrics/user_metrics.h"
+#include "base/metrics/user_metrics_action.h"
+#include "base/strings/string16.h"
+#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
+#include "chrome/browser/extensions/api/passwords_private/passwords_private_delegate_factory.h"
+#include "chrome/browser/password_manager/bulk_leak_check_service_factory.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/channel_info.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/grit/chromium_strings.h"
+#include "chrome/grit/generated_resources.h"
+#include "components/prefs/pref_service.h"
+#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
+#include "components/strings/grit/components_strings.h"
+#include "components/version_info/version_info.h"
+#include "extensions/browser/extension_prefs_factory.h"
+#include "extensions/browser/extension_system.h"
+#include "extensions/common/extension_id.h"
+#include "ui/base/l10n/l10n_util.h"
+
+#if defined(OS_CHROMEOS)
+#include "ui/chromeos/devicetype_utils.h"
+#endif
+
+namespace {
+
+// Constants for communication with JS.
+constexpr char kUpdatesEvent[] = "safety-check-updates-status-changed";
+constexpr char kPasswordsEvent[] = "safety-check-passwords-status-changed";
+constexpr char kSafeBrowsingEvent[] =
+ "safety-check-safe-browsing-status-changed";
+constexpr char kExtensionsEvent[] = "safety-check-extensions-status-changed";
+constexpr char kPerformSafetyCheck[] = "performSafetyCheck";
+constexpr char kGetParentRanDisplayString[] = "getSafetyCheckRanDisplayString";
+constexpr char kNewState[] = "newState";
+constexpr char kDisplayString[] = "displayString";
+constexpr char kButtonString[] = "buttonString";
+constexpr char kPasswordsCompromised[] = "passwordsCompromised";
+constexpr char kExtensionsReenabledByUser[] = "extensionsReenabledByUser";
+constexpr char kExtensionsReenabledByAdmin[] = "extensionsReenabledByAdmin";
+
+// Converts the VersionUpdater::Status to the UpdateStatus enum to be passed
+// to the safety check frontend. Note: if the VersionUpdater::Status gets
+// changed, this will fail to compile. That is done intentionally to ensure
+// that the states of the safety check are always in sync with the
+// VersionUpdater ones.
+SafetyCheckHandler::UpdateStatus ConvertToUpdateStatus(
+ VersionUpdater::Status status) {
+ switch (status) {
+ case VersionUpdater::CHECKING:
+ return SafetyCheckHandler::UpdateStatus::kChecking;
+ case VersionUpdater::UPDATED:
+ return SafetyCheckHandler::UpdateStatus::kUpdated;
+ case VersionUpdater::UPDATING:
+ return SafetyCheckHandler::UpdateStatus::kUpdating;
+ case VersionUpdater::NEED_PERMISSION_TO_UPDATE:
+ case VersionUpdater::NEARLY_UPDATED:
+ return SafetyCheckHandler::UpdateStatus::kRelaunch;
+ case VersionUpdater::DISABLED_BY_ADMIN:
+ return SafetyCheckHandler::UpdateStatus::kDisabledByAdmin;
+ // The disabled state can only be returned on non Chrome-branded browsers.
+ case VersionUpdater::DISABLED:
+ return SafetyCheckHandler::UpdateStatus::kUnknown;
+ case VersionUpdater::FAILED:
+ case VersionUpdater::FAILED_CONNECTION_TYPE_DISALLOWED:
+ return SafetyCheckHandler::UpdateStatus::kFailed;
+ case VersionUpdater::FAILED_OFFLINE:
+ return SafetyCheckHandler::UpdateStatus::kFailedOffline;
+ }
+}
+} // namespace
SafetyCheckHandler::SafetyCheckHandler() = default;
SafetyCheckHandler::~SafetyCheckHandler() = default;
void SafetyCheckHandler::PerformSafetyCheck() {
- version_updater_.reset(VersionUpdater::Create(web_ui()->GetWebContents()));
- CheckUpdates(version_updater_.get(),
- base::Bind(&SafetyCheckHandler::OnUpdateCheckResult,
- base::Unretained(this)));
+ AllowJavascript();
+
+ if (!version_updater_) {
+ version_updater_.reset(VersionUpdater::Create(web_ui()->GetWebContents()));
+ }
+ DCHECK(version_updater_);
+ CheckUpdates();
+
+ CheckSafeBrowsing();
+
+ if (!leak_service_) {
+ leak_service_ = BulkLeakCheckServiceFactory::GetForProfile(
+ Profile::FromWebUI(web_ui()));
+ }
+ DCHECK(leak_service_);
+ if (!passwords_delegate_) {
+ passwords_delegate_ =
+ extensions::PasswordsPrivateDelegateFactory::GetForBrowserContext(
+ Profile::FromWebUI(web_ui()), true);
+ }
+ DCHECK(passwords_delegate_);
+ CheckPasswords();
+
+ if (!extension_prefs_) {
+ extension_prefs_ = extensions::ExtensionPrefsFactory::GetForBrowserContext(
+ Profile::FromWebUI(web_ui()));
+ }
+ DCHECK(extension_prefs_);
+ if (!extension_service_) {
+ extension_service_ =
+ extensions::ExtensionSystem::Get(Profile::FromWebUI(web_ui()))
+ ->extension_service();
+ }
+ DCHECK(extension_service_);
+ CheckExtensions();
}
-void SafetyCheckHandler::CheckUpdates(
- VersionUpdater* version_updater,
- const VersionUpdater::StatusCallback& update_callback) {
- version_updater->CheckForUpdate(update_callback,
- VersionUpdater::PromoteCallback());
+SafetyCheckHandler::SafetyCheckHandler(
+ std::unique_ptr<VersionUpdater> version_updater,
+ password_manager::BulkLeakCheckService* leak_service,
+ extensions::PasswordsPrivateDelegate* passwords_delegate,
+ extensions::ExtensionPrefs* extension_prefs,
+ extensions::ExtensionServiceInterface* extension_service)
+ : version_updater_(std::move(version_updater)),
+ leak_service_(leak_service),
+ passwords_delegate_(passwords_delegate),
+ extension_prefs_(extension_prefs),
+ extension_service_(extension_service) {}
+
+void SafetyCheckHandler::HandlePerformSafetyCheck(const base::ListValue* args) {
+ PerformSafetyCheck();
+}
+
+void SafetyCheckHandler::HandleGetParentRanDisplayString(
+ const base::ListValue* args) {
+ const base::Value* callback_id;
+ double timestampRanDouble;
+ CHECK(args->Get(0, &callback_id));
+ CHECK(args->GetDouble(1, &timestampRanDouble));
+
+ ResolveJavascriptCallback(
+ *callback_id, base::Value(GetStringForParentRan(timestampRanDouble)));
+}
+
+void SafetyCheckHandler::CheckUpdates() {
+ // Usage of base::Unretained(this) is safe, because we own `version_updater_`.
+ version_updater_->CheckForUpdate(
+ base::Bind(&SafetyCheckHandler::OnUpdateCheckResult,
+ base::Unretained(this)),
+ VersionUpdater::PromoteCallback());
+}
+
+void SafetyCheckHandler::CheckSafeBrowsing() {
+ PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs();
+ const PrefService::Preference* pref =
+ pref_service->FindPreference(prefs::kSafeBrowsingEnabled);
+ SafeBrowsingStatus status;
+ if (pref_service->GetBoolean(prefs::kSafeBrowsingEnabled)) {
+ status = SafeBrowsingStatus::kEnabled;
+ } else if (pref->IsManaged()) {
+ status = SafeBrowsingStatus::kDisabledByAdmin;
+ } else if (pref->IsExtensionControlled()) {
+ status = SafeBrowsingStatus::kDisabledByExtension;
+ } else {
+ status = SafeBrowsingStatus::kDisabled;
+ }
+ OnSafeBrowsingCheckResult(status);
+}
+
+void SafetyCheckHandler::CheckPasswords() {
+ // Remove |this| as an existing observer for BulkLeakCheck if it is
+ // registered. This takes care of an edge case when safety check starts twice
+ // on the same page. Normally this should not happen, but if it does, the
+ // browser should not crash.
+ observed_leak_check_.RemoveAll();
+ observed_leak_check_.Add(leak_service_);
+ passwords_delegate_->StartPasswordCheck(base::BindOnce(
+ &SafetyCheckHandler::OnStateChanged, weak_ptr_factory_.GetWeakPtr()));
+}
+
+void SafetyCheckHandler::CheckExtensions() {
+ extensions::ExtensionIdList extensions;
+ extension_prefs_->GetExtensions(&extensions);
+ int blocklisted = 0;
+ int reenabled_by_user = 0;
+ int reenabled_by_admin = 0;
+ for (auto extension_id : extensions) {
+ extensions::BlacklistState state =
+ extension_prefs_->GetExtensionBlacklistState(extension_id);
+ if (state == extensions::BLACKLISTED_UNKNOWN) {
+ // If any of the extensions are in the unknown blacklist state, that means
+ // there was an error the last time the blacklist was fetched. That means
+ // the results cannot be relied upon.
+ OnExtensionsCheckResult(ExtensionsStatus::kError, Blocklisted(0),
+ ReenabledUser(0), ReenabledAdmin(0));
+ return;
+ }
+ if (state == extensions::NOT_BLACKLISTED) {
+ continue;
+ }
+ ++blocklisted;
+ if (!extension_service_->IsExtensionEnabled(extension_id)) {
+ continue;
+ }
+ if (extension_service_->UserCanDisableInstalledExtension(extension_id)) {
+ ++reenabled_by_user;
+ } else {
+ ++reenabled_by_admin;
+ }
+ }
+ if (blocklisted == 0) {
+ OnExtensionsCheckResult(ExtensionsStatus::kNoneBlocklisted, Blocklisted(0),
+ ReenabledUser(0), ReenabledAdmin(0));
+ } else if (reenabled_by_user == 0 && reenabled_by_admin == 0) {
+ OnExtensionsCheckResult(ExtensionsStatus::kBlocklistedAllDisabled,
+ Blocklisted(blocklisted), ReenabledUser(0),
+ ReenabledAdmin(0));
+ } else if (reenabled_by_user > 0 && reenabled_by_admin == 0) {
+ OnExtensionsCheckResult(ExtensionsStatus::kBlocklistedReenabledAllByUser,
+ Blocklisted(blocklisted),
+ ReenabledUser(reenabled_by_user),
+ ReenabledAdmin(0));
+ } else if (reenabled_by_admin > 0 && reenabled_by_user == 0) {
+ OnExtensionsCheckResult(ExtensionsStatus::kBlocklistedReenabledAllByAdmin,
+ Blocklisted(blocklisted), ReenabledUser(0),
+ ReenabledAdmin(reenabled_by_admin));
+ } else {
+ OnExtensionsCheckResult(ExtensionsStatus::kBlocklistedReenabledSomeByUser,
+ Blocklisted(blocklisted),
+ ReenabledUser(reenabled_by_user),
+ ReenabledAdmin(reenabled_by_admin));
+ }
}
void SafetyCheckHandler::OnUpdateCheckResult(VersionUpdater::Status status,
@@ -30,5 +245,370 @@ void SafetyCheckHandler::OnUpdateCheckResult(VersionUpdater::Status status,
const std::string& version,
int64_t update_size,
const base::string16& message) {
- NOTIMPLEMENTED();
+ UpdateStatus update_status = ConvertToUpdateStatus(status);
+ base::DictionaryValue event;
+ event.SetIntKey(kNewState,
+ static_cast<int>(update_status != UpdateStatus::kUnknown
+ ? update_status
+ : UpdateStatus::kFailedOffline));
+ event.SetStringKey(kDisplayString, GetStringForUpdates(update_status));
+ FireWebUIListener(kUpdatesEvent, event);
+ if (update_status != UpdateStatus::kChecking) {
+ base::UmaHistogramEnumeration("Settings.SafetyCheck.UpdatesResult",
+ update_status);
+ }
+}
+
+void SafetyCheckHandler::OnSafeBrowsingCheckResult(
+ SafetyCheckHandler::SafeBrowsingStatus status) {
+ base::DictionaryValue event;
+ event.SetIntKey(kNewState, static_cast<int>(status));
+ event.SetStringKey(kDisplayString, GetStringForSafeBrowsing(status));
+ FireWebUIListener(kSafeBrowsingEvent, event);
+ if (status != SafeBrowsingStatus::kChecking) {
+ base::UmaHistogramEnumeration("Settings.SafetyCheck.SafeBrowsingResult",
+ status);
+ }
+}
+
+void SafetyCheckHandler::OnPasswordsCheckResult(PasswordsStatus status,
+ Compromised compromised,
+ Done done,
+ Total total) {
+ base::DictionaryValue event;
+ event.SetIntKey(kNewState, static_cast<int>(status));
+ if (status == PasswordsStatus::kCompromisedExist) {
+ event.SetIntKey(kPasswordsCompromised, compromised.value());
+ event.SetStringKey(
+ kButtonString,
+ l10n_util::GetPluralStringFUTF16(
+ IDS_SETTINGS_SAFETY_CHECK_PASSWORDS_BUTTON, compromised.value()));
+ }
+ event.SetStringKey(kDisplayString,
+ GetStringForPasswords(status, compromised, done, total));
+ FireWebUIListener(kPasswordsEvent, event);
+ if (status != PasswordsStatus::kChecking) {
+ base::UmaHistogramEnumeration("Settings.SafetyCheck.PasswordsResult",
+ status);
+ }
+}
+
+void SafetyCheckHandler::OnExtensionsCheckResult(
+ ExtensionsStatus status,
+ Blocklisted blocklisted,
+ ReenabledUser reenabled_user,
+ ReenabledAdmin reenabled_admin) {
+ base::DictionaryValue event;
+ event.SetIntKey(kNewState, static_cast<int>(status));
+ if (status == ExtensionsStatus::kBlocklistedReenabledAllByUser ||
+ status == ExtensionsStatus::kBlocklistedReenabledSomeByUser) {
+ event.SetIntKey(kExtensionsReenabledByUser, reenabled_user.value());
+ }
+ if (status == ExtensionsStatus::kBlocklistedReenabledAllByAdmin ||
+ status == ExtensionsStatus::kBlocklistedReenabledSomeByUser) {
+ event.SetIntKey(kExtensionsReenabledByAdmin, reenabled_admin.value());
+ }
+ event.SetStringKey(kDisplayString,
+ GetStringForExtensions(status, Blocklisted(blocklisted),
+ reenabled_user, reenabled_admin));
+ FireWebUIListener(kExtensionsEvent, event);
+ if (status != ExtensionsStatus::kChecking) {
+ base::UmaHistogramEnumeration("Settings.SafetyCheck.ExtensionsResult",
+ status);
+ }
+}
+
+base::string16 SafetyCheckHandler::GetStringForUpdates(UpdateStatus status) {
+ switch (status) {
+ case UpdateStatus::kChecking:
+ return l10n_util::GetStringUTF16(IDS_SETTINGS_SAFETY_CHECK_RUNNING);
+ case UpdateStatus::kUpdated:
+#if defined(OS_CHROMEOS)
+ return ui::SubstituteChromeOSDeviceType(IDS_SETTINGS_UPGRADE_UP_TO_DATE);
+#else
+ return l10n_util::GetStringUTF16(IDS_SETTINGS_UPGRADE_UP_TO_DATE);
+#endif
+ case UpdateStatus::kUpdating:
+ return l10n_util::GetStringUTF16(IDS_SETTINGS_UPGRADE_UPDATING);
+ case UpdateStatus::kRelaunch:
+ return l10n_util::GetStringUTF16(
+ IDS_SETTINGS_UPGRADE_SUCCESSFUL_RELAUNCH);
+ case UpdateStatus::kDisabledByAdmin:
+ return l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_SAFETY_CHECK_UPDATES_DISABLED_BY_ADMIN,
+ base::ASCIIToUTF16(chrome::kWhoIsMyAdministratorHelpURL));
+ case UpdateStatus::kFailedOffline:
+ return l10n_util::GetStringUTF16(
+ IDS_SETTINGS_SAFETY_CHECK_UPDATES_FAILED_OFFLINE);
+ case UpdateStatus::kFailed:
+ return l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_SAFETY_CHECK_UPDATES_FAILED,
+ base::ASCIIToUTF16(chrome::kChromeFixUpdateProblems));
+ case UpdateStatus::kUnknown:
+ return l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_ABOUT_PAGE_BROWSER_VERSION,
+ base::UTF8ToUTF16(version_info::GetVersionNumber()),
+ l10n_util::GetStringUTF16(version_info::IsOfficialBuild()
+ ? IDS_VERSION_UI_OFFICIAL
+ : IDS_VERSION_UI_UNOFFICIAL),
+ base::UTF8ToUTF16(chrome::GetChannelName()),
+ l10n_util::GetStringUTF16(sizeof(void*) == 8 ? IDS_VERSION_UI_64BIT
+ : IDS_VERSION_UI_32BIT));
+ }
+}
+
+base::string16 SafetyCheckHandler::GetStringForSafeBrowsing(
+ SafeBrowsingStatus status) {
+ switch (status) {
+ case SafeBrowsingStatus::kChecking:
+ return l10n_util::GetStringUTF16(IDS_SETTINGS_SAFETY_CHECK_RUNNING);
+ case SafeBrowsingStatus::kEnabled:
+ return l10n_util::GetStringUTF16(
+ IDS_SETTINGS_SAFETY_CHECK_SAFE_BROWSING_ENABLED);
+ case SafeBrowsingStatus::kDisabled:
+ return l10n_util::GetStringUTF16(
+ IDS_SETTINGS_SAFETY_CHECK_SAFE_BROWSING_DISABLED);
+ case SafeBrowsingStatus::kDisabledByAdmin:
+ return l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_SAFETY_CHECK_SAFE_BROWSING_DISABLED_BY_ADMIN,
+ base::ASCIIToUTF16(chrome::kWhoIsMyAdministratorHelpURL));
+ case SafeBrowsingStatus::kDisabledByExtension:
+ return l10n_util::GetStringUTF16(
+ IDS_SETTINGS_SAFETY_CHECK_SAFE_BROWSING_DISABLED_BY_EXTENSION);
+ }
+}
+
+base::string16 SafetyCheckHandler::GetStringForPasswords(
+ PasswordsStatus status,
+ Compromised compromised,
+ Done done,
+ Total total) {
+ const base::string16 short_product_name =
+ l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME);
+ switch (status) {
+ case PasswordsStatus::kChecking: {
+ // Unable to get progress for some reason.
+ if (total.value() == 0) {
+ return l10n_util::GetStringUTF16(IDS_SETTINGS_SAFETY_CHECK_RUNNING);
+ }
+ return l10n_util::GetStringFUTF16(IDS_SETTINGS_CHECK_PASSWORDS_PROGRESS,
+ base::FormatNumber(done.value()),
+ base::FormatNumber(total.value()));
+ }
+ case PasswordsStatus::kSafe:
+ return l10n_util::GetPluralStringFUTF16(
+ IDS_SETTINGS_COMPROMISED_PASSWORDS_COUNT, 0);
+ case PasswordsStatus::kCompromisedExist:
+ return l10n_util::GetPluralStringFUTF16(
+ IDS_SETTINGS_COMPROMISED_PASSWORDS_COUNT, compromised.value());
+ case PasswordsStatus::kOffline:
+ return l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_CHECK_PASSWORDS_ERROR_OFFLINE, short_product_name);
+ case PasswordsStatus::kNoPasswords:
+ return l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_CHECK_PASSWORDS_ERROR_NO_PASSWORDS, short_product_name);
+ case PasswordsStatus::kSignedOut:
+ return l10n_util::GetStringUTF16(
+ IDS_SETTINGS_SAFETY_CHECK_PASSWORDS_SIGNED_OUT);
+ case PasswordsStatus::kQuotaLimit:
+ return l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_CHECK_PASSWORDS_ERROR_QUOTA_LIMIT, short_product_name);
+ case PasswordsStatus::kError:
+ return l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_CHECK_PASSWORDS_ERROR_GENERIC, short_product_name);
+ }
+}
+
+base::string16 SafetyCheckHandler::GetStringForExtensions(
+ ExtensionsStatus status,
+ Blocklisted blocklisted,
+ ReenabledUser reenabled_user,
+ ReenabledAdmin reenabled_admin) {
+ switch (status) {
+ case ExtensionsStatus::kChecking:
+ return l10n_util::GetStringUTF16(IDS_SETTINGS_SAFETY_CHECK_RUNNING);
+ case ExtensionsStatus::kError:
+ return l10n_util::GetStringUTF16(
+ IDS_SETTINGS_SAFETY_CHECK_EXTENSIONS_ERROR);
+ case ExtensionsStatus::kNoneBlocklisted:
+ return l10n_util::GetStringUTF16(
+ IDS_SETTINGS_SAFETY_CHECK_EXTENSIONS_SAFE);
+ case ExtensionsStatus::kBlocklistedAllDisabled:
+ return l10n_util::GetPluralStringFUTF16(
+ IDS_SETTINGS_SAFETY_CHECK_EXTENSIONS_BLOCKLISTED_OFF,
+ blocklisted.value());
+ case ExtensionsStatus::kBlocklistedReenabledAllByUser:
+ return l10n_util::GetPluralStringFUTF16(
+ IDS_SETTINGS_SAFETY_CHECK_EXTENSIONS_BLOCKLISTED_ON_USER,
+ reenabled_user.value());
+ case ExtensionsStatus::kBlocklistedReenabledSomeByUser:
+ // TODO(crbug/1060625): Make string concatenation with a period
+ // internationalized (see go/i18n-concatenation).
+ return l10n_util::GetPluralStringFUTF16(
+ IDS_SETTINGS_SAFETY_CHECK_EXTENSIONS_BLOCKLISTED_ON_USER,
+ reenabled_user.value()) +
+ base::ASCIIToUTF16(". ") +
+ l10n_util::GetPluralStringFUTF16(
+ IDS_SETTINGS_SAFETY_CHECK_EXTENSIONS_BLOCKLISTED_ON_ADMIN,
+ reenabled_admin.value()) +
+ base::ASCIIToUTF16(".");
+ case ExtensionsStatus::kBlocklistedReenabledAllByAdmin:
+ return l10n_util::GetPluralStringFUTF16(
+ IDS_SETTINGS_SAFETY_CHECK_EXTENSIONS_BLOCKLISTED_ON_ADMIN,
+ reenabled_admin.value());
+ }
+}
+
+base::string16 SafetyCheckHandler::GetStringForParentRan(double timestamp_ran) {
+ return SafetyCheckHandler::GetStringForParentRan(timestamp_ran,
+ base::Time::Now());
+}
+
+base::string16 SafetyCheckHandler::GetStringForParentRan(
+ double timestamp_ran,
+ base::Time system_time) {
+ const base::Time timeRan = base::Time::FromJsTime(timestamp_ran);
+ base::Time::Exploded timeRanExploded;
+ timeRan.LocalExplode(&timeRanExploded);
+
+ base::Time::Exploded systemTimeExploded;
+ system_time.LocalExplode(&systemTimeExploded);
+
+ const base::Time timeYesterday = system_time - base::TimeDelta::FromDays(1);
+ base::Time::Exploded timeYesterdayExploded;
+ timeYesterday.LocalExplode(&timeYesterdayExploded);
+
+ const auto timeDiff = system_time - timeRan;
+ if (timeRanExploded.year == systemTimeExploded.year &&
+ timeRanExploded.month == systemTimeExploded.month &&
+ timeRanExploded.day_of_month == systemTimeExploded.day_of_month) {
+ // Safety check ran today.
+ const int timeDiffInMinutes = timeDiff.InMinutes();
+ if (timeDiffInMinutes == 0) {
+ return l10n_util::GetStringUTF16(
+ IDS_SETTINGS_SAFETY_CHECK_PARENT_PRIMARY_LABEL_AFTER);
+ } else if (timeDiffInMinutes < 60) {
+ return l10n_util::GetPluralStringFUTF16(
+ IDS_SETTINGS_SAFETY_CHECK_PARENT_PRIMARY_LABEL_AFTER_MINS,
+ timeDiffInMinutes);
+ } else {
+ return l10n_util::GetPluralStringFUTF16(
+ IDS_SETTINGS_SAFETY_CHECK_PARENT_PRIMARY_LABEL_AFTER_HOURS,
+ timeDiffInMinutes / 60);
+ }
+ } else if (timeRanExploded.year == timeYesterdayExploded.year &&
+ timeRanExploded.month == timeYesterdayExploded.month &&
+ timeRanExploded.day_of_month ==
+ timeYesterdayExploded.day_of_month) {
+ // Safety check ran yesterday.
+ return l10n_util::GetStringUTF16(
+ IDS_SETTINGS_SAFETY_CHECK_PARENT_PRIMARY_LABEL_AFTER_YESTERDAY);
+ } else {
+ // Safety check ran longer ago than yesterday.
+ // TODO(crbug.com/1015841): While a minor issue, this is not be the ideal
+ // way to calculate the days passed since safety check ran. For example,
+ // <48 h might still be 2 days ago.
+ const int timeDiffInDays = timeDiff.InDays();
+ return l10n_util::GetPluralStringFUTF16(
+ IDS_SETTINGS_SAFETY_CHECK_PARENT_PRIMARY_LABEL_AFTER_DAYS,
+ timeDiffInDays);
+ }
+}
+
+void SafetyCheckHandler::DetermineIfNoPasswordsOrSafe(
+ const std::vector<extensions::api::passwords_private::PasswordUiEntry>&
+ passwords) {
+ OnPasswordsCheckResult(passwords.empty() ? PasswordsStatus::kNoPasswords
+ : PasswordsStatus::kSafe,
+ Compromised(0), Done(0), Total(0));
+}
+
+void SafetyCheckHandler::OnStateChanged(
+ password_manager::BulkLeakCheckService::State state) {
+ using password_manager::BulkLeakCheckService;
+ switch (state) {
+ case BulkLeakCheckService::State::kIdle:
+ case BulkLeakCheckService::State::kCanceled: {
+ size_t num_compromised =
+ passwords_delegate_->GetCompromisedCredentials().size();
+ if (num_compromised == 0) {
+ passwords_delegate_->GetSavedPasswordsList(
+ base::BindOnce(&SafetyCheckHandler::DetermineIfNoPasswordsOrSafe,
+ base::Unretained(this)));
+ } else {
+ OnPasswordsCheckResult(PasswordsStatus::kCompromisedExist,
+ Compromised(num_compromised), Done(0), Total(0));
+ }
+ break;
+ }
+ case BulkLeakCheckService::State::kRunning:
+ OnPasswordsCheckResult(PasswordsStatus::kChecking, Compromised(0),
+ Done(0), Total(0));
+ // Non-terminal state, so nothing else needs to be done.
+ return;
+ case BulkLeakCheckService::State::kSignedOut:
+ OnPasswordsCheckResult(PasswordsStatus::kSignedOut, Compromised(0),
+ Done(0), Total(0));
+ break;
+ case BulkLeakCheckService::State::kNetworkError:
+ OnPasswordsCheckResult(PasswordsStatus::kOffline, Compromised(0), Done(0),
+ Total(0));
+ break;
+ case BulkLeakCheckService::State::kQuotaLimit:
+ OnPasswordsCheckResult(PasswordsStatus::kQuotaLimit, Compromised(0),
+ Done(0), Total(0));
+ break;
+ case BulkLeakCheckService::State::kTokenRequestFailure:
+ case BulkLeakCheckService::State::kHashingFailure:
+ case BulkLeakCheckService::State::kServiceError:
+ OnPasswordsCheckResult(PasswordsStatus::kError, Compromised(0), Done(0),
+ Total(0));
+ break;
+ }
+
+ // Stop observing the leak service in all terminal states, if it's still being
+ // observed.
+ observed_leak_check_.RemoveAll();
+}
+
+void SafetyCheckHandler::OnCredentialDone(
+ const password_manager::LeakCheckCredential& credential,
+ password_manager::IsLeaked is_leaked) {
+ extensions::api::passwords_private::PasswordCheckStatus status =
+ passwords_delegate_->GetPasswordCheckStatus();
+ // Send progress updates only if the check is still running.
+ if (status.state ==
+ extensions::api::passwords_private::PASSWORD_CHECK_STATE_RUNNING &&
+ status.already_processed && status.remaining_in_queue) {
+ Done done = Done(*(status.already_processed));
+ Total total = Total(*(status.remaining_in_queue) + done.value());
+ OnPasswordsCheckResult(PasswordsStatus::kChecking, Compromised(0), done,
+ total);
+ }
+}
+
+void SafetyCheckHandler::OnJavascriptAllowed() {}
+
+void SafetyCheckHandler::OnJavascriptDisallowed() {
+ // Remove |this| as an observer for BulkLeakCheck. This takes care of an edge
+ // case when the page is reloaded while the password check is in progress and
+ // another safety check is started. Otherwise |observed_leak_check_|
+ // automatically calls RemoveAll() on destruction.
+ observed_leak_check_.RemoveAll();
+ // Destroy the version updater to prevent getting a callback and firing a
+ // WebUI event, which would cause a crash.
+ version_updater_.reset();
+}
+
+void SafetyCheckHandler::RegisterMessages() {
+ // Usage of base::Unretained(this) is safe, because web_ui() owns `this` and
+ // won't release ownership until destruction.
+ web_ui()->RegisterMessageCallback(
+ kPerformSafetyCheck,
+ base::BindRepeating(&SafetyCheckHandler::HandlePerformSafetyCheck,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ kGetParentRanDisplayString,
+ base::BindRepeating(&SafetyCheckHandler::HandleGetParentRanDisplayString,
+ base::Unretained(this)));
}
diff --git a/chromium/chrome/browser/ui/webui/settings/safety_check_handler.h b/chromium/chrome/browser/ui/webui/settings/safety_check_handler.h
index 6268c712010..0680927e4c8 100644
--- a/chromium/chrome/browser/ui/webui/settings/safety_check_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/safety_check_handler.h
@@ -13,13 +13,75 @@
#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
+#include "base/scoped_observer.h"
+#include "base/util/type_safety/strong_alias.h"
+#include "chrome/browser/extensions/api/passwords_private/passwords_private_delegate.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/ui/webui/help/version_updater.h"
#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+#include "components/password_manager/core/browser/bulk_leak_check_service.h"
+#include "extensions/browser/extension_prefs.h"
+#include "extensions/browser/extension_registry.h"
-// Settings page UI handler that checks four areas of browser safety: browser
-// updates, password leaks, malicious extensions, and unwanted software.
-class SafetyCheckHandler : public settings::SettingsPageUIHandler {
+// Settings page UI handler that checks four areas of browser safety:
+// browser updates, password leaks, malicious extensions, and unwanted
+// software.
+class SafetyCheckHandler
+ : public settings::SettingsPageUIHandler,
+ public password_manager::BulkLeakCheckService::Observer {
public:
+ // The following enums represent the state of each component of the safety
+ // check and should be kept in sync with the JS frontend
+ // (safety_check_browser_proxy.js) and |SafetyCheck*| metrics enums in
+ // enums.xml.
+ enum class UpdateStatus {
+ kChecking = 0,
+ kUpdated = 1,
+ kUpdating = 2,
+ kRelaunch = 3,
+ kDisabledByAdmin = 4,
+ kFailedOffline = 5,
+ kFailed = 6,
+ // Non-Google branded browsers cannot check for updates using
+ // VersionUpdater.
+ kUnknown = 7,
+ // New enum values must go above here.
+ kMaxValue = kUnknown,
+ };
+ enum class SafeBrowsingStatus {
+ kChecking = 0,
+ kEnabled = 1,
+ kDisabled = 2,
+ kDisabledByAdmin = 3,
+ kDisabledByExtension = 4,
+ // New enum values must go above here.
+ kMaxValue = kDisabledByExtension,
+ };
+ enum class PasswordsStatus {
+ kChecking = 0,
+ kSafe = 1,
+ kCompromisedExist = 2,
+ kOffline = 3,
+ kNoPasswords = 4,
+ kSignedOut = 5,
+ kQuotaLimit = 6,
+ kError = 7,
+ // New enum values must go above here.
+ kMaxValue = kError,
+ };
+ enum class ExtensionsStatus {
+ kChecking = 0,
+ kError = 1,
+ kNoneBlocklisted = 2,
+ kBlocklistedAllDisabled = 3,
+ kBlocklistedReenabledAllByUser = 4,
+ // In this case, at least one of the extensions was re-enabled by admin.
+ kBlocklistedReenabledSomeByUser = 5,
+ kBlocklistedReenabledAllByAdmin = 6,
+ // New enum values must go above here.
+ kMaxValue = kBlocklistedReenabledAllByAdmin,
+ };
+
SafetyCheckHandler();
~SafetyCheckHandler() override;
@@ -28,18 +90,57 @@ class SafetyCheckHandler : public settings::SettingsPageUIHandler {
// should only be called as a result of an explicit user action.
void PerformSafetyCheck();
- // Each triggers a corresponding check and calls the provided callback on
- // completion.
- void CheckUpdates(VersionUpdater* updater,
- const VersionUpdater::StatusCallback& update_callback);
+ // Constructs the 'safety check ran' display string by how long ago safety
+ // check ran.
+ base::string16 GetStringForParentRan(double timestamp_ran);
+ base::string16 GetStringForParentRan(double timestamp_ran,
+ base::Time systemTime);
+
+ protected:
+ SafetyCheckHandler(std::unique_ptr<VersionUpdater> version_updater,
+ password_manager::BulkLeakCheckService* leak_service,
+ extensions::PasswordsPrivateDelegate* passwords_delegate,
+ extensions::ExtensionPrefs* extension_prefs,
+ extensions::ExtensionServiceInterface* extension_service);
+
+ void SetVersionUpdaterForTesting(
+ std::unique_ptr<VersionUpdater> version_updater) {
+ version_updater_ = std::move(version_updater);
+ }
private:
- // SettingsPageUIHandler implementation.
- void OnJavascriptAllowed() override {}
- void OnJavascriptDisallowed() override {}
+ // These ensure integers are passed in the correct possitions in the extension
+ // check methods.
+ using Compromised = util::StrongAlias<class CompromisedTag, int>;
+ using Done = util::StrongAlias<class DoneTag, int>;
+ using Total = util::StrongAlias<class TotalTag, int>;
+ using Blocklisted = util::StrongAlias<class BlocklistedTag, int>;
+ using ReenabledUser = util::StrongAlias<class ReenabledUserTag, int>;
+ using ReenabledAdmin = util::StrongAlias<class ReenabledAdminTag, int>;
- // WebUIMessageHandler implementation.
- void RegisterMessages() override {}
+ // Handles triggering the safety check from the frontend (by user pressing a
+ // button).
+ void HandlePerformSafetyCheck(const base::ListValue* args);
+
+ // Handles updating the safety check parent display string to show how long
+ // ago the safety check last ran.
+ void HandleGetParentRanDisplayString(const base::ListValue* args);
+
+ // Triggers an update check and invokes OnUpdateCheckResult once results
+ // are available.
+ void CheckUpdates();
+
+ // Gets the status of Safe Browsing from the PrefService and invokes
+ // OnSafeBrowsingCheckResult with results.
+ void CheckSafeBrowsing();
+
+ // Triggers a bulk password leak check and invokes OnPasswordsCheckResult once
+ // results are available.
+ void CheckPasswords();
+
+ // Checks if any of the installed extensions are blocklisted, and in
+ // that case, if any of those were re-enabled.
+ void CheckExtensions();
// Callbacks that get triggered when each check completes.
void OnUpdateCheckResult(VersionUpdater::Status status,
@@ -48,10 +149,60 @@ class SafetyCheckHandler : public settings::SettingsPageUIHandler {
const std::string& version,
int64_t update_size,
const base::string16& message);
+ void OnSafeBrowsingCheckResult(SafeBrowsingStatus status);
+ void OnPasswordsCheckResult(PasswordsStatus status,
+ Compromised compromised,
+ Done done,
+ Total total);
+ void OnExtensionsCheckResult(ExtensionsStatus status,
+ Blocklisted blocklisted,
+ ReenabledUser reenabled_user,
+ ReenabledAdmin reenabled_admin);
- std::unique_ptr<VersionUpdater> version_updater_;
+ // Methods for building user-visible strings based on the safety check
+ // state.
+ base::string16 GetStringForUpdates(UpdateStatus status);
+ base::string16 GetStringForSafeBrowsing(SafeBrowsingStatus status);
+ base::string16 GetStringForPasswords(PasswordsStatus status,
+ Compromised compromised,
+ Done done,
+ Total total);
+ base::string16 GetStringForExtensions(ExtensionsStatus status,
+ Blocklisted blocklisted,
+ ReenabledUser reenabled_user,
+ ReenabledAdmin reenabled_admin);
+
+ // Since the password check API does not distinguish between the cases of
+ // having no compromised passwords and not having any passwords at all, it is
+ // necessary to use this method as a callback for
+ // |PasswordsPrivateDelegate::GetSavedPasswordsList| to distinguish the two
+ // states here.
+ void DetermineIfNoPasswordsOrSafe(
+ const std::vector<extensions::api::passwords_private::PasswordUiEntry>&
+ passwords);
- DISALLOW_COPY_AND_ASSIGN(SafetyCheckHandler);
+ // BulkLeakCheckService::Observer implementation.
+ void OnStateChanged(
+ password_manager::BulkLeakCheckService::State state) override;
+ void OnCredentialDone(const password_manager::LeakCheckCredential& credential,
+ password_manager::IsLeaked is_leaked) override;
+
+ // SettingsPageUIHandler implementation.
+ void OnJavascriptAllowed() override;
+ void OnJavascriptDisallowed() override;
+
+ // WebUIMessageHandler implementation.
+ void RegisterMessages() override;
+
+ std::unique_ptr<VersionUpdater> version_updater_;
+ password_manager::BulkLeakCheckService* leak_service_ = nullptr;
+ extensions::PasswordsPrivateDelegate* passwords_delegate_ = nullptr;
+ extensions::ExtensionPrefs* extension_prefs_ = nullptr;
+ extensions::ExtensionServiceInterface* extension_service_ = nullptr;
+ ScopedObserver<password_manager::BulkLeakCheckService,
+ password_manager::BulkLeakCheckService::Observer>
+ observed_leak_check_{this};
+ base::WeakPtrFactory<SafetyCheckHandler> weak_ptr_factory_{this};
};
#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_SAFETY_CHECK_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/safety_check_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/safety_check_handler_unittest.cc
index 827d2dec6bd..cefb6e359d7 100644
--- a/chromium/chrome/browser/ui/webui/settings/safety_check_handler_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/safety_check_handler_unittest.cc
@@ -4,43 +4,1040 @@
#include "chrome/browser/ui/webui/settings/safety_check_handler.h"
+#include <string>
+#include <unordered_map>
+
#include "base/bind.h"
+#include "base/optional.h"
+#include "base/strings/string16.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/test/metrics/histogram_tester.h"
+#include "base/test/metrics/user_action_tester.h"
+#include "base/util/type_safety/strong_alias.h"
+#include "build/build_config.h"
+#include "chrome/browser/extensions/api/passwords_private/passwords_private_delegate.h"
+#include "chrome/browser/extensions/api/passwords_private/test_passwords_private_delegate.h"
+#include "chrome/browser/extensions/test_extension_service.h"
#include "chrome/browser/ui/webui/help/test_version_updater.h"
+#include "chrome/common/channel_info.h"
+#include "chrome/common/extensions/api/passwords_private.h"
+#include "chrome/test/base/chrome_render_view_host_test_harness.h"
+#include "components/crx_file/id_util.h"
+#include "components/password_manager/core/browser/bulk_leak_check_service.h"
+#include "components/password_manager/core/browser/leak_detection/bulk_leak_check.h"
+#include "components/prefs/pref_service.h"
+#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
+#include "components/sync_preferences/testing_pref_service_syncable.h"
+#include "components/version_info/version_info.h"
+#include "content/public/test/test_web_ui.h"
+#include "extensions/browser/extension_prefs.h"
+#include "extensions/common/extension.h"
+#include "extensions/common/extension_builder.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
-class SafetyCheckHandlerTest : public ::testing::Test {
+#if defined(OS_CHROMEOS)
+#include "ui/chromeos/devicetype_utils.h"
+#endif
+
+// Components for building event strings.
+constexpr char kUpdates[] = "updates";
+constexpr char kPasswords[] = "passwords";
+constexpr char kSafeBrowsing[] = "safe-browsing";
+constexpr char kExtensions[] = "extensions";
+
+namespace {
+using Enabled = util::StrongAlias<class EnabledTag, bool>;
+using UserCanDisable = util::StrongAlias<class UserCanDisableTag, bool>;
+
+class TestingSafetyCheckHandler : public SafetyCheckHandler {
public:
- void Callback(VersionUpdater::Status status,
- int progress,
- bool rollback,
- const std::string& version,
- int64_t update_size,
- const base::string16& message) {
- callback_invoked_ = true;
- result_ = status;
+ using SafetyCheckHandler::AllowJavascript;
+ using SafetyCheckHandler::DisallowJavascript;
+ using SafetyCheckHandler::set_web_ui;
+ using SafetyCheckHandler::SetVersionUpdaterForTesting;
+
+ TestingSafetyCheckHandler(
+ std::unique_ptr<VersionUpdater> version_updater,
+ password_manager::BulkLeakCheckService* leak_service,
+ extensions::PasswordsPrivateDelegate* passwords_delegate,
+ extensions::ExtensionPrefs* extension_prefs,
+ extensions::ExtensionServiceInterface* extension_service)
+ : SafetyCheckHandler(std::move(version_updater),
+ leak_service,
+ passwords_delegate,
+ extension_prefs,
+ extension_service) {}
+};
+
+class TestDestructionVersionUpdater : public TestVersionUpdater {
+ public:
+ ~TestDestructionVersionUpdater() override { destructor_invoked_ = true; }
+
+ void CheckForUpdate(const StatusCallback& callback,
+ const PromoteCallback&) override {}
+
+ static bool GetDestructorInvoked() { return destructor_invoked_; }
+
+ private:
+ static bool destructor_invoked_;
+};
+
+bool TestDestructionVersionUpdater::destructor_invoked_ = false;
+
+class TestPasswordsDelegate : public extensions::TestPasswordsPrivateDelegate {
+ public:
+ void SetBulkLeakCheckService(
+ password_manager::BulkLeakCheckService* leak_service) {
+ leak_service_ = leak_service;
+ }
+
+ void SetNumCompromisedCredentials(int compromised_password_count) {
+ compromised_password_count_ = compromised_password_count;
}
+ void SetPasswordCheckState(
+ extensions::api::passwords_private::PasswordCheckState state) {
+ state_ = state;
+ }
+
+ void SetProgress(int done, int total) {
+ done_ = done;
+ total_ = total;
+ }
+
+ std::vector<extensions::api::passwords_private::CompromisedCredential>
+ GetCompromisedCredentials() override {
+ std::vector<extensions::api::passwords_private::CompromisedCredential>
+ compromised(compromised_password_count_);
+ for (int i = 0; i < compromised_password_count_; ++i) {
+ compromised[i].username = "test" + base::NumberToString(i);
+ }
+ return compromised;
+ }
+
+ extensions::api::passwords_private::PasswordCheckStatus
+ GetPasswordCheckStatus() override {
+ extensions::api::passwords_private::PasswordCheckStatus status;
+ status.state = state_;
+ if (total_ != 0) {
+ status.already_processed = std::make_unique<int>(done_);
+ status.remaining_in_queue = std::make_unique<int>(total_ - done_);
+ }
+ return status;
+ }
+
+ private:
+ password_manager::BulkLeakCheckService* leak_service_ = nullptr;
+ int compromised_password_count_ = 0;
+ int done_ = 0;
+ int total_ = 0;
+ extensions::api::passwords_private::PasswordCheckState state_ =
+ extensions::api::passwords_private::PASSWORD_CHECK_STATE_IDLE;
+};
+
+class TestSafetyCheckExtensionService : public TestExtensionService {
+ public:
+ void AddExtensionState(const std::string& extension_id,
+ Enabled enabled,
+ UserCanDisable user_can_disable) {
+ state_map_.emplace(extension_id, ExtensionState{enabled.value(),
+ user_can_disable.value()});
+ }
+
+ bool IsExtensionEnabled(const std::string& extension_id) const override {
+ auto it = state_map_.find(extension_id);
+ if (it == state_map_.end()) {
+ return false;
+ }
+ return it->second.enabled;
+ }
+
+ bool UserCanDisableInstalledExtension(
+ const std::string& extension_id) override {
+ auto it = state_map_.find(extension_id);
+ if (it == state_map_.end()) {
+ return false;
+ }
+ return it->second.user_can_disable;
+ }
+
+ private:
+ struct ExtensionState {
+ bool enabled;
+ bool user_can_disable;
+ };
+
+ std::unordered_map<std::string, ExtensionState> state_map_;
+};
+
+} // namespace
+
+class SafetyCheckHandlerTest : public ChromeRenderViewHostTestHarness {
+ public:
+ void SetUp() override;
+
+ // Returns a |base::DictionaryValue| for safety check status update that
+ // has the specified |component| and |new_state| if it exists; nullptr
+ // otherwise.
+ const base::DictionaryValue* GetSafetyCheckStatusChangedWithDataIfExists(
+ const std::string& component,
+ int new_state);
+
+ std::string GenerateExtensionId(char char_to_repeat);
+
+ void VerifyDisplayString(const base::DictionaryValue* event,
+ const base::string16& expected);
+ void VerifyDisplayString(const base::DictionaryValue* event,
+ const std::string& expected);
+ void VerifyButtonString(const base::DictionaryValue* event,
+ const base::string16& expected);
+ void VerifyButtonString(const base::DictionaryValue* event,
+ const std::string& expected);
+
protected:
- bool callback_invoked_ = false;
- VersionUpdater::Status result_;
- TestVersionUpdater version_updater_;
- SafetyCheckHandler safety_check_;
+ TestVersionUpdater* version_updater_ = nullptr;
+ std::unique_ptr<password_manager::BulkLeakCheckService> test_leak_service_;
+ TestPasswordsDelegate test_passwords_delegate_;
+ extensions::ExtensionPrefs* test_extension_prefs_ = nullptr;
+ TestSafetyCheckExtensionService test_extension_service_;
+ content::TestWebUI test_web_ui_;
+ std::unique_ptr<TestingSafetyCheckHandler> safety_check_;
+ base::HistogramTester histogram_tester_;
+
+ private:
+ // Replaces any instances of browser name (e.g. Google Chrome, Chromium,
+ // etc) with "browser" to make sure tests work both on Chromium and
+ // Google Chrome.
+ void ReplaceBrowserName(base::string16* s);
};
-TEST_F(SafetyCheckHandlerTest, CheckUpdatesUpdated) {
- version_updater_.SetReturnedStatus(VersionUpdater::Status::UPDATED);
- safety_check_.CheckUpdates(
- &version_updater_,
- base::Bind(&SafetyCheckHandlerTest::Callback, base::Unretained(this)));
- ASSERT_TRUE(callback_invoked_);
- EXPECT_EQ(VersionUpdater::Status::UPDATED, result_);
-}
-
-TEST_F(SafetyCheckHandlerTest, CheckUpdatesNotUpdated) {
- version_updater_.SetReturnedStatus(VersionUpdater::Status::DISABLED);
- safety_check_.CheckUpdates(
- &version_updater_,
- base::Bind(&SafetyCheckHandlerTest::Callback, base::Unretained(this)));
- ASSERT_TRUE(callback_invoked_);
- EXPECT_EQ(VersionUpdater::Status::DISABLED, result_);
+void SafetyCheckHandlerTest::SetUp() {
+ ChromeRenderViewHostTestHarness::SetUp();
+
+ // The unique pointer to a TestVersionUpdater gets moved to
+ // SafetyCheckHandler, but a raw pointer is retained here to change its
+ // state.
+ auto version_updater = std::make_unique<TestVersionUpdater>();
+ test_leak_service_ = std::make_unique<password_manager::BulkLeakCheckService>(
+ nullptr, nullptr);
+ test_passwords_delegate_.SetBulkLeakCheckService(test_leak_service_.get());
+ version_updater_ = version_updater.get();
+ test_web_ui_.set_web_contents(web_contents());
+ test_extension_prefs_ = extensions::ExtensionPrefs::Get(profile());
+ safety_check_ = std::make_unique<TestingSafetyCheckHandler>(
+ std::move(version_updater), test_leak_service_.get(),
+ &test_passwords_delegate_, test_extension_prefs_,
+ &test_extension_service_);
+ test_web_ui_.ClearTrackedCalls();
+ safety_check_->set_web_ui(&test_web_ui_);
+ safety_check_->AllowJavascript();
+}
+
+const base::DictionaryValue*
+SafetyCheckHandlerTest::GetSafetyCheckStatusChangedWithDataIfExists(
+ const std::string& component,
+ int new_state) {
+ // Return the latest update if multiple, so iterate from the end.
+ const std::vector<std::unique_ptr<content::TestWebUI::CallData>>& call_data =
+ test_web_ui_.call_data();
+ for (int i = call_data.size() - 1; i >= 0; --i) {
+ const content::TestWebUI::CallData& data = *(call_data[i]);
+ if (data.function_name() != "cr.webUIListenerCallback") {
+ continue;
+ }
+ std::string event;
+ if ((!data.arg1()->GetAsString(&event)) ||
+ event != "safety-check-" + component + "-status-changed") {
+ continue;
+ }
+ const base::DictionaryValue* dictionary = nullptr;
+ if (!data.arg2()->GetAsDictionary(&dictionary)) {
+ continue;
+ }
+ int cur_new_state;
+ if (dictionary->GetInteger("newState", &cur_new_state) &&
+ cur_new_state == new_state) {
+ return dictionary;
+ }
+ }
+ return nullptr;
+}
+
+std::string SafetyCheckHandlerTest::GenerateExtensionId(char char_to_repeat) {
+ return std::string(crx_file::id_util::kIdSize * 2, char_to_repeat);
+}
+
+void SafetyCheckHandlerTest::VerifyDisplayString(
+ const base::DictionaryValue* event,
+ const base::string16& expected) {
+ base::string16 display;
+ ASSERT_TRUE(event->GetString("displayString", &display));
+ ReplaceBrowserName(&display);
+ // Need to also replace any instances of Chrome and Chromium in the
+ // expected string due to an edge case on ChromeOS, where a device name
+ // is "Chrome", which gets replaced in the display string.
+ base::string16 expected_replaced = expected;
+ ReplaceBrowserName(&expected_replaced);
+ EXPECT_EQ(expected_replaced, display);
+}
+
+void SafetyCheckHandlerTest::VerifyDisplayString(
+ const base::DictionaryValue* event,
+ const std::string& expected) {
+ VerifyDisplayString(event, base::ASCIIToUTF16(expected));
+}
+
+void SafetyCheckHandlerTest::VerifyButtonString(
+ const base::DictionaryValue* event,
+ const base::string16& expected) {
+ base::string16 button;
+ ASSERT_TRUE(event->GetString("buttonString", &button));
+ EXPECT_EQ(expected, button);
+}
+
+void SafetyCheckHandlerTest::VerifyButtonString(
+ const base::DictionaryValue* event,
+ const std::string& expected) {
+ VerifyButtonString(event, base::ASCIIToUTF16(expected));
+}
+
+void SafetyCheckHandlerTest::ReplaceBrowserName(base::string16* s) {
+ base::ReplaceSubstringsAfterOffset(s, 0, base::ASCIIToUTF16("Google Chrome"),
+ base::ASCIIToUTF16("Browser"));
+ base::ReplaceSubstringsAfterOffset(s, 0, base::ASCIIToUTF16("Chrome"),
+ base::ASCIIToUTF16("Browser"));
+ base::ReplaceSubstringsAfterOffset(s, 0, base::ASCIIToUTF16("Chromium"),
+ base::ASCIIToUTF16("Browser"));
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckUpdates_Checking) {
+ version_updater_->SetReturnedStatus(VersionUpdater::Status::CHECKING);
+ safety_check_->PerformSafetyCheck();
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kUpdates,
+ static_cast<int>(SafetyCheckHandler::UpdateStatus::kChecking));
+ ASSERT_TRUE(event);
+ VerifyDisplayString(event, base::UTF8ToUTF16("Running…"));
+ // Checking state should not get recorded.
+ histogram_tester_.ExpectTotalCount("Settings.SafetyCheck.UpdatesResult", 0);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckUpdates_Updated) {
+ version_updater_->SetReturnedStatus(VersionUpdater::Status::UPDATED);
+ safety_check_->PerformSafetyCheck();
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kUpdates,
+ static_cast<int>(SafetyCheckHandler::UpdateStatus::kUpdated));
+ ASSERT_TRUE(event);
+#if defined(OS_CHROMEOS)
+ base::string16 expected = base::ASCIIToUTF16("Your ") +
+ ui::GetChromeOSDeviceName() +
+ base::ASCIIToUTF16(" is up to date");
+ VerifyDisplayString(event, expected);
+#else
+ VerifyDisplayString(event, "Browser is up to date");
+#endif
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.UpdatesResult",
+ SafetyCheckHandler::UpdateStatus::kUpdated, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckUpdates_Updating) {
+ version_updater_->SetReturnedStatus(VersionUpdater::Status::UPDATING);
+ safety_check_->PerformSafetyCheck();
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kUpdates,
+ static_cast<int>(SafetyCheckHandler::UpdateStatus::kUpdating));
+ ASSERT_TRUE(event);
+#if defined(OS_CHROMEOS)
+ VerifyDisplayString(event, "Updating your device");
+#else
+ VerifyDisplayString(event, "Updating Browser");
+#endif
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.UpdatesResult",
+ SafetyCheckHandler::UpdateStatus::kUpdating, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckUpdates_Relaunch) {
+ version_updater_->SetReturnedStatus(VersionUpdater::Status::NEARLY_UPDATED);
+ safety_check_->PerformSafetyCheck();
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kUpdates,
+ static_cast<int>(SafetyCheckHandler::UpdateStatus::kRelaunch));
+ ASSERT_TRUE(event);
+#if defined(OS_CHROMEOS)
+ VerifyDisplayString(
+ event, "Nearly up to date! Restart your device to finish updating.");
+#else
+ VerifyDisplayString(event,
+ "Nearly up to date! Relaunch Browser to finish "
+ "updating. Incognito windows won't reopen.");
+#endif
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.UpdatesResult",
+ SafetyCheckHandler::UpdateStatus::kRelaunch, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckUpdates_Disabled) {
+ version_updater_->SetReturnedStatus(VersionUpdater::Status::DISABLED);
+ safety_check_->PerformSafetyCheck();
+ // TODO(crbug/1072432): Since the UNKNOWN state is not present in JS in M83,
+ // use FAILED_OFFLINE, which uses the same icon.
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kUpdates,
+ static_cast<int>(SafetyCheckHandler::UpdateStatus::kFailedOffline));
+ ASSERT_TRUE(event);
+ VerifyDisplayString(
+ event, "Version " + version_info::GetVersionNumber() + " (" +
+ (version_info::IsOfficialBuild() ? "Official Build"
+ : "Developer Build") +
+ ") " + chrome::GetChannelName() +
+ (sizeof(void*) == 8 ? " (64-bit)" : " (32-bit)"));
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.UpdatesResult",
+ SafetyCheckHandler::UpdateStatus::kUnknown, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckUpdates_DisabledByAdmin) {
+ version_updater_->SetReturnedStatus(
+ VersionUpdater::Status::DISABLED_BY_ADMIN);
+ safety_check_->PerformSafetyCheck();
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kUpdates,
+ static_cast<int>(SafetyCheckHandler::UpdateStatus::kDisabledByAdmin));
+ ASSERT_TRUE(event);
+ VerifyDisplayString(
+ event,
+ "Updates are managed by <a target=\"_blank\" "
+ "href=\"https://support.google.com/chrome?p=your_administrator\">your "
+ "administrator</a>");
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.UpdatesResult",
+ SafetyCheckHandler::UpdateStatus::kDisabledByAdmin, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckUpdates_FailedOffline) {
+ version_updater_->SetReturnedStatus(VersionUpdater::Status::FAILED_OFFLINE);
+ safety_check_->PerformSafetyCheck();
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kUpdates,
+ static_cast<int>(SafetyCheckHandler::UpdateStatus::kFailedOffline));
+ ASSERT_TRUE(event);
+ VerifyDisplayString(event,
+ "Browser can't check for updates. Try checking your "
+ "internet connection.");
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.UpdatesResult",
+ SafetyCheckHandler::UpdateStatus::kFailedOffline, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckUpdates_Failed) {
+ version_updater_->SetReturnedStatus(VersionUpdater::Status::FAILED);
+ safety_check_->PerformSafetyCheck();
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kUpdates,
+ static_cast<int>(SafetyCheckHandler::UpdateStatus::kFailed));
+ ASSERT_TRUE(event);
+ VerifyDisplayString(
+ event,
+ "Browser didn't update, something went wrong. <a target=\"_blank\" "
+ "href=\"https://support.google.com/chrome?p=fix_chrome_updates\">Fix "
+ "Browser update problems and failed updates.</a>");
+ histogram_tester_.ExpectBucketCount("Settings.SafetyCheck.UpdatesResult",
+ SafetyCheckHandler::UpdateStatus::kFailed,
+ 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckUpdates_DestroyedOnJavascriptDisallowed) {
+ EXPECT_FALSE(TestDestructionVersionUpdater::GetDestructorInvoked());
+ safety_check_->SetVersionUpdaterForTesting(
+ std::make_unique<TestDestructionVersionUpdater>());
+ safety_check_->PerformSafetyCheck();
+ safety_check_->DisallowJavascript();
+ EXPECT_TRUE(TestDestructionVersionUpdater::GetDestructorInvoked());
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckSafeBrowsing_Enabled) {
+ Profile::FromWebUI(&test_web_ui_)
+ ->GetPrefs()
+ ->SetBoolean(prefs::kSafeBrowsingEnabled, true);
+ safety_check_->PerformSafetyCheck();
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kSafeBrowsing,
+ static_cast<int>(SafetyCheckHandler::SafeBrowsingStatus::kEnabled));
+ ASSERT_TRUE(event);
+ VerifyDisplayString(event,
+ "Safe Browsing is on and protecting you from harmful "
+ "sites and downloads");
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.SafeBrowsingResult",
+ SafetyCheckHandler::SafeBrowsingStatus::kEnabled, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckSafeBrowsing_Disabled) {
+ Profile::FromWebUI(&test_web_ui_)
+ ->GetPrefs()
+ ->SetBoolean(prefs::kSafeBrowsingEnabled, false);
+ safety_check_->PerformSafetyCheck();
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kSafeBrowsing,
+ static_cast<int>(SafetyCheckHandler::SafeBrowsingStatus::kDisabled));
+ ASSERT_TRUE(event);
+ VerifyDisplayString(
+ event, "Safe Browsing is off. Browser recommends turning it on.");
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.SafeBrowsingResult",
+ SafetyCheckHandler::SafeBrowsingStatus::kDisabled, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckSafeBrowsing_DisabledByAdmin) {
+ TestingProfile::FromWebUI(&test_web_ui_)
+ ->AsTestingProfile()
+ ->GetTestingPrefService()
+ ->SetManagedPref(prefs::kSafeBrowsingEnabled,
+ std::make_unique<base::Value>(false));
+ safety_check_->PerformSafetyCheck();
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kSafeBrowsing,
+ static_cast<int>(
+ SafetyCheckHandler::SafeBrowsingStatus::kDisabledByAdmin));
+ ASSERT_TRUE(event);
+ VerifyDisplayString(
+ event,
+ "<a target=\"_blank\" "
+ "href=\"https://support.google.com/chrome?p=your_administrator\">Your "
+ "administrator</a> has turned off Safe Browsing");
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.SafeBrowsingResult",
+ SafetyCheckHandler::SafeBrowsingStatus::kDisabledByAdmin, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckSafeBrowsing_DisabledByExtension) {
+ TestingProfile::FromWebUI(&test_web_ui_)
+ ->AsTestingProfile()
+ ->GetTestingPrefService()
+ ->SetExtensionPref(prefs::kSafeBrowsingEnabled,
+ std::make_unique<base::Value>(false));
+ safety_check_->PerformSafetyCheck();
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kSafeBrowsing,
+ static_cast<int>(
+ SafetyCheckHandler::SafeBrowsingStatus::kDisabledByExtension));
+ ASSERT_TRUE(event);
+ VerifyDisplayString(event, "An extension has turned off Safe Browsing");
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.SafeBrowsingResult",
+ SafetyCheckHandler::SafeBrowsingStatus::kDisabledByExtension, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckPasswords_ObserverRemovedAfterError) {
+ safety_check_->PerformSafetyCheck();
+ // First, a "running" change of state.
+ test_leak_service_->set_state_and_notify(
+ password_manager::BulkLeakCheckService::State::kRunning);
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(SafetyCheckHandler::PasswordsStatus::kChecking));
+ ASSERT_TRUE(event);
+ VerifyDisplayString(event, base::UTF8ToUTF16("Running…"));
+ histogram_tester_.ExpectTotalCount("Settings.SafetyCheck.PasswordsResult", 0);
+ // Second, an "offline" state.
+ test_leak_service_->set_state_and_notify(
+ password_manager::BulkLeakCheckService::State::kNetworkError);
+ const base::DictionaryValue* event2 =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(SafetyCheckHandler::PasswordsStatus::kOffline));
+ ASSERT_TRUE(event2);
+ VerifyDisplayString(event2,
+ "Browser can't check your passwords. Try checking your "
+ "internet connection.");
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.PasswordsResult",
+ SafetyCheckHandler::PasswordsStatus::kOffline, 1);
+ // Another error, but since the previous state is terminal, the handler
+ // should no longer be observing the BulkLeakCheckService state.
+ test_leak_service_->set_state_and_notify(
+ password_manager::BulkLeakCheckService::State::kServiceError);
+ const base::DictionaryValue* event3 =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(SafetyCheckHandler::PasswordsStatus::kOffline));
+ ASSERT_TRUE(event3);
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.PasswordsResult",
+ SafetyCheckHandler::PasswordsStatus::kOffline, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckPasswords_InterruptedAndRefreshed) {
+ safety_check_->PerformSafetyCheck();
+ // Password check running.
+ test_leak_service_->set_state_and_notify(
+ password_manager::BulkLeakCheckService::State::kRunning);
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(SafetyCheckHandler::PasswordsStatus::kChecking));
+ ASSERT_TRUE(event);
+ VerifyDisplayString(event, base::UTF8ToUTF16("Running…"));
+ // The check gets interrupted and the page is refreshed.
+ safety_check_->DisallowJavascript();
+ safety_check_->AllowJavascript();
+ // Need to set the |TestVersionUpdater| instance again to prevent
+ // |PerformSafetyCheck()| from creating a real |VersionUpdater| instance.
+ safety_check_->SetVersionUpdaterForTesting(
+ std::make_unique<TestVersionUpdater>());
+ // Another run of the safety check.
+ safety_check_->PerformSafetyCheck();
+ test_leak_service_->set_state_and_notify(
+ password_manager::BulkLeakCheckService::State::kRunning);
+ const base::DictionaryValue* event2 =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(SafetyCheckHandler::PasswordsStatus::kChecking));
+ ASSERT_TRUE(event2);
+ test_leak_service_->set_state_and_notify(
+ password_manager::BulkLeakCheckService::State::kSignedOut);
+ const base::DictionaryValue* event3 =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(SafetyCheckHandler::PasswordsStatus::kSignedOut));
+ ASSERT_TRUE(event3);
+ VerifyDisplayString(event3,
+ "Browser can't check your passwords because you're not "
+ "signed in");
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.PasswordsResult",
+ SafetyCheckHandler::PasswordsStatus::kSignedOut, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckPasswords_StartedTwice) {
+ safety_check_->PerformSafetyCheck();
+ safety_check_->PerformSafetyCheck();
+ // First, a "running" change of state.
+ test_leak_service_->set_state_and_notify(
+ password_manager::BulkLeakCheckService::State::kRunning);
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(SafetyCheckHandler::PasswordsStatus::kChecking));
+ ASSERT_TRUE(event);
+ // Then, a network error.
+ test_leak_service_->set_state_and_notify(
+ password_manager::BulkLeakCheckService::State::kNetworkError);
+ const base::DictionaryValue* event2 =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(SafetyCheckHandler::PasswordsStatus::kOffline));
+ EXPECT_TRUE(event2);
+ VerifyDisplayString(event2,
+ "Browser can't check your passwords. Try checking your "
+ "internet connection.");
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.PasswordsResult",
+ SafetyCheckHandler::PasswordsStatus::kOffline, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckPasswords_ObserverNotifiedTwice) {
+ safety_check_->PerformSafetyCheck();
+ EXPECT_TRUE(test_passwords_delegate_.StartPasswordCheckTriggered());
+ static_cast<password_manager::BulkLeakCheckService::Observer*>(
+ safety_check_.get())
+ ->OnStateChanged(
+ password_manager::BulkLeakCheckService::State::kServiceError);
+ // Another notification about the same state change.
+ static_cast<password_manager::BulkLeakCheckService::Observer*>(
+ safety_check_.get())
+ ->OnStateChanged(
+ password_manager::BulkLeakCheckService::State::kServiceError);
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(SafetyCheckHandler::PasswordsStatus::kError));
+ ASSERT_TRUE(event);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckPasswords_Safe) {
+ safety_check_->PerformSafetyCheck();
+ // First, a "running" change of state.
+ test_leak_service_->set_state_and_notify(
+ password_manager::BulkLeakCheckService::State::kRunning);
+ EXPECT_TRUE(GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(SafetyCheckHandler::PasswordsStatus::kChecking)));
+ // Second, a "safe" state.
+ test_leak_service_->set_state_and_notify(
+ password_manager::BulkLeakCheckService::State::kIdle);
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(SafetyCheckHandler::PasswordsStatus::kSafe));
+ EXPECT_TRUE(event);
+ VerifyDisplayString(event, "No compromised passwords found");
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.PasswordsResult",
+ SafetyCheckHandler::PasswordsStatus::kSafe, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckPasswords_CompromisedExist) {
+ constexpr int kCompromised = 7;
+ test_passwords_delegate_.SetNumCompromisedCredentials(kCompromised);
+ safety_check_->PerformSafetyCheck();
+ // First, a "running" change of state.
+ test_leak_service_->set_state_and_notify(
+ password_manager::BulkLeakCheckService::State::kRunning);
+ EXPECT_TRUE(GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(SafetyCheckHandler::PasswordsStatus::kChecking)));
+ // Compromised passwords found state.
+ test_leak_service_->set_state_and_notify(
+ password_manager::BulkLeakCheckService::State::kIdle);
+ const base::DictionaryValue* event2 =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(
+ SafetyCheckHandler::PasswordsStatus::kCompromisedExist));
+ ASSERT_TRUE(event2);
+ VerifyDisplayString(
+ event2, base::NumberToString(kCompromised) + " compromised passwords");
+ VerifyButtonString(event2, "Change passwords");
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.PasswordsResult",
+ SafetyCheckHandler::PasswordsStatus::kCompromisedExist, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckPasswords_Error) {
+ safety_check_->PerformSafetyCheck();
+ EXPECT_TRUE(test_passwords_delegate_.StartPasswordCheckTriggered());
+ static_cast<password_manager::BulkLeakCheckService::Observer*>(
+ safety_check_.get())
+ ->OnStateChanged(
+ password_manager::BulkLeakCheckService::State::kServiceError);
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(SafetyCheckHandler::PasswordsStatus::kError));
+ ASSERT_TRUE(event);
+ VerifyDisplayString(event,
+ "Browser can't check your passwords. Try again "
+ "later.");
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.PasswordsResult",
+ SafetyCheckHandler::PasswordsStatus::kError, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckPasswords_RunningOneCompromised) {
+ test_passwords_delegate_.SetNumCompromisedCredentials(1);
+ safety_check_->PerformSafetyCheck();
+ EXPECT_TRUE(test_passwords_delegate_.StartPasswordCheckTriggered());
+ static_cast<password_manager::BulkLeakCheckService::Observer*>(
+ safety_check_.get())
+ ->OnStateChanged(password_manager::BulkLeakCheckService::State::kIdle);
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(
+ SafetyCheckHandler::PasswordsStatus::kCompromisedExist));
+ ASSERT_TRUE(event);
+ VerifyDisplayString(event, "1 compromised password");
+ VerifyButtonString(event, "Change password");
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.PasswordsResult",
+ SafetyCheckHandler::PasswordsStatus::kCompromisedExist, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckPasswords_NoPasswords) {
+ test_passwords_delegate_.ClearSavedPasswordsList();
+ test_passwords_delegate_.SetStartPasswordCheckState(
+ password_manager::BulkLeakCheckService::State::kIdle);
+ safety_check_->PerformSafetyCheck();
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(SafetyCheckHandler::PasswordsStatus::kNoPasswords));
+ EXPECT_TRUE(event);
+ VerifyDisplayString(event,
+ "No saved passwords. Chrome can check your passwords "
+ "when you save them.");
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.PasswordsResult",
+ SafetyCheckHandler::PasswordsStatus::kNoPasswords, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckPasswords_Progress) {
+ auto credential = password_manager::LeakCheckCredential(
+ base::UTF8ToUTF16("test"), base::UTF8ToUTF16("test"));
+ auto is_leaked = password_manager::IsLeaked(false);
+ safety_check_->PerformSafetyCheck();
+ test_passwords_delegate_.SetPasswordCheckState(
+ extensions::api::passwords_private::PASSWORD_CHECK_STATE_RUNNING);
+ test_passwords_delegate_.SetProgress(1, 3);
+ static_cast<password_manager::BulkLeakCheckService::Observer*>(
+ safety_check_.get())
+ ->OnCredentialDone(credential, is_leaked);
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(SafetyCheckHandler::PasswordsStatus::kChecking));
+ EXPECT_TRUE(event);
+ VerifyDisplayString(event, base::UTF8ToUTF16("Checking passwords (1 of 3)…"));
+
+ test_passwords_delegate_.SetProgress(2, 3);
+ static_cast<password_manager::BulkLeakCheckService::Observer*>(
+ safety_check_.get())
+ ->OnCredentialDone(credential, is_leaked);
+ const base::DictionaryValue* event2 =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(SafetyCheckHandler::PasswordsStatus::kChecking));
+ EXPECT_TRUE(event2);
+ VerifyDisplayString(event2,
+ base::UTF8ToUTF16("Checking passwords (2 of 3)…"));
+
+ // Final update comes after status change, so no new progress message should
+ // be present.
+ test_passwords_delegate_.SetPasswordCheckState(
+ extensions::api::passwords_private::PASSWORD_CHECK_STATE_IDLE);
+ test_passwords_delegate_.SetProgress(3, 3);
+ static_cast<password_manager::BulkLeakCheckService::Observer*>(
+ safety_check_.get())
+ ->OnCredentialDone(credential, is_leaked);
+ const base::DictionaryValue* event3 =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(SafetyCheckHandler::PasswordsStatus::kChecking));
+ EXPECT_TRUE(event3);
+ // Still 2/3 event.
+ VerifyDisplayString(event3,
+ base::UTF8ToUTF16("Checking passwords (2 of 3)…"));
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckExtensions_NoExtensions) {
+ safety_check_->PerformSafetyCheck();
+ EXPECT_TRUE(GetSafetyCheckStatusChangedWithDataIfExists(
+ kExtensions,
+ static_cast<int>(
+ SafetyCheckHandler::ExtensionsStatus::kNoneBlocklisted)));
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.ExtensionsResult",
+ SafetyCheckHandler::ExtensionsStatus::kNoneBlocklisted, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckExtensions_NoneBlocklisted) {
+ std::string extension_id = GenerateExtensionId('a');
+ scoped_refptr<const extensions::Extension> extension =
+ extensions::ExtensionBuilder(extension_id).Build();
+ test_extension_prefs_->OnExtensionInstalled(
+ extension.get(), extensions::Extension::State::ENABLED,
+ syncer::StringOrdinal(), "");
+ test_extension_prefs_->SetExtensionBlacklistState(
+ extension_id, extensions::NOT_BLACKLISTED);
+ safety_check_->PerformSafetyCheck();
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kExtensions,
+ static_cast<int>(
+ SafetyCheckHandler::ExtensionsStatus::kNoneBlocklisted));
+ EXPECT_TRUE(event);
+ VerifyDisplayString(event,
+ "You're protected from potentially harmful extensions");
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.ExtensionsResult",
+ SafetyCheckHandler::ExtensionsStatus::kNoneBlocklisted, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckExtensions_BlocklistedAllDisabled) {
+ std::string extension_id = GenerateExtensionId('a');
+ scoped_refptr<const extensions::Extension> extension =
+ extensions::ExtensionBuilder("test0").SetID(extension_id).Build();
+ test_extension_prefs_->OnExtensionInstalled(
+ extension.get(), extensions::Extension::State::DISABLED,
+ syncer::StringOrdinal(), "");
+ test_extension_prefs_->SetExtensionBlacklistState(
+ extension_id, extensions::BLACKLISTED_MALWARE);
+ test_extension_service_.AddExtensionState(extension_id, Enabled(false),
+ UserCanDisable(false));
+ safety_check_->PerformSafetyCheck();
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kExtensions,
+ static_cast<int>(
+ SafetyCheckHandler::ExtensionsStatus::kBlocklistedAllDisabled));
+ EXPECT_TRUE(event);
+ VerifyDisplayString(
+ event, "1 potentially harmful extension is off. You can also remove it.");
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.ExtensionsResult",
+ SafetyCheckHandler::ExtensionsStatus::kBlocklistedAllDisabled, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckExtensions_BlocklistedReenabledAllByUser) {
+ std::string extension_id = GenerateExtensionId('a');
+ scoped_refptr<const extensions::Extension> extension =
+ extensions::ExtensionBuilder("test0").SetID(extension_id).Build();
+ test_extension_prefs_->OnExtensionInstalled(
+ extension.get(), extensions::Extension::State::ENABLED,
+ syncer::StringOrdinal(), "");
+ test_extension_prefs_->SetExtensionBlacklistState(
+ extension_id, extensions::BLACKLISTED_POTENTIALLY_UNWANTED);
+ test_extension_service_.AddExtensionState(extension_id, Enabled(true),
+ UserCanDisable(true));
+ safety_check_->PerformSafetyCheck();
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kExtensions, static_cast<int>(SafetyCheckHandler::ExtensionsStatus::
+ kBlocklistedReenabledAllByUser));
+ EXPECT_TRUE(event);
+ VerifyDisplayString(event,
+ "You turned 1 potentially harmful extension back on");
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.ExtensionsResult",
+ SafetyCheckHandler::ExtensionsStatus::kBlocklistedReenabledAllByUser, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckExtensions_BlocklistedReenabledAllByAdmin) {
+ std::string extension_id = GenerateExtensionId('a');
+ scoped_refptr<const extensions::Extension> extension =
+ extensions::ExtensionBuilder("test0").SetID(extension_id).Build();
+ test_extension_prefs_->OnExtensionInstalled(
+ extension.get(), extensions::Extension::State::ENABLED,
+ syncer::StringOrdinal(), "");
+ test_extension_prefs_->SetExtensionBlacklistState(
+ extension_id, extensions::BLACKLISTED_POTENTIALLY_UNWANTED);
+ test_extension_service_.AddExtensionState(extension_id, Enabled(true),
+ UserCanDisable(false));
+ safety_check_->PerformSafetyCheck();
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kExtensions, static_cast<int>(SafetyCheckHandler::ExtensionsStatus::
+ kBlocklistedReenabledAllByAdmin));
+ VerifyDisplayString(event,
+ "Your administrator turned 1 potentially harmful "
+ "extension back on");
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.ExtensionsResult",
+ SafetyCheckHandler::ExtensionsStatus::kBlocklistedReenabledAllByAdmin, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckExtensions_BlocklistedReenabledSomeByUser) {
+ std::string extension_id = GenerateExtensionId('a');
+ scoped_refptr<const extensions::Extension> extension =
+ extensions::ExtensionBuilder("test0").SetID(extension_id).Build();
+ test_extension_prefs_->OnExtensionInstalled(
+ extension.get(), extensions::Extension::State::ENABLED,
+ syncer::StringOrdinal(), "");
+ test_extension_prefs_->SetExtensionBlacklistState(
+ extension_id, extensions::BLACKLISTED_POTENTIALLY_UNWANTED);
+ test_extension_service_.AddExtensionState(extension_id, Enabled(true),
+ UserCanDisable(true));
+
+ std::string extension2_id = GenerateExtensionId('b');
+ scoped_refptr<const extensions::Extension> extension2 =
+ extensions::ExtensionBuilder("test1").SetID(extension2_id).Build();
+ test_extension_prefs_->OnExtensionInstalled(
+ extension2.get(), extensions::Extension::State::ENABLED,
+ syncer::StringOrdinal(), "");
+ test_extension_prefs_->SetExtensionBlacklistState(
+ extension2_id, extensions::BLACKLISTED_POTENTIALLY_UNWANTED);
+ test_extension_service_.AddExtensionState(extension2_id, Enabled(true),
+ UserCanDisable(false));
+
+ safety_check_->PerformSafetyCheck();
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kExtensions, static_cast<int>(SafetyCheckHandler::ExtensionsStatus::
+ kBlocklistedReenabledSomeByUser));
+ EXPECT_TRUE(event);
+ VerifyDisplayString(event,
+ "You turned 1 potentially harmful extension back "
+ "on. Your administrator "
+ "turned 1 potentially harmful extension back on.");
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.ExtensionsResult",
+ SafetyCheckHandler::ExtensionsStatus::kBlocklistedReenabledSomeByUser, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckExtensions_Error) {
+ // One extension in the error state.
+ std::string extension_id = GenerateExtensionId('a');
+ scoped_refptr<const extensions::Extension> extension =
+ extensions::ExtensionBuilder("test0").SetID(extension_id).Build();
+ test_extension_prefs_->OnExtensionInstalled(
+ extension.get(), extensions::Extension::State::ENABLED,
+ syncer::StringOrdinal(), "");
+ test_extension_prefs_->SetExtensionBlacklistState(
+ extension_id, extensions::BLACKLISTED_UNKNOWN);
+ test_extension_service_.AddExtensionState(extension_id, Enabled(true),
+ UserCanDisable(true));
+
+ // Another extension blocklisted.
+ std::string extension2_id = GenerateExtensionId('b');
+ scoped_refptr<const extensions::Extension> extension2 =
+ extensions::ExtensionBuilder("test1").SetID(extension2_id).Build();
+ test_extension_prefs_->OnExtensionInstalled(
+ extension2.get(), extensions::Extension::State::ENABLED,
+ syncer::StringOrdinal(), "");
+ test_extension_prefs_->SetExtensionBlacklistState(
+ extension2_id, extensions::BLACKLISTED_POTENTIALLY_UNWANTED);
+ test_extension_service_.AddExtensionState(extension2_id, Enabled(true),
+ UserCanDisable(false));
+
+ safety_check_->PerformSafetyCheck();
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kExtensions,
+ static_cast<int>(SafetyCheckHandler::ExtensionsStatus::kError));
+ EXPECT_TRUE(event);
+ VerifyDisplayString(event,
+ "Browser can't check your extensions. Try again later.");
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.ExtensionsResult",
+ SafetyCheckHandler::ExtensionsStatus::kError, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckParentRanDisplayString) {
+ // 1 second before midnight, so that -(24h-1s) is still on the same day.
+ const base::Time systemTime =
+ base::Time::Now().LocalMidnight() - base::TimeDelta::FromSeconds(1);
+ // Display strings for given time deltas in seconds.
+ std::vector<std::tuple<std::string, int>> tuples{
+ std::make_tuple("Safety check ran a moment ago", 1),
+ std::make_tuple("Safety check ran a moment ago", 59),
+ std::make_tuple("Safety check ran 1 minute ago", 60),
+ std::make_tuple("Safety check ran 2 minutes ago", 60 * 2),
+ std::make_tuple("Safety check ran 59 minutes ago", 60 * 60 - 1),
+ std::make_tuple("Safety check ran 1 hour ago", 60 * 60),
+ std::make_tuple("Safety check ran 2 hours ago", 60 * 60 * 2),
+ std::make_tuple("Safety check ran 23 hours ago", 60 * 60 * 23),
+ std::make_tuple("Safety check ran yesterday", 60 * 60 * 24),
+ std::make_tuple("Safety check ran yesterday", 60 * 60 * 24 * 2 - 1),
+ std::make_tuple("Safety check ran 2 days ago", 60 * 60 * 24 * 2),
+ std::make_tuple("Safety check ran 2 days ago", 60 * 60 * 24 * 3 - 1),
+ std::make_tuple("Safety check ran 3 days ago", 60 * 60 * 24 * 3),
+ std::make_tuple("Safety check ran 3 days ago", 60 * 60 * 24 * 4 - 1)};
+ // Test that above time deltas produce the corresponding display strings.
+ for (auto tuple : tuples) {
+ const base::Time time =
+ systemTime - base::TimeDelta::FromSeconds(std::get<1>(tuple));
+ const base::string16 displayString = safety_check_->GetStringForParentRan(
+ time.ToJsTimeIgnoringNull(), systemTime);
+ EXPECT_EQ(base::UTF8ToUTF16(std::get<0>(tuple)), displayString);
+ }
}
diff --git a/chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc b/chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc
index ed1e4d58c0b..7c2416bd30a 100644
--- a/chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc
@@ -18,6 +18,7 @@
#include "chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h"
#include "chrome/browser/browsing_data/counters/browsing_data_counter_factory.h"
#include "chrome/browser/browsing_data/counters/browsing_data_counter_utils.h"
+#include "chrome/browser/engagement/important_sites_util.h"
#include "chrome/browser/history/web_history_service_factory.h"
#include "chrome/browser/signin/account_reconcilor_factory.h"
#include "chrome/browser/signin/identity_manager_factory.h"
@@ -26,6 +27,7 @@
#include "chrome/common/channel_info.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/pref_names.h"
+#include "components/browsing_data/core/browsing_data_utils.h"
#include "components/browsing_data/core/history_notice_utils.h"
#include "components/browsing_data/core/pref_names.h"
#include "components/feature_engagement/buildflags.h"
@@ -48,6 +50,7 @@ using BrowsingDataType = browsing_data::BrowsingDataType;
namespace {
const int kMaxTimesHistoryNoticeShown = 1;
+const int kMaxInstalledAppsToWarnOf = 5;
// TODO(msramek): Get the list of deletion preferences from the JS side.
const char* kCounterPrefsAdvanced[] = {
@@ -66,14 +69,20 @@ const char* kCounterPrefsBasic[] = {
browsing_data::prefs::kDeleteCacheBasic,
};
+const char kRegisterableDomainField[] = "registerableDomain";
+const char kReasonBitfieldField[] = "reasonBitfield";
+const char kIsCheckedField[] = "isChecked";
+const char kAppName[] = "appName";
+
} // namespace
namespace settings {
// ClearBrowsingDataHandler ----------------------------------------------------
-ClearBrowsingDataHandler::ClearBrowsingDataHandler(content::WebUI* webui)
- : profile_(Profile::FromWebUI(webui)),
+ClearBrowsingDataHandler::ClearBrowsingDataHandler(content::WebUI* webui,
+ Profile* profile)
+ : profile_(profile),
sync_service_(ProfileSyncServiceFactory::GetForProfile(profile_)),
sync_service_observer_(this),
show_history_deletion_dialog_(false) {}
@@ -83,6 +92,11 @@ ClearBrowsingDataHandler::~ClearBrowsingDataHandler() {
void ClearBrowsingDataHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(
+ "getInstalledApps",
+ base::BindRepeating(
+ &ClearBrowsingDataHandler::GetRecentlyLaunchedInstalledApps,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
"clearBrowsingData",
base::BindRepeating(&ClearBrowsingDataHandler::HandleClearBrowsingData,
base::Unretained(this)));
@@ -137,16 +151,99 @@ void ClearBrowsingDataHandler::HandleClearBrowsingDataForTest() {
std::make_unique<base::ListValue>();
data_types->AppendString("browser.clear_data.browsing_history");
+ std::unique_ptr<base::ListValue> installed_apps =
+ std::make_unique<base::ListValue>();
+
base::ListValue list_args;
list_args.AppendString("webui_callback_id");
list_args.Append(std::move(data_types));
list_args.AppendInteger(1u);
+ list_args.Append(std::move(installed_apps));
HandleClearBrowsingData(&list_args);
}
+void ClearBrowsingDataHandler::GetRecentlyLaunchedInstalledApps(
+ const base::ListValue* args) {
+ CHECK_EQ(2U, args->GetSize());
+ std::string webui_callback_id;
+ int period_selected;
+ CHECK(args->GetString(0, &webui_callback_id));
+
+ CHECK(args->GetInteger(1, &period_selected));
+ browsing_data::TimePeriod time_period =
+ static_cast<browsing_data::TimePeriod>(period_selected);
+
+ auto installed_apps = ImportantSitesUtil::GetInstalledRegisterableDomains(
+ time_period, profile_, kMaxInstalledAppsToWarnOf);
+
+ OnGotInstalledApps(webui_callback_id, installed_apps);
+}
+
+void ClearBrowsingDataHandler::OnGotInstalledApps(
+ const std::string& webui_callback_id,
+ const std::vector<ImportantSitesUtil::ImportantDomainInfo>&
+ installed_apps) {
+ base::ListValue installed_apps_list;
+ for (const auto& info : installed_apps) {
+ auto entry = std::make_unique<base::DictionaryValue>();
+ // Used to get favicon in ClearBrowsingDataDialog and display URL next to
+ // app name in the dialog.
+ entry->SetString(kRegisterableDomainField, info.registerable_domain);
+ // The |reason_bitfield| is only passed to Javascript to be logged
+ // from |HandleClearBrowsingData|.
+ entry->SetInteger(kReasonBitfieldField, info.reason_bitfield);
+ // Initially all sites are selected for deletion.
+ entry->SetBoolean(kIsCheckedField, true);
+ // User friendly name for the installed app.
+ DCHECK(info.app_name);
+ entry->SetString(kAppName, info.app_name.value());
+ installed_apps_list.Append(std::move(entry));
+ }
+ ResolveJavascriptCallback(base::Value(webui_callback_id),
+ installed_apps_list);
+}
+
+std::unique_ptr<content::BrowsingDataFilterBuilder>
+ClearBrowsingDataHandler::ProcessInstalledApps(
+ const base::ListValue* installed_apps) {
+ std::vector<std::string> excluded_domains;
+ std::vector<int32_t> excluded_domain_reasons;
+ std::vector<std::string> ignored_domains;
+ std::vector<int32_t> ignored_domain_reasons;
+ for (const auto& item : *installed_apps) {
+ const base::DictionaryValue* site = nullptr;
+ CHECK(item.GetAsDictionary(&site));
+ bool is_checked = false;
+ CHECK(site->GetBoolean(kIsCheckedField, &is_checked));
+ std::string domain;
+ CHECK(site->GetString(kRegisterableDomainField, &domain));
+ int domain_reason = -1;
+ CHECK(site->GetInteger(kReasonBitfieldField, &domain_reason));
+ if (is_checked) { // Selected installed apps should be deleted.
+ ignored_domains.push_back(domain);
+ ignored_domain_reasons.push_back(domain_reason);
+ } else { // Unselected sites should be kept.
+ excluded_domains.push_back(domain);
+ excluded_domain_reasons.push_back(domain_reason);
+ }
+ }
+ if (!excluded_domains.empty() || !ignored_domains.empty()) {
+ ImportantSitesUtil::RecordBlacklistedAndIgnoredImportantSites(
+ profile_->GetOriginalProfile(), excluded_domains,
+ excluded_domain_reasons, ignored_domains, ignored_domain_reasons);
+ }
+
+ std::unique_ptr<content::BrowsingDataFilterBuilder> filter_builder(
+ content::BrowsingDataFilterBuilder::Create(
+ content::BrowsingDataFilterBuilder::BLACKLIST));
+ for (const std::string& domain : excluded_domains)
+ filter_builder->AddRegisterableDomain(domain);
+ return filter_builder;
+}
+
void ClearBrowsingDataHandler::HandleClearBrowsingData(
const base::ListValue* args) {
- CHECK_EQ(3U, args->GetSize());
+ CHECK_EQ(4U, args->GetSize());
std::string webui_callback_id;
CHECK(args->GetString(0, &webui_callback_id));
@@ -261,6 +358,11 @@ void ClearBrowsingDataHandler::HandleClearBrowsingData(
int period_selected;
CHECK(args->GetInteger(2, &period_selected));
+ const base::ListValue* installed_apps = nullptr;
+ CHECK(args->GetList(3, &installed_apps));
+ std::unique_ptr<content::BrowsingDataFilterBuilder> filter_builder =
+ ProcessInstalledApps(installed_apps);
+
content::BrowsingDataRemover* remover =
content::BrowserContext::GetBrowsingDataRemover(profile_);
@@ -272,10 +374,8 @@ void ClearBrowsingDataHandler::HandleClearBrowsingData(
static_cast<browsing_data::TimePeriod>(period_selected);
browsing_data_important_sites_util::Remove(
- remove_mask, origin_mask, time_period,
- content::BrowsingDataFilterBuilder::Create(
- content::BrowsingDataFilterBuilder::BLACKLIST),
- remover, std::move(callback));
+ remove_mask, origin_mask, time_period, std::move(filter_builder), remover,
+ std::move(callback));
#if BUILDFLAG(ENABLE_LEGACY_DESKTOP_IN_PRODUCT_HELP)
feature_engagement::IncognitoWindowTrackerFactory::GetInstance()
@@ -360,11 +460,10 @@ void ClearBrowsingDataHandler::RefreshHistoryNotice() {
if (notice_shown_times < kMaxTimesHistoryNoticeShown) {
browsing_data::ShouldPopupDialogAboutOtherFormsOfBrowsingHistory(
- sync_service_,
- WebHistoryServiceFactory::GetForProfile(profile_),
+ sync_service_, WebHistoryServiceFactory::GetForProfile(profile_),
chrome::GetChannel(),
- base::Bind(&ClearBrowsingDataHandler::UpdateHistoryDeletionDialog,
- weak_ptr_factory_.GetWeakPtr()));
+ base::BindOnce(&ClearBrowsingDataHandler::UpdateHistoryDeletionDialog,
+ weak_ptr_factory_.GetWeakPtr()));
}
}
diff --git a/chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h b/chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h
index 9434c788871..784812552ef 100644
--- a/chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h
@@ -12,6 +12,7 @@
#include "base/containers/flat_set.h"
#include "base/macros.h"
#include "base/scoped_observer.h"
+#include "chrome/browser/engagement/important_sites_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
#include "components/browsing_data/core/browsing_data_utils.h"
@@ -24,6 +25,7 @@ class ListValue;
}
namespace content {
+class BrowsingDataFilterBuilder;
class WebUI;
}
@@ -33,7 +35,7 @@ namespace settings {
class ClearBrowsingDataHandler : public SettingsPageUIHandler,
public syncer::SyncServiceObserver {
public:
- explicit ClearBrowsingDataHandler(content::WebUI* webui);
+ ClearBrowsingDataHandler(content::WebUI* webui, Profile* profile);
~ClearBrowsingDataHandler() override;
// WebUIMessageHandler implementation.
@@ -44,7 +46,24 @@ class ClearBrowsingDataHandler : public SettingsPageUIHandler,
// Calls |HandleClearBrowsingData| with test data for browser test.
void HandleClearBrowsingDataForTest();
+ protected:
+ // Fetches a list of installed apps to be displayed in the clear browsing
+ // data confirmation dialog. Called by Javascript.
+ void GetRecentlyLaunchedInstalledApps(const base::ListValue* args);
+
private:
+ // Respond to the WebUI callback with the list of installed apps.
+ void OnGotInstalledApps(
+ const std::string& webui_callback_id,
+ const std::vector<ImportantSitesUtil::ImportantDomainInfo>&
+ installed_apps);
+
+ // Build a filter of sites to include and exclude from site data removal
+ // based on whether installed apps were marked for deletion by the checkbox on
+ // the installed apps warning dialog.
+ std::unique_ptr<content::BrowsingDataFilterBuilder> ProcessInstalledApps(
+ const base::ListValue* installed_apps);
+
// Clears browsing data, called by Javascript.
void HandleClearBrowsingData(const base::ListValue* value);
diff --git a/chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler_browsertest.cc b/chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler_browsertest.cc
new file mode 100644
index 00000000000..98dca3b412e
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler_browsertest.cc
@@ -0,0 +1,110 @@
+// Copyright 2015 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 <memory>
+
+#include "chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h"
+
+#include "base/values.h"
+#include "chrome/browser/ui/web_applications/web_app_controller_browsertest.h"
+#include "chrome/common/webui_url_constants.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "content/public/browser/web_ui.h"
+#include "content/public/test/browser_test.h"
+#include "content/public/test/test_web_ui.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace {
+
+constexpr char kGetInstalledApps[] = "getInstalledApps";
+constexpr char kWebUiFunctionName[] = "webUiCallbackName";
+
+} // namespace
+
+namespace settings {
+
+class TestingClearBrowsingDataHandler : public ClearBrowsingDataHandler {
+ public:
+ TestingClearBrowsingDataHandler(content::WebUI* webui, Profile* profile)
+ : ClearBrowsingDataHandler(webui, profile) {
+ set_web_ui(webui);
+ }
+ TestingClearBrowsingDataHandler& operator=(
+ const TestingClearBrowsingDataHandler&) = delete;
+ TestingClearBrowsingDataHandler(const TestingClearBrowsingDataHandler&) =
+ delete;
+};
+
+class ClearBrowsingDataHandlerBrowserTest
+ : public web_app::WebAppControllerBrowserTest {
+ public:
+ ClearBrowsingDataHandlerBrowserTest() = default;
+ ~ClearBrowsingDataHandlerBrowserTest() = default;
+
+ void SetUpOnMainThread() override {
+ WebAppControllerBrowserTest::SetUpOnMainThread();
+
+ handler_ = std::make_unique<TestingClearBrowsingDataHandler>(
+ web_ui(), browser()->profile());
+ handler_->AllowJavascriptForTesting();
+ handler_->RegisterMessages();
+ }
+
+ void TearDownOnMainThread() override { handler_.reset(); }
+
+ protected:
+ web_app::AppId InstallAndLaunchApp(GURL& url) {
+ auto app_id = InstallPWA(url);
+
+ ui_test_utils::UrlLoadObserver url_observer(
+ url, content::NotificationService::AllSources());
+
+ auto* app_browser =
+ ClearBrowsingDataHandlerBrowserTest::LaunchWebAppBrowser(app_id);
+ url_observer.Wait();
+ DCHECK(app_browser);
+ DCHECK(app_browser != browser());
+
+ return app_id;
+ }
+
+ ClearBrowsingDataHandler* handler() { return handler_.get(); }
+ content::TestWebUI* web_ui() { return &web_ui_; }
+
+ private:
+ std::unique_ptr<ClearBrowsingDataHandler> handler_;
+ content::TestWebUI web_ui_;
+};
+
+IN_PROC_BROWSER_TEST_P(ClearBrowsingDataHandlerBrowserTest, GetInstalledApps) {
+ GURL url(https_server()->GetURL("/"));
+ InstallAndLaunchApp(url);
+ base::ListValue args;
+ args.AppendString(kWebUiFunctionName);
+ args.AppendInteger(1U);
+
+ web_ui()->HandleReceivedMessage(kGetInstalledApps, &args);
+ const content::TestWebUI::CallData& call_data = *web_ui()->call_data().back();
+ EXPECT_EQ("cr.webUIResponse", call_data.function_name());
+ EXPECT_EQ(kWebUiFunctionName, call_data.arg1()->GetString());
+ ASSERT_TRUE(call_data.arg2()->GetBool());
+
+ // Get results from JS callback.
+ const base::span<const base::Value> result = call_data.arg3()->GetList();
+ ASSERT_EQ(1U, result.size());
+ auto& installed_app = result.back();
+ ASSERT_EQ(url.host(), *(installed_app.FindStringKey("registerableDomain")));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ All,
+ ClearBrowsingDataHandlerBrowserTest,
+ ::testing::Values(
+ web_app::ControllerType::kHostedAppController,
+ web_app::ControllerType::kUnifiedControllerWithBookmarkApp,
+ web_app::ControllerType::kUnifiedControllerWithWebApp),
+ web_app::ControllerTypeParamToString);
+
+} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chromium/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
index 8dc520241ba..90189cf77f1 100644
--- a/chromium/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
+++ b/chromium/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -10,7 +10,6 @@
#include "base/feature_list.h"
#include "base/i18n/number_formatting.h"
#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/windows_version.h"
#include "build/branding_buildflags.h"
@@ -28,8 +27,8 @@
#include "chrome/browser/ui/passwords/manage_passwords_view_utils.h"
#include "chrome/browser/ui/webui/management_ui.h"
#include "chrome/browser/ui/webui/policy_indicator_localized_strings_provider.h"
+#include "chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.h"
#include "chrome/browser/ui/webui/webui_util.h"
-#include "chrome/common/channel_info.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/url_constants.h"
@@ -50,18 +49,20 @@
#include "components/autofill/core/common/autofill_payments_features.h"
#include "components/browsing_data/core/features.h"
#include "components/content_settings/core/common/features.h"
+#include "components/dom_distiller/core/dom_distiller_features.h"
#include "components/google/core/common/google_util.h"
#include "components/omnibox/common/omnibox_features.h"
+#include "components/password_manager/core/browser/leak_detection_dialog_utils.h"
#include "components/password_manager/core/browser/manage_passwords_referrer.h"
#include "components/password_manager/core/common/password_manager_features.h"
-#include "components/safe_browsing/common/safe_browsing_prefs.h"
+#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
#include "components/signin/public/base/signin_buildflags.h"
#include "components/strings/grit/components_strings.h"
#include "components/subresource_filter/core/browser/subresource_filter_features.h"
#include "components/sync/driver/sync_service.h"
#include "components/sync/driver/sync_service_utils.h"
#include "components/sync/driver/sync_user_settings.h"
-#include "components/version_info/version_info.h"
+#include "components/zoom/page_zoom_constants.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui_data_source.h"
#include "content/public/common/content_features.h"
@@ -74,42 +75,25 @@
#include "ui/accessibility/accessibility_switches.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/webui/web_ui_util.h"
+#include "ui/strings/grit/ui_strings.h"
#if defined(OS_CHROMEOS)
-#include "ash/public/cpp/ash_features.h"
#include "ash/public/cpp/ash_switches.h"
-#include "ash/public/mojom/assistant_state_controller.mojom.h"
#include "base/system/sys_info.h"
#include "chrome/browser/chromeos/account_manager/account_manager_util.h"
-#include "chrome/browser/chromeos/arc/arc_util.h"
#include "chrome/browser/chromeos/assistant/assistant_util.h"
-#include "chrome/browser/chromeos/crostini/crostini_features.h"
-#include "chrome/browser/chromeos/crostini/crostini_util.h"
#include "chrome/browser/chromeos/kerberos/kerberos_credentials_manager.h"
#include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.h"
#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h"
#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h"
#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
-#include "chrome/browser/policy/profile_policy_connector.h"
-#include "chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.h"
-#include "chrome/browser/ui/webui/chromeos/bluetooth_dialog_localized_strings_provider.h"
-#include "chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.h"
-#include "chrome/browser/ui/webui/chromeos/smb_shares/smb_shares_localized_strings_provider.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/webui_url_constants.h"
#include "chromeos/constants/chromeos_features.h"
-#include "chromeos/constants/chromeos_switches.h"
-#include "chromeos/services/assistant/public/features.h"
-#include "chromeos/services/multidevice_setup/public/cpp/url_provider.h"
-#include "chromeos/strings/grit/chromeos_strings.h"
#include "components/prefs/pref_service.h"
#include "components/user_manager/user_manager.h"
-#include "device/bluetooth/strings/grit/bluetooth_strings.h"
#include "ui/chromeos/devicetype_utils.h"
-#include "ui/chromeos/events/keyboard_layout_util.h"
-#include "ui/display/display_features.h"
-#include "ui/display/display_switches.h"
-#include "ui/display/manager/touch_device_manager.h"
#else
#include "chrome/browser/ui/webui/settings/system_handler.h"
#endif
@@ -129,7 +113,6 @@
#if defined(USE_NSS_CERTS)
#include "chrome/browser/ui/webui/certificate_manager_localized_strings_provider.h"
#endif
-
namespace settings {
namespace {
@@ -141,26 +124,6 @@ base::string16 GetHelpUrlWithBoard(const std::string& original_url) {
return base::ASCIIToUTF16(original_url +
"&b=" + base::SysInfo::GetLsbReleaseBoard());
}
-
-bool IsDeviceManaged() {
- policy::BrowserPolicyConnectorChromeOS* connector =
- g_browser_process->platform_part()->browser_policy_connector_chromeos();
- return connector->IsEnterpriseManaged();
-}
-
-bool IsProfileManaged(Profile* profile) {
- return profile->GetProfilePolicyConnector()->IsManaged();
-}
-
-bool ShouldEnableArcAdbSideloading() {
- // Only enable on supported devices per USE flag.
- if (!base::FeatureList::IsEnabled(
- chromeos::features::kArcAdbSideloadingFeature)) {
- return false;
- }
-
- return chrome::GetChannel() < version_info::Channel::BETA;
-}
#endif
void AddCommonStrings(content::WebUIDataSource* html_source, Profile* profile) {
@@ -175,11 +138,8 @@ void AddCommonStrings(content::WebUIDataSource* html_source, Profile* profile) {
{"confirm", IDS_CONFIRM},
{"continue", IDS_SETTINGS_CONTINUE},
{"controlledByExtension", IDS_SETTINGS_CONTROLLED_BY_EXTENSION},
+ {"custom", IDS_SETTINGS_CUSTOM},
{"delete", IDS_SETTINGS_DELETE},
-#if defined(OS_CHROMEOS)
- {"deviceOff", IDS_SETTINGS_DEVICE_OFF},
- {"deviceOn", IDS_SETTINGS_DEVICE_ON},
-#endif
{"disable", IDS_DISABLE},
{"done", IDS_DONE},
{"edit", IDS_SETTINGS_EDIT},
@@ -195,15 +155,24 @@ void AddCommonStrings(content::WebUIDataSource* html_source, Profile* profile) {
#endif
{"retry", IDS_SETTINGS_RETRY},
{"save", IDS_SAVE},
+ {"searchResultBubbleText", IDS_SEARCH_RESULT_BUBBLE_TEXT},
+ {"searchResultsBubbleText", IDS_SEARCH_RESULTS_BUBBLE_TEXT},
+ {"sentenceEnd", IDS_SENTENCE_END},
{"settings", IDS_SETTINGS_SETTINGS},
{"settingsAltPageTitle", IDS_SETTINGS_ALT_PAGE_TITLE},
{"subpageArrowRoleDescription", IDS_SETTINGS_SUBPAGE_BUTTON},
- {"toggleOn", IDS_SETTINGS_TOGGLE_ON},
- {"toggleOff", IDS_SETTINGS_TOGGLE_OFF},
{"notValid", IDS_SETTINGS_NOT_VALID},
{"notValidWebAddress", IDS_SETTINGS_NOT_VALID_WEB_ADDRESS},
{"notValidWebAddressForContentType",
IDS_SETTINGS_NOT_VALID_WEB_ADDRESS_FOR_CONTENT_TYPE},
+
+ // Common font related strings shown in a11y and appearance sections.
+ {"quickBrownFox", IDS_SETTINGS_QUICK_BROWN_FOX},
+ {"verySmall", IDS_SETTINGS_VERY_SMALL_FONT},
+ {"small", IDS_SETTINGS_SMALL_FONT},
+ {"medium", IDS_SETTINGS_MEDIUM_FONT},
+ {"large", IDS_SETTINGS_LARGE_FONT},
+ {"veryLarge", IDS_SETTINGS_VERY_LARGE_FONT},
};
AddLocalizedStringsBulk(html_source, kLocalizedStrings);
@@ -221,327 +190,66 @@ void AddCommonStrings(content::WebUIDataSource* html_source, Profile* profile) {
void AddA11yStrings(content::WebUIDataSource* html_source) {
static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"moreFeaturesLink", IDS_SETTINGS_MORE_FEATURES_LINK},
{"a11yPageTitle", IDS_SETTINGS_ACCESSIBILITY},
{"a11yWebStore", IDS_SETTINGS_ACCESSIBILITY_WEB_STORE},
+ {"moreFeaturesLinkDescription",
+ IDS_SETTINGS_MORE_FEATURES_LINK_DESCRIPTION},
{"accessibleImageLabelsTitle", IDS_SETTINGS_ACCESSIBLE_IMAGE_LABELS_TITLE},
{"accessibleImageLabelsSubtitle",
IDS_SETTINGS_ACCESSIBLE_IMAGE_LABELS_SUBTITLE},
- {"moreFeaturesLink", IDS_SETTINGS_MORE_FEATURES_LINK},
- {"moreFeaturesLinkDescription",
- IDS_SETTINGS_MORE_FEATURES_LINK_DESCRIPTION},
- {"captionsTitle", IDS_SETTINGS_CAPTIONS},
- {"captionsSettings", IDS_SETTINGS_CAPTIONS_SETTINGS},
- {"captionsPreview", IDS_SETTINGS_CAPTIONS_PREVIEW},
- {"captionsTextSize", IDS_SETTINGS_CAPTIONS_TEXT_SIZE},
- {"captionsTextFont", IDS_SETTINGS_CAPTIONS_TEXT_FONT},
- {"captionsTextColor", IDS_SETTINGS_CAPTIONS_TEXT_COLOR},
- {"captionsTextOpacity", IDS_SETTINGS_CAPTIONS_TEXT_OPACITY},
- {"captionsBackgroundOpacity", IDS_SETTINGS_CAPTIONS_BACKGROUND_OPACITY},
- {"captionsOpacityOpaque", IDS_SETTINGS_CAPTIONS_OPACITY_OPAQUE},
- {"captionsOpacitySemiTransparent",
- IDS_SETTINGS_CAPTIONS_OPACITY_SEMI_TRANSPARENT},
- {"captionsOpacityTransparent", IDS_SETTINGS_CAPTIONS_OPACITY_TRANSPARENT},
- {"captionsTextShadow", IDS_SETTINGS_CAPTIONS_TEXT_SHADOW},
- {"captionsTextShadowNone", IDS_SETTINGS_CAPTIONS_TEXT_SHADOW_NONE},
- {"captionsTextShadowRaised", IDS_SETTINGS_CAPTIONS_TEXT_SHADOW_RAISED},
- {"captionsTextShadowDepressed",
- IDS_SETTINGS_CAPTIONS_TEXT_SHADOW_DEPRESSED},
- {"captionsTextShadowUniform", IDS_SETTINGS_CAPTIONS_TEXT_SHADOW_UNIFORM},
- {"captionsTextShadowDropShadow",
- IDS_SETTINGS_CAPTIONS_TEXT_SHADOW_DROP_SHADOW},
- {"captionsBackgroundColor", IDS_SETTINGS_CAPTIONS_BACKGROUND_COLOR},
- {"captionsColorBlack", IDS_SETTINGS_CAPTIONS_COLOR_BLACK},
- {"captionsColorWhite", IDS_SETTINGS_CAPTIONS_COLOR_WHITE},
- {"captionsColorRed", IDS_SETTINGS_CAPTIONS_COLOR_RED},
- {"captionsColorGreen", IDS_SETTINGS_CAPTIONS_COLOR_GREEN},
- {"captionsColorBlue", IDS_SETTINGS_CAPTIONS_COLOR_BLUE},
- {"captionsColorYellow", IDS_SETTINGS_CAPTIONS_COLOR_YELLOW},
- {"captionsColorCyan", IDS_SETTINGS_CAPTIONS_COLOR_CYAN},
- {"captionsColorMagenta", IDS_SETTINGS_CAPTIONS_COLOR_MAGENTA},
- {"captionsDefaultSetting", IDS_SETTINGS_CAPTIONS_DEFAULT_SETTING},
{"settingsSliderRoleDescription",
IDS_SETTINGS_SLIDER_MIN_MAX_ARIA_ROLE_DESCRIPTION},
+ {"captionsEnableLiveCaptionTitle",
+ IDS_SETTINGS_CAPTIONS_ENABLE_LIVE_CAPTION_TITLE},
+ {"captionsEnableLiveCaptionSubtitle",
+ IDS_SETTINGS_CAPTIONS_ENABLE_LIVE_CAPTION_SUBTITLE},
#if defined(OS_CHROMEOS)
- {"optionsInMenuLabel", IDS_SETTINGS_OPTIONS_IN_MENU_LABEL},
- {"largeMouseCursorLabel", IDS_SETTINGS_LARGE_MOUSE_CURSOR_LABEL},
- {"largeMouseCursorSizeLabel", IDS_SETTINGS_LARGE_MOUSE_CURSOR_SIZE_LABEL},
- {"largeMouseCursorSizeDefaultLabel",
- IDS_SETTINGS_LARGE_MOUSE_CURSOR_SIZE_DEFAULT_LABEL},
- {"largeMouseCursorSizeLargeLabel",
- IDS_SETTINGS_LARGE_MOUSE_CURSOR_SIZE_LARGE_LABEL},
- {"highContrastLabel", IDS_SETTINGS_HIGH_CONTRAST_LABEL},
- {"stickyKeysLabel", IDS_SETTINGS_STICKY_KEYS_LABEL},
- {"chromeVoxLabel", IDS_SETTINGS_CHROMEVOX_LABEL},
- {"chromeVoxOptionsLabel", IDS_SETTINGS_CHROMEVOX_OPTIONS_LABEL},
- {"screenMagnifierLabel", IDS_SETTINGS_SCREEN_MAGNIFIER_LABEL},
- {"screenMagnifierZoomLabel", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_LABEL},
- {"dockedMagnifierLabel", IDS_SETTINGS_DOCKED_MAGNIFIER_LABEL},
- {"dockedMagnifierZoomLabel", IDS_SETTINGS_DOCKED_MAGNIFIER_ZOOM_LABEL},
- {"screenMagnifierZoom2x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_2_X},
- {"screenMagnifierZoom4x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_4_X},
- {"screenMagnifierZoom6x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_6_X},
- {"screenMagnifierZoom8x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_8_X},
- {"screenMagnifierZoom10x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_10_X},
- {"screenMagnifierZoom12x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_12_X},
- {"screenMagnifierZoom14x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_14_X},
- {"screenMagnifierZoom16x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_16_X},
- {"screenMagnifierZoom18x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_18_X},
- {"screenMagnifierZoom20x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_20_X},
- {"tapDraggingLabel", IDS_SETTINGS_TAP_DRAGGING_LABEL},
- {"clickOnStopLabel", IDS_SETTINGS_CLICK_ON_STOP_LABEL},
- {"delayBeforeClickLabel", IDS_SETTINGS_DELAY_BEFORE_CLICK_LABEL},
- {"delayBeforeClickExtremelyShort",
- IDS_SETTINGS_DELAY_BEFORE_CLICK_EXTREMELY_SHORT},
- {"delayBeforeClickVeryShort", IDS_SETTINGS_DELAY_BEFORE_CLICK_VERY_SHORT},
- {"delayBeforeClickShort", IDS_SETTINGS_DELAY_BEFORE_CLICK_SHORT},
- {"delayBeforeClickLong", IDS_SETTINGS_DELAY_BEFORE_CLICK_LONG},
- {"delayBeforeClickVeryLong", IDS_SETTINGS_DELAY_BEFORE_CLICK_VERY_LONG},
- {"autoclickRevertToLeftClick", IDS_SETTINGS_AUTOCLICK_REVERT_TO_LEFT_CLICK},
- {"autoclickStabilizeCursorPosition",
- IDS_SETTINGS_AUTOCLICK_STABILIZE_CURSOR_POSITION},
- {"autoclickMovementThresholdLabel",
- IDS_SETTINGS_AUTOCLICK_MOVEMENT_THRESHOLD_LABEL},
- {"autoclickMovementThresholdExtraSmall",
- IDS_SETTINGS_AUTOCLICK_MOVEMENT_THRESHOLD_EXTRA_SMALL},
- {"autoclickMovementThresholdSmall",
- IDS_SETTINGS_AUTOCLICK_MOVEMENT_THRESHOLD_SMALL},
- {"autoclickMovementThresholdDefault",
- IDS_SETTINGS_AUTOCLICK_MOVEMENT_THRESHOLD_DEFAULT},
- {"autoclickMovementThresholdLarge",
- IDS_SETTINGS_AUTOCLICK_MOVEMENT_THRESHOLD_LARGE},
- {"autoclickMovementThresholdExtraLarge",
- IDS_SETTINGS_AUTOCLICK_MOVEMENT_THRESHOLD_EXTRA_LARGE},
- {"dictationDescription", IDS_SETTINGS_ACCESSIBILITY_DICTATION_DESCRIPTION},
- {"dictationLabel", IDS_SETTINGS_ACCESSIBILITY_DICTATION_LABEL},
- {"onScreenKeyboardLabel", IDS_SETTINGS_ON_SCREEN_KEYBOARD_LABEL},
- {"monoAudioLabel", IDS_SETTINGS_MONO_AUDIO_LABEL},
- {"startupSoundLabel", IDS_SETTINGS_STARTUP_SOUND_LABEL},
- {"a11yExplanation", IDS_SETTINGS_ACCESSIBILITY_EXPLANATION},
- {"caretHighlightLabel",
- IDS_SETTINGS_ACCESSIBILITY_CARET_HIGHLIGHT_DESCRIPTION},
- {"cursorHighlightLabel",
- IDS_SETTINGS_ACCESSIBILITY_CURSOR_HIGHLIGHT_DESCRIPTION},
- {"focusHighlightLabel",
- IDS_SETTINGS_ACCESSIBILITY_FOCUS_HIGHLIGHT_DESCRIPTION},
- {"selectToSpeakTitle", IDS_SETTINGS_ACCESSIBILITY_SELECT_TO_SPEAK_TITLE},
- {"selectToSpeakDisabledDescription",
- IDS_SETTINGS_ACCESSIBILITY_SELECT_TO_SPEAK_DISABLED_DESCRIPTION},
- {"selectToSpeakDescription",
- IDS_SETTINGS_ACCESSIBILITY_SELECT_TO_SPEAK_DESCRIPTION},
- {"selectToSpeakDescriptionWithoutKeyboard",
- IDS_SETTINGS_ACCESSIBILITY_SELECT_TO_SPEAK_DESCRIPTION_WITHOUT_KEYBOARD},
- {"selectToSpeakOptionsLabel",
- IDS_SETTINGS_ACCESSIBILITY_SELECT_TO_SPEAK_OPTIONS_LABEL},
- {"switchAccessLabel", IDS_SETTINGS_ACCESSIBILITY_SWITCH_ACCESS_DESCRIPTION},
- {"switchAccessOptionsLabel",
- IDS_SETTINGS_ACCESSIBILITY_SWITCH_ACCESS_OPTIONS_LABEL},
- {"manageSwitchAccessSettings", IDS_SETTINGS_MANAGE_SWITCH_ACCESS_SETTINGS},
- {"switchAssignmentHeading", IDS_SETTINGS_SWITCH_ASSIGNMENT_HEADING},
- {"switchAssignOptionNone", IDS_SETTINGS_SWITCH_ASSIGN_OPTION_NONE},
- {"switchAssignOptionSpace", IDS_SETTINGS_SWITCH_ASSIGN_OPTION_SPACE},
- {"switchAssignOptionEnter", IDS_SETTINGS_SWITCH_ASSIGN_OPTION_ENTER},
- {"assignSelectSwitchLabel", IDS_SETTINGS_ASSIGN_SELECT_SWITCH_LABEL},
- {"assignNextSwitchLabel", IDS_SETTINGS_ASSIGN_NEXT_SWITCH_LABEL},
- {"assignPreviousSwitchLabel", IDS_SETTINGS_ASSIGN_PREVIOUS_SWITCH_LABEL},
- {"switchAccessAutoScanHeading",
- IDS_SETTINGS_SWITCH_ACCESS_AUTO_SCAN_HEADING},
- {"switchAccessAutoScanLabel", IDS_SETTINGS_SWITCH_ACCESS_AUTO_SCAN_LABEL},
- {"switchAccessAutoScanSpeedLabel",
- IDS_SETTINGS_SWITCH_ACCESS_AUTO_SCAN_SPEED_LABEL},
- {"switchAccessAutoScanKeyboardSpeedLabel",
- IDS_SETTINGS_SWITCH_ACCESS_AUTO_SCAN_KEYBOARD_SPEED_LABEL},
- {"durationInSeconds", IDS_SETTINGS_DURATION_IN_SECONDS},
{"manageAccessibilityFeatures",
IDS_SETTINGS_ACCESSIBILITY_MANAGE_ACCESSIBILITY_FEATURES},
- {"textToSpeechHeading", IDS_SETTINGS_ACCESSIBILITY_TEXT_TO_SPEECH_HEADING},
- {"displayHeading", IDS_SETTINGS_ACCESSIBILITY_DISPLAY_HEADING},
- {"displaySettingsTitle", IDS_SETTINGS_ACCESSIBILITY_DISPLAY_SETTINGS_TITLE},
- {"displaySettingsDescription",
- IDS_SETTINGS_ACCESSIBILITY_DISPLAY_SETTINGS_DESCRIPTION},
- {"appearanceSettingsTitle",
- IDS_SETTINGS_ACCESSIBILITY_APPEARANCE_SETTINGS_TITLE},
- {"appearanceSettingsDescription",
- IDS_SETTINGS_ACCESSIBILITY_APPEARANCE_SETTINGS_DESCRIPTION},
- {"keyboardAndTextInputHeading",
- IDS_SETTINGS_ACCESSIBILITY_KEYBOARD_AND_TEXT_INPUT_HEADING},
- {"keyboardSettingsTitle",
- IDS_SETTINGS_ACCESSIBILITY_KEYBOARD_SETTINGS_TITLE},
- {"keyboardSettingsDescription",
- IDS_SETTINGS_ACCESSIBILITY_KEYBOARD_SETTINGS_DESCRIPTION},
- {"mouseAndTouchpadHeading",
- IDS_SETTINGS_ACCESSIBILITY_MOUSE_AND_TOUCHPAD_HEADING},
- {"mouseSettingsTitle", IDS_SETTINGS_ACCESSIBILITY_MOUSE_SETTINGS_TITLE},
- {"mouseSettingsDescription",
- IDS_SETTINGS_ACCESSIBILITY_MOUSE_SETTINGS_DESCRIPTION},
- {"audioAndCaptionsHeading",
- IDS_SETTINGS_ACCESSIBILITY_AUDIO_AND_CAPTIONS_HEADING},
- {"additionalFeaturesTitle",
- IDS_SETTINGS_ACCESSIBILITY_ADDITIONAL_FEATURES_TITLE},
- {"manageTtsSettings", IDS_SETTINGS_MANAGE_TTS_SETTINGS},
- {"ttsSettingsLinkDescription", IDS_SETTINGS_TTS_LINK_DESCRIPTION},
- {"textToSpeechVoices", IDS_SETTINGS_TEXT_TO_SPEECH_VOICES},
- {"textToSpeechNoVoicesMessage",
- IDS_SETTINGS_TEXT_TO_SPEECH_NO_VOICES_MESSAGE},
- {"textToSpeechMoreLanguages", IDS_SETTINGS_TEXT_TO_SPEECH_MORE_LANGUAGES},
- {"textToSpeechProperties", IDS_SETTINGS_TEXT_TO_SPEECH_PROPERTIES},
- {"textToSpeechRate", IDS_SETTINGS_TEXT_TO_SPEECH_RATE},
- {"textToSpeechRateMinimumLabel",
- IDS_SETTINGS_TEXT_TO_SPEECH_RATE_MINIMUM_LABEL},
- {"textToSpeechRateMaximumLabel",
- IDS_SETTINGS_TEXT_TO_SPEECH_RATE_MAXIMUM_LABEL},
- {"textToSpeechPitch", IDS_SETTINGS_TEXT_TO_SPEECH_PITCH},
- {"textToSpeechPitchMinimumLabel",
- IDS_SETTINGS_TEXT_TO_SPEECH_PITCH_MINIMUM_LABEL},
- {"textToSpeechPitchMaximumLabel",
- IDS_SETTINGS_TEXT_TO_SPEECH_PITCH_MAXIMUM_LABEL},
- {"textToSpeechVolume", IDS_SETTINGS_TEXT_TO_SPEECH_VOLUME},
- {"textToSpeechVolumeMinimumLabel",
- IDS_SETTINGS_TEXT_TO_SPEECH_VOLUME_MINIMUM_LABEL},
- {"textToSpeechVolumeMaximumLabel",
- IDS_SETTINGS_TEXT_TO_SPEECH_VOLUME_MAXIMUM_LABEL},
- {"percentage", IDS_SETTINGS_PERCENTAGE},
- {"defaultPercentage", IDS_SETTINGS_DEFAULT_PERCENTAGE},
- {"textToSpeechPreviewHeading", IDS_SETTINGS_TEXT_TO_SPEECH_PREVIEW_HEADING},
- {"textToSpeechPreviewInputLabel",
- IDS_SETTINGS_TEXT_TO_SPEECH_PREVIEW_INPUT_LABEL},
- {"textToSpeechPreviewInput", IDS_SETTINGS_TEXT_TO_SPEECH_PREVIEW_INPUT},
- {"textToSpeechPreviewVoice", IDS_SETTINGS_TEXT_TO_SPEECH_PREVIEW_VOICE},
- {"textToSpeechPreviewPlay", IDS_SETTINGS_TEXT_TO_SPEECH_PREVIEW_PLAY},
- {"textToSpeechEngines", IDS_SETTINGS_TEXT_TO_SPEECH_ENGINES},
+ {"androidAppsManageAppLinks", IDS_SETTINGS_ANDROID_APPS_MANAGE_APP_LINKS},
#endif
};
AddLocalizedStringsBulk(html_source, kLocalizedStrings);
- html_source->AddBoolean(
- "showExperimentalA11yLabels",
- base::FeatureList::IsEnabled(features::kExperimentalAccessibilityLabels));
-
- html_source->AddBoolean(
- "enableCaptionSettings",
- base::FeatureList::IsEnabled(features::kCaptionSettings));
-
#if defined(OS_WIN)
html_source->AddBoolean("isWindows10OrNewer",
base::win::GetVersion() >= base::win::Version::WIN10);
#endif
-
-#if defined(OS_CHROMEOS)
- html_source->AddString("accountManagerLearnMoreUrl",
- chrome::kAccountManagerLearnMoreURL);
- html_source->AddString("a11yLearnMoreUrl",
- chrome::kChromeAccessibilityHelpURL);
-
- base::CommandLine& cmd = *base::CommandLine::ForCurrentProcess();
html_source->AddBoolean(
- "showExperimentalA11yFeatures",
- cmd.HasSwitch(::switches::kEnableExperimentalAccessibilityFeatures));
+ "showExperimentalA11yLabels",
+ base::FeatureList::IsEnabled(features::kExperimentalAccessibilityLabels));
- html_source->AddBoolean(
- "showExperimentalAccessibilitySwitchAccess",
- cmd.HasSwitch(::switches::kEnableExperimentalAccessibilitySwitchAccess));
+ html_source->AddBoolean("enableLiveCaption",
+ base::FeatureList::IsEnabled(media::kLiveCaption));
- html_source->AddBoolean(
- "showExperimentalAccessibilitySwitchAccessImprovedTextInput",
- cmd.HasSwitch(
- ::switches::kEnableExperimentalAccessibilitySwitchAccessText));
-#endif
+ AddCaptionSubpageStrings(html_source);
}
-void AddAboutStrings(content::WebUIDataSource* html_source) {
+void AddAboutStrings(content::WebUIDataSource* html_source, Profile* profile) {
+ // Top level About Page strings.
static constexpr webui::LocalizedString kLocalizedStrings[] = {
{"aboutProductLogoAlt", IDS_SHORT_PRODUCT_LOGO_ALT_TEXT},
-
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
{"aboutReportAnIssue", IDS_SETTINGS_ABOUT_PAGE_REPORT_AN_ISSUE},
#endif
-
{"aboutRelaunch", IDS_SETTINGS_ABOUT_PAGE_RELAUNCH},
{"aboutUpgradeCheckStarted", IDS_SETTINGS_ABOUT_UPGRADE_CHECK_STARTED},
{"aboutUpgradeRelaunch", IDS_SETTINGS_UPGRADE_SUCCESSFUL_RELAUNCH},
{"aboutUpgradeUpdating", IDS_SETTINGS_UPGRADE_UPDATING},
{"aboutUpgradeUpdatingPercent", IDS_SETTINGS_UPGRADE_UPDATING_PERCENT},
-
+ {"aboutGetHelpUsingChrome", IDS_SETTINGS_GET_HELP_USING_CHROME},
+ {"aboutPageTitle", IDS_SETTINGS_ABOUT_PROGRAM},
+ {"aboutProductTitle", IDS_PRODUCT_NAME},
#if defined(OS_CHROMEOS)
- {"aboutBuildDetailsTitle", IDS_OS_SETTINGS_ABOUT_PAGE_BUILD_DETAILS},
- {"aboutChannelBeta", IDS_SETTINGS_ABOUT_PAGE_CURRENT_CHANNEL_BETA},
- {"aboutChannelCanary", IDS_SETTINGS_ABOUT_PAGE_CURRENT_CHANNEL_CANARY},
- {"aboutChannelDev", IDS_SETTINGS_ABOUT_PAGE_CURRENT_CHANNEL_DEV},
- {"aboutChannelLabel", IDS_SETTINGS_ABOUT_PAGE_CHANNEL},
- {"aboutChannelStable", IDS_SETTINGS_ABOUT_PAGE_CURRENT_CHANNEL_STABLE},
- {"aboutCheckForUpdates", IDS_SETTINGS_ABOUT_PAGE_CHECK_FOR_UPDATES},
- {"aboutCurrentlyOnChannel", IDS_SETTINGS_ABOUT_PAGE_CURRENT_CHANNEL},
- {"aboutDetailedBuildInfo", IDS_SETTINGS_ABOUT_PAGE_DETAILED_BUILD_INFO},
- {"aboutEndOfLifeTitle", IDS_SETTINGS_ABOUT_PAGE_END_OF_LIFE_TITLE},
- {"aboutRelaunchAndPowerwash",
- IDS_SETTINGS_ABOUT_PAGE_RELAUNCH_AND_POWERWASH},
- {"aboutRollbackInProgress", IDS_SETTINGS_UPGRADE_ROLLBACK_IN_PROGRESS},
- {"aboutRollbackSuccess", IDS_SETTINGS_UPGRADE_ROLLBACK_SUCCESS},
{"aboutUpdateOsSettingsLink",
IDS_SETTINGS_ABOUT_SEE_OS_SETTINGS_FOR_UPDATE_MESSAGE},
- {"aboutUpgradeUpdatingChannelSwitch",
- IDS_SETTINGS_UPGRADE_UPDATING_CHANNEL_SWITCH},
- {"aboutUpgradeSuccessChannelSwitch",
- IDS_SETTINGS_UPGRADE_SUCCESSFUL_CHANNEL_SWITCH},
- {"aboutTPMFirmwareUpdateTitle",
- IDS_SETTINGS_ABOUT_TPM_FIRMWARE_UPDATE_TITLE},
- {"aboutTPMFirmwareUpdateDescription",
- IDS_SETTINGS_ABOUT_TPM_FIRMWARE_UPDATE_DESCRIPTION},
-
- // About page, channel switcher dialog.
- {"aboutChangeChannel", IDS_SETTINGS_ABOUT_PAGE_CHANGE_CHANNEL},
- {"aboutChangeChannelAndPowerwash",
- IDS_SETTINGS_ABOUT_PAGE_CHANGE_CHANNEL_AND_POWERWASH},
- {"aboutDelayedWarningMessage",
- IDS_SETTINGS_ABOUT_PAGE_DELAYED_WARNING_MESSAGE},
- {"aboutDelayedWarningTitle", IDS_SETTINGS_ABOUT_PAGE_DELAYED_WARNING_TITLE},
- {"aboutPowerwashWarningMessage",
- IDS_SETTINGS_ABOUT_PAGE_POWERWASH_WARNING_MESSAGE},
- {"aboutPowerwashWarningTitle",
- IDS_SETTINGS_ABOUT_PAGE_POWERWASH_WARNING_TITLE},
- {"aboutUnstableWarningMessage",
- IDS_SETTINGS_ABOUT_PAGE_UNSTABLE_WARNING_MESSAGE},
- {"aboutUnstableWarningTitle",
- IDS_SETTINGS_ABOUT_PAGE_UNSTABLE_WARNING_TITLE},
- {"aboutChannelDialogBeta", IDS_SETTINGS_ABOUT_PAGE_DIALOG_CHANNEL_BETA},
- {"aboutChannelDialogDev", IDS_SETTINGS_ABOUT_PAGE_DIALOG_CHANNEL_DEV},
- {"aboutChannelDialogStable", IDS_SETTINGS_ABOUT_PAGE_DIALOG_CHANNEL_STABLE},
-
- // About page, update warning dialog.
- {"aboutUpdateWarningMessage",
- IDS_SETTINGS_ABOUT_PAGE_UPDATE_WARNING_MESSAGE},
- {"aboutUpdateWarningTitle", IDS_SETTINGS_ABOUT_PAGE_UPDATE_WARNING_TITLE},
-#endif // defined(OS_CHROMEOS)
+#endif
};
AddLocalizedStringsBulk(html_source, kLocalizedStrings);
-#if defined(OS_CHROMEOS)
- html_source->AddLocalizedString("aboutOsPageTitle", IDS_SETTINGS_ABOUT_OS);
- html_source->AddLocalizedString("aboutGetHelpUsingChromeOs",
- IDS_SETTINGS_GET_HELP_USING_CHROME_OS);
- html_source->AddLocalizedString("aboutOsProductTitle", IDS_PRODUCT_OS_NAME);
- html_source->AddLocalizedString("aboutReleaseNotesOffline",
- IDS_SETTINGS_ABOUT_PAGE_RELEASE_NOTES);
- html_source->AddLocalizedString("aboutShowReleaseNotes",
- IDS_SETTINGS_ABOUT_PAGE_SHOW_RELEASE_NOTES);
- if (base::FeatureList::IsEnabled(chromeos::features::kSplitSettings)) {
- html_source->AddLocalizedString("aboutGetHelpUsingChrome",
- IDS_SETTINGS_GET_HELP_USING_CHROME);
- html_source->AddLocalizedString("aboutPageTitle",
- IDS_SETTINGS_ABOUT_PROGRAM);
- html_source->AddLocalizedString("aboutProductTitle", IDS_PRODUCT_NAME);
- } else {
- html_source->AddLocalizedString("aboutGetHelpUsingChrome",
- IDS_SETTINGS_GET_HELP_USING_CHROME_OS);
- html_source->AddLocalizedString("aboutPageTitle", IDS_SETTINGS_ABOUT_OS);
- html_source->AddLocalizedString("aboutProductTitle", IDS_PRODUCT_OS_NAME);
- }
-#else
- html_source->AddLocalizedString("aboutGetHelpUsingChrome",
- IDS_SETTINGS_GET_HELP_USING_CHROME);
- html_source->AddLocalizedString("aboutPageTitle", IDS_SETTINGS_ABOUT_PROGRAM);
- html_source->AddLocalizedString("aboutProductTitle", IDS_PRODUCT_NAME);
-#endif
-
+ html_source->AddString("managementPage",
+ ManagementUI::GetManagementPageSubtitle(profile));
html_source->AddString(
"aboutUpgradeUpToDate",
#if defined(OS_CHROMEOS)
@@ -549,200 +257,7 @@ void AddAboutStrings(content::WebUIDataSource* html_source) {
#else
l10n_util::GetStringUTF16(IDS_SETTINGS_UPGRADE_UP_TO_DATE));
#endif
-
-#if defined(OS_CHROMEOS)
- html_source->AddString("aboutTPMFirmwareUpdateLearnMoreURL",
- chrome::kTPMFirmwareUpdateLearnMoreURL);
-#endif
-}
-
-#if defined(OS_CHROMEOS)
-void AddCrostiniStrings(content::WebUIDataSource* html_source,
- Profile* profile) {
- static constexpr webui::LocalizedString kLocalizedStrings[] = {
- {"crostiniPageTitle", IDS_SETTINGS_CROSTINI_TITLE},
- {"crostiniPageLabel", IDS_SETTINGS_CROSTINI_LABEL},
- {"crostiniEnable", IDS_SETTINGS_TURN_ON},
- {"crostiniSharedPaths", IDS_SETTINGS_CROSTINI_SHARED_PATHS},
- {"crostiniSharedPathsListHeading",
- IDS_SETTINGS_CROSTINI_SHARED_PATHS_LIST_HEADING},
- {"crostiniSharedPathsInstructionsAdd",
- IDS_SETTINGS_CROSTINI_SHARED_PATHS_INSTRUCTIONS_ADD},
- {"crostiniSharedPathsInstructionsRemove",
- IDS_SETTINGS_CROSTINI_SHARED_PATHS_INSTRUCTIONS_REMOVE},
- {"crostiniSharedPathsRemoveSharing",
- IDS_SETTINGS_CROSTINI_SHARED_PATHS_REMOVE_SHARING},
- {"crostiniExportImportTitle", IDS_SETTINGS_CROSTINI_EXPORT_IMPORT_TITLE},
- {"crostiniExport", IDS_SETTINGS_CROSTINI_EXPORT},
- {"crostiniExportLabel", IDS_SETTINGS_CROSTINI_EXPORT_LABEL},
- {"crostiniImport", IDS_SETTINGS_CROSTINI_IMPORT},
- {"crostiniImportLabel", IDS_SETTINGS_CROSTINI_IMPORT_LABEL},
- {"crostiniImportConfirmationDialogTitle",
- IDS_SETTINGS_CROSTINI_CONFIRM_IMPORT_DIALOG_WINDOW_TITLE},
- {"crostiniImportConfirmationDialogMessage",
- IDS_SETTINGS_CROSTINI_CONFIRM_IMPORT_DIALOG_WINDOW_MESSAGE},
- {"crostiniImportConfirmationDialogConfirmationButton",
- IDS_SETTINGS_CROSTINI_IMPORT},
- {"crostiniRemoveButton", IDS_SETTINGS_CROSTINI_REMOVE_BUTTON},
- {"crostiniSharedUsbDevicesLabel",
- IDS_SETTINGS_CROSTINI_SHARED_USB_DEVICES_LABEL},
- {"crostiniSharedUsbDevicesDescription",
- IDS_SETTINGS_CROSTINI_SHARED_USB_DEVICES_DESCRIPTION},
- {"crostiniSharedUsbDevicesExtraDescription",
- IDS_SETTINGS_CROSTINI_SHARED_USB_DEVICES_EXTRA_DESCRIPTION},
- {"crostiniSharedUsbDevicesListEmptyMessage",
- IDS_SETTINGS_CROSTINI_SHARED_USB_DEVICES_LIST_EMPTY_MESSAGE},
- {"crostiniArcAdbTitle", IDS_SETTINGS_CROSTINI_ARC_ADB_TITLE},
- {"crostiniArcAdbDescription", IDS_SETTINGS_CROSTINI_ARC_ADB_DESCRIPTION},
- {"crostiniArcAdbLabel", IDS_SETTINGS_CROSTINI_ARC_ADB_LABEL},
- {"crostiniArcAdbRestartButton",
- IDS_SETTINGS_CROSTINI_ARC_ADB_RESTART_BUTTON},
- {"crostiniArcAdbConfirmationTitleEnable",
- IDS_SETTINGS_CROSTINI_ARC_ADB_CONFIRMATION_TITLE_ENABLE},
- {"crostiniArcAdbConfirmationTitleDisable",
- IDS_SETTINGS_CROSTINI_ARC_ADB_CONFIRMATION_TITLE_DISABLE},
- };
- AddLocalizedStringsBulk(html_source, kLocalizedStrings);
- html_source->AddString(
- "crostiniSubtext",
- l10n_util::GetStringFUTF16(
- IDS_SETTINGS_CROSTINI_SUBTEXT, ui::GetChromeOSDeviceName(),
- GetHelpUrlWithBoard(chrome::kLinuxAppsLearnMoreURL)));
- // TODO(crbug.com/893332): replace with the final URL
- html_source->AddString(
- "crostiniArcAdbPowerwashRequiredSublabel",
- l10n_util::GetStringFUTF16(
- IDS_SETTINGS_CROSTINI_ARC_ADB_POWERWASH_REQUIRED_SUBLABEL,
- GetHelpUrlWithBoard(chrome::kLinuxAppsLearnMoreURL)));
- html_source->AddString("crostiniRemove", l10n_util::GetStringFUTF16(
- IDS_SETTINGS_CROSTINI_REMOVE,
- ui::GetChromeOSDeviceName()));
- html_source->AddString(
- "crostiniArcAdbConfirmationMessageEnable",
- l10n_util::GetStringFUTF16(
- IDS_SETTINGS_CROSTINI_ARC_ADB_CONFIRMATION_MESSAGE_ENABLE,
- ui::GetChromeOSDeviceName()));
- html_source->AddString(
- "crostiniArcAdbConfirmationMessageDisable",
- l10n_util::GetStringFUTF16(
- IDS_SETTINGS_CROSTINI_ARC_ADB_CONFIRMATION_MESSAGE_DISABLE,
- ui::GetChromeOSDeviceName()));
- html_source->AddString(
- "crostiniSharedPathsInstructionsLocate",
- l10n_util::GetStringFUTF16(
- IDS_SETTINGS_CROSTINI_SHARED_PATHS_INSTRUCTIONS_LOCATE,
- base::ASCIIToUTF16(
- crostini::ContainerChromeOSBaseDirectory().value())));
- html_source->AddBoolean(
- "showCrostiniExportImport",
- crostini::CrostiniFeatures::Get()->IsExportImportUIAllowed(profile));
- html_source->AddBoolean("ArcAdbSideloadingSupported",
- ShouldEnableArcAdbSideloading());
- html_source->AddBoolean("isOwnerProfile",
- chromeos::ProfileHelper::IsOwnerProfile(profile));
- html_source->AddBoolean("isEnterpriseManaged",
- IsDeviceManaged() || IsProfileManaged(profile));
-}
-
-void AddPluginVmStrings(content::WebUIDataSource* html_source,
- Profile* profile) {
- static constexpr webui::LocalizedString kLocalizedStrings[] = {
- {"pluginVmPageTitle", IDS_SETTINGS_PLUGIN_VM_PAGE_TITLE},
- {"pluginVmPageLabel", IDS_SETTINGS_PLUGIN_VM_PAGE_LABEL},
- {"pluginVmPageSubtext", IDS_SETTINGS_PLUGIN_VM_PAGE_SUBTEXT},
- {"pluginVmPrinterAccess", IDS_SETTINGS_PLUGIN_VM_PRINTER_ACCESS},
- {"pluginVmSharedPaths", IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS},
- {"pluginVmSharedPathsListHeading",
- IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS_LIST_HEADING},
- {"pluginVmSharedPathsInstructionsAdd",
- IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS_INSTRUCTIONS_ADD},
- {"pluginVmSharedPathsInstructionsRemove",
- IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS_INSTRUCTIONS_REMOVE},
- {"pluginVmSharedPathsRemoveSharing",
- IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS_REMOVE_SHARING},
- };
- AddLocalizedStringsBulk(html_source, kLocalizedStrings);
-}
-
-void AddAndroidAppStrings(content::WebUIDataSource* html_source) {
- static constexpr webui::LocalizedString kLocalizedStrings[] = {
- {"androidAppsPageLabel", IDS_SETTINGS_ANDROID_APPS_LABEL},
- {"androidAppsEnable", IDS_SETTINGS_TURN_ON},
- {"androidAppsManageApps", IDS_SETTINGS_ANDROID_APPS_MANAGE_APPS},
- {"androidAppsRemove", IDS_SETTINGS_ANDROID_APPS_REMOVE},
- {"androidAppsRemoveButton", IDS_SETTINGS_ANDROID_APPS_REMOVE_BUTTON},
- {"androidAppsDisableDialogTitle",
- IDS_SETTINGS_ANDROID_APPS_DISABLE_DIALOG_TITLE},
- {"androidAppsDisableDialogMessage",
- IDS_SETTINGS_ANDROID_APPS_DISABLE_DIALOG_MESSAGE},
- {"androidAppsDisableDialogRemove",
- IDS_SETTINGS_ANDROID_APPS_DISABLE_DIALOG_REMOVE},
- {"androidAppsManageAppLinks", IDS_SETTINGS_ANDROID_APPS_MANAGE_APP_LINKS},
- };
- AddLocalizedStringsBulk(html_source, kLocalizedStrings);
- html_source->AddLocalizedString("androidAppsPageTitle",
- arc::IsPlayStoreAvailable()
- ? IDS_SETTINGS_ANDROID_APPS_TITLE
- : IDS_SETTINGS_ANDROID_SETTINGS_TITLE);
- html_source->AddString(
- "androidAppsSubtext",
- l10n_util::GetStringFUTF16(
- IDS_SETTINGS_ANDROID_APPS_SUBTEXT, ui::GetChromeOSDeviceName(),
- GetHelpUrlWithBoard(chrome::kAndroidAppsLearnMoreURL)));
-}
-
-void AddAppsStrings(content::WebUIDataSource* html_source) {
- static constexpr webui::LocalizedString kLocalizedStrings[] = {
- {"appsPageTitle", IDS_SETTINGS_APPS_TITLE},
- {"appManagementTitle", IDS_SETTINGS_APPS_LINK_TEXT},
- };
-
- AddLocalizedStringsBulk(html_source, kLocalizedStrings);
-}
-
-void AddAppManagementStrings(content::WebUIDataSource* html_source) {
- static constexpr webui::LocalizedString kLocalizedStrings[] = {
- {"appManagementAppInstalledByPolicyLabel",
- IDS_APP_MANAGEMENT_POLICY_APP_POLICY_STRING},
- {"appManagementCameraPermissionLabel", IDS_APP_MANAGEMENT_CAMERA},
- {"appManagementContactsPermissionLabel", IDS_APP_MANAGEMENT_CONTACTS},
- {"appManagementLocationPermissionLabel", IDS_APP_MANAGEMENT_LOCATION},
- {"appManagementMicrophonePermissionLabel", IDS_APP_MANAGEMENT_MICROPHONE},
- {"appManagementMoreSettingsLabel", IDS_APP_MANAGEMENT_MORE_SETTINGS},
- {"appManagementNoAppsFound", IDS_APP_MANAGEMENT_NO_APPS_FOUND},
- {"appManagementNoPermissions",
- IDS_APPLICATION_INFO_APP_NO_PERMISSIONS_TEXT},
- {"appManagementNotificationsLabel", IDS_APP_MANAGEMENT_NOTIFICATIONS},
- {"appManagementPermissionsLabel", IDS_APP_MANAGEMENT_PERMISSIONS},
- {"appManagementPinToShelfLabel", IDS_APP_MANAGEMENT_PIN_TO_SHELF},
- {"appManagementSearchPrompt", IDS_APP_MANAGEMENT_SEARCH_PROMPT},
- {"appManagementStoragePermissionLabel", IDS_APP_MANAGEMENT_STORAGE},
- {"appManagementUninstallLabel", IDS_APP_MANAGEMENT_UNINSTALL_APP},
- };
- AddLocalizedStringsBulk(html_source, kLocalizedStrings);
-}
-#endif
-
-#if defined(OS_CHROMEOS)
-void AddParentalControlStrings(content::WebUIDataSource* html_source) {
- html_source->AddBoolean(
- "isChild", user_manager::UserManager::Get()->IsLoggedInAsChildUser());
- static constexpr webui::LocalizedString kLocalizedStrings[] = {
- {"parentalControlsPageTitle", IDS_SETTINGS_PARENTAL_CONTROLS_PAGE_TITLE},
- {"parentalControlsPageSetUpLabel",
- IDS_SETTINGS_PARENTAL_CONTROLS_PAGE_SET_UP_LABEL},
- {"parentalControlsPageViewSettingsLabel",
- IDS_SETTINGS_PARENTAL_CONTROLS_PAGE_VIEW_SETTINGS_LABEL},
- {"parentalControlsPageConnectToInternetLabel",
- IDS_SETTINGS_PARENTAL_CONTROLS_PAGE_CONNECT_TO_INTERNET_LABEL},
- {"parentalControlsSetUpButtonLabel",
- IDS_SETTINGS_PARENTAL_CONTROLS_SET_UP_BUTTON_LABEL},
- {"parentalControlsSetUpButtonRole",
- IDS_SETTINGS_PARENTAL_CONTROLS_SET_UP_BUTTON_ROLE},
- };
- AddLocalizedStringsBulk(html_source, kLocalizedStrings);
}
-#endif
void AddAppearanceStrings(content::WebUIDataSource* html_source,
Profile* profile) {
@@ -752,14 +267,6 @@ void AddAppearanceStrings(content::WebUIDataSource* html_source,
{"enterCustomWebAddress", IDS_SETTINGS_ENTER_CUSTOM_WEB_ADDRESS},
{"homeButtonDisabled", IDS_SETTINGS_HOME_BUTTON_DISABLED},
{"themes", IDS_SETTINGS_THEMES},
-#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
- {"systemTheme", IDS_SETTINGS_SYSTEM_THEME},
- {"useSystemTheme", IDS_SETTINGS_USE_SYSTEM_THEME},
- {"classicTheme", IDS_SETTINGS_CLASSIC_THEME},
- {"useClassicTheme", IDS_SETTINGS_USE_CLASSIC_THEME},
-#else
- {"resetToDefaultTheme", IDS_SETTINGS_RESET_TO_DEFAULT_THEME},
-#endif
{"chromeColors", IDS_SETTINGS_CHROME_COLORS},
{"showHomeButton", IDS_SETTINGS_SHOW_HOME_BUTTON},
{"showBookmarksBar", IDS_SETTINGS_SHOW_BOOKMARKS_BAR},
@@ -767,98 +274,39 @@ void AddAppearanceStrings(content::WebUIDataSource* html_source,
{"changeHomePage", IDS_SETTINGS_CHANGE_HOME_PAGE},
{"themesGalleryUrl", IDS_THEMES_GALLERY_URL},
{"chooseFromWebStore", IDS_SETTINGS_WEB_STORE},
-#if defined(OS_CHROMEOS)
- {"personalizationPageTitle", IDS_OS_SETTINGS_PERSONALIZATION},
- {"openWallpaperApp", IDS_OS_SETTINGS_OPEN_WALLPAPER_APP},
- {"setWallpaper", IDS_OS_SETTINGS_SET_WALLPAPER},
-#endif
+ {"pageZoom", IDS_SETTINGS_PAGE_ZOOM_LABEL},
+ {"fontSize", IDS_SETTINGS_FONT_SIZE_LABEL},
+ {"customizeFonts", IDS_SETTINGS_CUSTOMIZE_FONTS},
+ {"fonts", IDS_SETTINGS_FONTS},
+ {"standardFont", IDS_SETTINGS_STANDARD_FONT_LABEL},
+ {"serifFont", IDS_SETTINGS_SERIF_FONT_LABEL},
+ {"sansSerifFont", IDS_SETTINGS_SANS_SERIF_FONT_LABEL},
+ {"fixedWidthFont", IDS_SETTINGS_FIXED_WIDTH_FONT_LABEL},
+ {"minimumFont", IDS_SETTINGS_MINIMUM_FONT_SIZE_LABEL},
+ {"tiny", IDS_SETTINGS_TINY_FONT_SIZE},
+ {"huge", IDS_SETTINGS_HUGE_FONT_SIZE},
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+ {"systemTheme", IDS_SETTINGS_SYSTEM_THEME},
+ {"useSystemTheme", IDS_SETTINGS_USE_SYSTEM_THEME},
+ {"classicTheme", IDS_SETTINGS_CLASSIC_THEME},
+ {"useClassicTheme", IDS_SETTINGS_USE_CLASSIC_THEME},
{"showWindowDecorations", IDS_SHOW_WINDOW_DECORATIONS},
+#else
+ {"resetToDefaultTheme", IDS_SETTINGS_RESET_TO_DEFAULT_THEME},
#endif
#if defined(OS_MACOSX)
{"tabsToLinks", IDS_SETTINGS_TABS_TO_LINKS_PREF},
{"warnBeforeQuitting", IDS_SETTINGS_WARN_BEFORE_QUITTING_PREF},
#endif
+ {"readerMode", IDS_SETTINGS_READER_MODE},
+ {"readerModeDescription", IDS_SETTINGS_READER_MODE_DESCRIPTION},
};
AddLocalizedStringsBulk(html_source, kLocalizedStrings);
-#if defined(OS_CHROMEOS)
- if (base::FeatureList::IsEnabled(chromeos::features::kSplitSettings)) {
- html_source->AddLocalizedString("changePictureTitle",
- IDS_OS_SETTINGS_CHANGE_PICTURE_TITLE);
- } else {
- html_source->AddLocalizedString("changePictureTitle",
- IDS_SETTINGS_CHANGE_PICTURE_DIALOG_TITLE);
- }
-#endif
-}
-
-#if defined(OS_CHROMEOS)
-void AddBluetoothStrings(content::WebUIDataSource* html_source) {
- static constexpr webui::LocalizedString kLocalizedStrings[] = {
- {"bluetoothConnected", IDS_SETTINGS_BLUETOOTH_CONNECTED},
- {"bluetoothConnectedWithBattery",
- IDS_SETTINGS_BLUETOOTH_CONNECTED_WITH_BATTERY},
- {"bluetoothConnecting", IDS_SETTINGS_BLUETOOTH_CONNECTING},
- {"bluetoothDeviceListPaired", IDS_SETTINGS_BLUETOOTH_DEVICE_LIST_PAIRED},
- {"bluetoothDeviceListUnpaired",
- IDS_SETTINGS_BLUETOOTH_DEVICE_LIST_UNPAIRED},
- {"bluetoothConnect", IDS_SETTINGS_BLUETOOTH_CONNECT},
- {"bluetoothDisconnect", IDS_SETTINGS_BLUETOOTH_DISCONNECT},
- {"bluetoothToggleA11yLabel",
- IDS_SETTINGS_BLUETOOTH_TOGGLE_ACCESSIBILITY_LABEL},
- {"bluetoothExpandA11yLabel",
- IDS_SETTINGS_BLUETOOTH_EXPAND_ACCESSIBILITY_LABEL},
- {"bluetoothNoDevices", IDS_SETTINGS_BLUETOOTH_NO_DEVICES},
- {"bluetoothNoDevicesFound", IDS_SETTINGS_BLUETOOTH_NO_DEVICES_FOUND},
- {"bluetoothNotConnected", IDS_SETTINGS_BLUETOOTH_NOT_CONNECTED},
- {"bluetoothPageTitle", IDS_SETTINGS_BLUETOOTH},
- {"bluetoothPairDevicePageTitle",
- IDS_SETTINGS_BLUETOOTH_PAIR_DEVICE_TITLE},
- {"bluetoothRemove", IDS_SETTINGS_BLUETOOTH_REMOVE},
- {"bluetoothPrimaryUserControlled",
- IDS_SETTINGS_BLUETOOTH_PRIMARY_USER_CONTROLLED},
- {"bluetoothDeviceType_computer",
- IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_COMPUTER},
- {"bluetoothDeviceType_phone",
- IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_PHONE},
- {"bluetoothDeviceType_modem",
- IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_MODEM},
- {"bluetoothDeviceType_audio",
- IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_AUDIO},
- {"bluetoothDeviceType_carAudio",
- IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_CAR_AUDIO},
- {"bluetoothDeviceType_video",
- IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_VIDEO},
- {"bluetoothDeviceType_peripheral",
- IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_PERIPHERAL},
- {"bluetoothDeviceType_joystick",
- IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_JOYSTICK},
- {"bluetoothDeviceType_gamepad",
- IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_GAMEPAD},
- {"bluetoothDeviceType_keyboard",
- IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_KEYBOARD},
- {"bluetoothDeviceType_mouse",
- IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_MOUSE},
- {"bluetoothDeviceType_tablet",
- IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_TABLET},
- {"bluetoothDeviceType_keyboardMouseCombo",
- IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_KEYBOARD_MOUSE_COMBO},
- {"bluetoothDeviceType_unknown",
- IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_UNKNOWN},
- };
- AddLocalizedStringsBulk(html_source, kLocalizedStrings);
- chromeos::bluetooth_dialog::AddLocalizedStrings(html_source);
-}
-#endif
-
-void AddChangePasswordStrings(content::WebUIDataSource* html_source) {
- static constexpr webui::LocalizedString kLocalizedStrings[] = {
- {"changePasswordPageTitle", IDS_SETTINGS_CHANGE_PASSWORD_TITLE},
- {"changePasswordPageDetails", IDS_PAGE_INFO_CHANGE_PASSWORD_DETAILS},
- {"changePasswordPageButton", IDS_SETTINGS_CHANGE_PASSWORD_BUTTON},
- };
- AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+ html_source->AddString("presetZoomFactors",
+ zoom::GetPresetZoomFactorsAsJSON());
+ html_source->AddBoolean("showReaderModeOption",
+ dom_distiller::OfferReaderModeInSettings());
}
void AddClearBrowsingDataStrings(content::WebUIDataSource* html_source,
@@ -895,6 +343,8 @@ void AddClearBrowsingDataStrings(content::WebUIDataSource* html_source,
{"historyDeletionDialogTitle",
IDS_CLEAR_BROWSING_DATA_HISTORY_NOTICE_TITLE},
{"historyDeletionDialogOK", IDS_CLEAR_BROWSING_DATA_HISTORY_NOTICE_OK},
+ {"installedAppsConfirm", IDS_SETTINGS_CLEAR_INSTALLED_APPS_DATA_CONFIRM},
+ {"installedAppsTitle", IDS_SETTINGS_CLEAR_INSTALLED_APPS_DATA_TITLE},
{"notificationWarning", IDS_SETTINGS_NOTIFICATION_WARNING},
};
@@ -933,288 +383,12 @@ void AddDefaultBrowserStrings(content::WebUIDataSource* html_source) {
}
#endif
-#if defined(OS_CHROMEOS)
-void AddDeviceStrings(content::WebUIDataSource* html_source) {
- static constexpr webui::LocalizedString kDeviceStrings[] = {
- {"devicePageTitle", IDS_SETTINGS_DEVICE_TITLE},
- {"scrollLabel", IDS_SETTINGS_SCROLL_LABEL},
- {"traditionalScrollLabel", IDS_SETTINGS_TRADITIONAL_SCROLL_LABEL},
- {"naturalScrollLabel", IDS_SETTINGS_NATURAL_SCROLL_LABEL},
- {"naturalScrollLearnMore", IDS_LEARN_MORE},
- };
- AddLocalizedStringsBulk(html_source, kDeviceStrings);
-
- static constexpr webui::LocalizedString kPointersStrings[] = {
- {"mouseTitle", IDS_SETTINGS_MOUSE_TITLE},
- {"touchpadTitle", IDS_SETTINGS_TOUCHPAD_TITLE},
- {"mouseAndTouchpadTitle", IDS_SETTINGS_MOUSE_AND_TOUCHPAD_TITLE},
- {"touchpadTapToClickEnabledLabel",
- IDS_SETTINGS_TOUCHPAD_TAP_TO_CLICK_ENABLED_LABEL},
- {"touchpadSpeed", IDS_SETTINGS_TOUCHPAD_SPEED_LABEL},
- {"pointerSlow", IDS_SETTINGS_POINTER_SPEED_SLOW_LABEL},
- {"pointerFast", IDS_SETTINGS_POINTER_SPEED_FAST_LABEL},
- {"mouseSpeed", IDS_SETTINGS_MOUSE_SPEED_LABEL},
- {"mouseSwapButtons", IDS_SETTINGS_MOUSE_SWAP_BUTTONS_LABEL},
- {"mouseReverseScroll", IDS_SETTINGS_MOUSE_REVERSE_SCROLL_LABEL},
- {"mouseAccelerationLabel", IDS_SETTINGS_MOUSE_ACCELERATION_LABEL},
- {"touchpadAccelerationLabel", IDS_SETTINGS_TOUCHPAD_ACCELERATION_LABEL},
- };
- AddLocalizedStringsBulk(html_source, kPointersStrings);
-
- static constexpr webui::LocalizedString keyboard_strings[] = {
- {"keyboardTitle", IDS_SETTINGS_KEYBOARD_TITLE},
- {"keyboardKeyCtrl", IDS_SETTINGS_KEYBOARD_KEY_LEFT_CTRL},
- {"keyboardKeyAlt", IDS_SETTINGS_KEYBOARD_KEY_LEFT_ALT},
- {"keyboardKeyCapsLock", IDS_SETTINGS_KEYBOARD_KEY_CAPS_LOCK},
- {"keyboardKeyCommand", IDS_SETTINGS_KEYBOARD_KEY_COMMAND},
- {"keyboardKeyDiamond", IDS_SETTINGS_KEYBOARD_KEY_DIAMOND},
- {"keyboardKeyEscape", IDS_SETTINGS_KEYBOARD_KEY_ESCAPE},
- {"keyboardKeyBackspace", IDS_SETTINGS_KEYBOARD_KEY_BACKSPACE},
- {"keyboardKeyAssistant", IDS_SETTINGS_KEYBOARD_KEY_ASSISTANT},
- {"keyboardKeyDisabled", IDS_SETTINGS_KEYBOARD_KEY_DISABLED},
- {"keyboardKeyExternalCommand",
- IDS_SETTINGS_KEYBOARD_KEY_EXTERNAL_COMMAND},
- {"keyboardKeyExternalMeta", IDS_SETTINGS_KEYBOARD_KEY_EXTERNAL_META},
- {"keyboardKeyMeta", IDS_SETTINGS_KEYBOARD_KEY_META},
- {"keyboardSendFunctionKeys", IDS_SETTINGS_KEYBOARD_SEND_FUNCTION_KEYS},
- {"keyboardEnableAutoRepeat", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_ENABLE},
- {"keyRepeatDelay", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_DELAY},
- {"keyRepeatDelayLong", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_DELAY_LONG},
- {"keyRepeatDelayShort", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_DELAY_SHORT},
- {"keyRepeatRate", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_RATE},
- {"keyRepeatRateSlow", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_RATE_SLOW},
- {"keyRepeatRateFast", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_FAST},
- {"showKeyboardShortcutViewer",
- IDS_SETTINGS_KEYBOARD_SHOW_SHORTCUT_VIEWER},
- {"keyboardShowLanguageAndInput",
- IDS_SETTINGS_KEYBOARD_SHOW_LANGUAGE_AND_INPUT},
- };
- AddLocalizedStringsBulk(html_source, keyboard_strings);
- html_source->AddLocalizedString("keyboardKeySearch",
- ui::DeviceUsesKeyboardLayout2()
- ? IDS_SETTINGS_KEYBOARD_KEY_LAUNCHER
- : IDS_SETTINGS_KEYBOARD_KEY_SEARCH);
- html_source->AddLocalizedString(
- "keyboardSendFunctionKeysDescription",
- ui::DeviceUsesKeyboardLayout2()
- ? IDS_SETTINGS_KEYBOARD_SEND_FUNCTION_KEYS_LAYOUT2_DESCRIPTION
- : IDS_SETTINGS_KEYBOARD_SEND_FUNCTION_KEYS_DESCRIPTION);
-
- static constexpr webui::LocalizedString kStylusStrings[] = {
- {"stylusTitle", IDS_SETTINGS_STYLUS_TITLE},
- {"stylusEnableStylusTools", IDS_SETTINGS_STYLUS_ENABLE_STYLUS_TOOLS},
- {"stylusAutoOpenStylusTools", IDS_SETTINGS_STYLUS_AUTO_OPEN_STYLUS_TOOLS},
- {"stylusFindMoreAppsPrimary", IDS_SETTINGS_STYLUS_FIND_MORE_APPS_PRIMARY},
- {"stylusFindMoreAppsSecondary",
- IDS_SETTINGS_STYLUS_FIND_MORE_APPS_SECONDARY},
- {"stylusNoteTakingApp", IDS_SETTINGS_STYLUS_NOTE_TAKING_APP_LABEL},
- {"stylusNoteTakingAppEnabledOnLockScreen",
- IDS_SETTINGS_STYLUS_NOTE_TAKING_APP_LOCK_SCREEN_CHECKBOX},
- {"stylusNoteTakingAppKeepsLastNoteOnLockScreen",
- IDS_SETTINGS_STYLUS_NOTE_TAKING_APP_KEEP_LATEST_NOTE},
- {"stylusNoteTakingAppLockScreenSettingsHeader",
- IDS_SETTINGS_STYLUS_LOCK_SCREEN_NOTES_TITLE},
- {"stylusNoteTakingAppNoneAvailable",
- IDS_SETTINGS_STYLUS_NOTE_TAKING_APP_NONE_AVAILABLE},
- {"stylusNoteTakingAppWaitingForAndroid",
- IDS_SETTINGS_STYLUS_NOTE_TAKING_APP_WAITING_FOR_ANDROID}};
- AddLocalizedStringsBulk(html_source, kStylusStrings);
-
- static constexpr webui::LocalizedString kDisplayStrings[] = {
- {"displayTitle", IDS_SETTINGS_DISPLAY_TITLE},
- {"displayArrangementText", IDS_SETTINGS_DISPLAY_ARRANGEMENT_TEXT},
- {"displayArrangementTitle", IDS_SETTINGS_DISPLAY_ARRANGEMENT_TITLE},
- {"displayMirror", IDS_SETTINGS_DISPLAY_MIRROR},
- {"displayMirrorDisplayName", IDS_SETTINGS_DISPLAY_MIRROR_DISPLAY_NAME},
- {"displayAmbientColorTitle", IDS_SETTINGS_DISPLAY_AMBIENT_COLOR_TITLE},
- {"displayAmbientColorSubtitle",
- IDS_SETTINGS_DISPLAY_AMBIENT_COLOR_SUBTITLE},
- {"displayNightLightLabel", IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_LABEL},
- {"displayNightLightOnAtSunset",
- IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_ON_AT_SUNSET},
- {"displayNightLightOffAtSunrise",
- IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_OFF_AT_SUNRISE},
- {"displayNightLightScheduleCustom",
- IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_CUSTOM},
- {"displayNightLightScheduleLabel",
- IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_LABEL},
- {"displayNightLightScheduleNever",
- IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_NEVER},
- {"displayNightLightScheduleSunsetToSunRise",
- IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_SUNSET_TO_SUNRISE},
- {"displayNightLightStartTime",
- IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_START_TIME},
- {"displayNightLightStopTime", IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_STOP_TIME},
- {"displayNightLightText", IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEXT},
- {"displayNightLightTemperatureLabel",
- IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEMPERATURE_LABEL},
- {"displayNightLightTempSliderMaxLabel",
- IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEMP_SLIDER_MAX_LABEL},
- {"displayNightLightTempSliderMinLabel",
- IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEMP_SLIDER_MIN_LABEL},
- {"displayUnifiedDesktop", IDS_SETTINGS_DISPLAY_UNIFIED_DESKTOP},
- {"displayResolutionTitle", IDS_SETTINGS_DISPLAY_RESOLUTION_TITLE},
- {"displayResolutionText", IDS_SETTINGS_DISPLAY_RESOLUTION_TEXT},
- {"displayResolutionTextBest", IDS_SETTINGS_DISPLAY_RESOLUTION_TEXT_BEST},
- {"displayResolutionTextNative",
- IDS_SETTINGS_DISPLAY_RESOLUTION_TEXT_NATIVE},
- {"displayResolutionSublabel", IDS_SETTINGS_DISPLAY_RESOLUTION_SUBLABEL},
- {"displayResolutionMenuItem", IDS_SETTINGS_DISPLAY_RESOLUTION_MENU_ITEM},
- {"displayResolutionInterlacedMenuItem",
- IDS_SETTINGS_DISPLAY_RESOLUTION_INTERLACED_MENU_ITEM},
- {"displayZoomTitle", IDS_SETTINGS_DISPLAY_ZOOM_TITLE},
- {"displayZoomSublabel", IDS_SETTINGS_DISPLAY_ZOOM_SUBLABEL},
- {"displayZoomValue", IDS_SETTINGS_DISPLAY_ZOOM_VALUE},
- {"displayZoomLogicalResolutionText",
- IDS_SETTINGS_DISPLAY_ZOOM_LOGICAL_RESOLUTION_TEXT},
- {"displayZoomNativeLogicalResolutionNativeText",
- IDS_SETTINGS_DISPLAY_ZOOM_LOGICAL_RESOLUTION_NATIVE_TEXT},
- {"displayZoomLogicalResolutionDefaultText",
- IDS_SETTINGS_DISPLAY_ZOOM_LOGICAL_RESOLUTION_DEFAULT_TEXT},
- {"displaySizeSliderMinLabel", IDS_SETTINGS_DISPLAY_ZOOM_SLIDER_MINIMUM},
- {"displaySizeSliderMaxLabel", IDS_SETTINGS_DISPLAY_ZOOM_SLIDER_MAXIMUM},
- {"displayScreenTitle", IDS_SETTINGS_DISPLAY_SCREEN},
- {"displayScreenExtended", IDS_SETTINGS_DISPLAY_SCREEN_EXTENDED},
- {"displayScreenPrimary", IDS_SETTINGS_DISPLAY_SCREEN_PRIMARY},
- {"displayOrientation", IDS_SETTINGS_DISPLAY_ORIENTATION},
- {"displayOrientationStandard", IDS_SETTINGS_DISPLAY_ORIENTATION_STANDARD},
- {"displayOrientationAutoRotate",
- IDS_SETTINGS_DISPLAY_ORIENTATION_AUTO_ROTATE},
- {"displayOverscanPageText", IDS_SETTINGS_DISPLAY_OVERSCAN_TEXT},
- {"displayOverscanPageTitle", IDS_SETTINGS_DISPLAY_OVERSCAN_TITLE},
- {"displayOverscanSubtitle", IDS_SETTINGS_DISPLAY_OVERSCAN_SUBTITLE},
- {"displayOverscanInstructions",
- IDS_SETTINGS_DISPLAY_OVERSCAN_INSTRUCTIONS},
- {"displayOverscanResize", IDS_SETTINGS_DISPLAY_OVERSCAN_RESIZE},
- {"displayOverscanPosition", IDS_SETTINGS_DISPLAY_OVERSCAN_POSITION},
- {"displayOverscanReset", IDS_SETTINGS_DISPLAY_OVERSCAN_RESET},
- {"displayTouchCalibrationTitle",
- IDS_SETTINGS_DISPLAY_TOUCH_CALIBRATION_TITLE},
- {"displayTouchCalibrationText",
- IDS_SETTINGS_DISPLAY_TOUCH_CALIBRATION_TEXT}};
- AddLocalizedStringsBulk(html_source, kDisplayStrings);
- base::CommandLine& cmd = *base::CommandLine::ForCurrentProcess();
- html_source->AddBoolean("unifiedDesktopAvailable",
- cmd.HasSwitch(::switches::kEnableUnifiedDesktop));
-
- html_source->AddBoolean("listAllDisplayModes",
- display::features::IsListAllDisplayModesEnabled());
-
- html_source->AddBoolean("deviceSupportsAmbientColor",
- ash::features::IsAllowAmbientEQEnabled());
-
- html_source->AddBoolean(
- "enableTouchCalibrationSetting",
- cmd.HasSwitch(chromeos::switches::kEnableTouchCalibrationSetting));
-
- html_source->AddBoolean("hasExternalTouchDevice",
- display::HasExternalTouchscreenDevice());
-
- html_source->AddBoolean(
- "allowDisableMouseAcceleration",
- base::FeatureList::IsEnabled(features::kAllowDisableMouseAcceleration));
-
- static constexpr webui::LocalizedString kStorageStrings[] = {
- {"storageTitle", IDS_SETTINGS_STORAGE_TITLE},
- {"storageItemInUse", IDS_SETTINGS_STORAGE_ITEM_IN_USE},
- {"storageItemAvailable", IDS_SETTINGS_STORAGE_ITEM_AVAILABLE},
- {"storageItemDownloads", IDS_SETTINGS_STORAGE_ITEM_DOWNLOADS},
- {"storageItemBrowsingData", IDS_SETTINGS_STORAGE_ITEM_BROWSING_DATA},
- {"storageItemAndroid", IDS_SETTINGS_STORAGE_ITEM_ANDROID},
- {"storageItemCrostini", IDS_SETTINGS_STORAGE_ITEM_CROSTINI},
- {"storageItemOtherUsers", IDS_SETTINGS_STORAGE_ITEM_OTHER_USERS},
- {"storageSizeComputing", IDS_SETTINGS_STORAGE_SIZE_CALCULATING},
- {"storageSizeUnknown", IDS_SETTINGS_STORAGE_SIZE_UNKNOWN},
- {"storageSpaceLowMessageTitle",
- IDS_SETTINGS_STORAGE_SPACE_LOW_MESSAGE_TITLE},
- {"storageSpaceLowMessageLine1",
- IDS_SETTINGS_STORAGE_SPACE_LOW_MESSAGE_LINE_1},
- {"storageSpaceLowMessageLine2",
- IDS_SETTINGS_STORAGE_SPACE_LOW_MESSAGE_LINE_2},
- {"storageSpaceCriticallyLowMessageTitle",
- IDS_SETTINGS_STORAGE_SPACE_CRITICALLY_LOW_MESSAGE_TITLE},
- {"storageSpaceCriticallyLowMessageLine1",
- IDS_SETTINGS_STORAGE_SPACE_CRITICALLY_LOW_MESSAGE_LINE_1},
- {"storageSpaceCriticallyLowMessageLine2",
- IDS_SETTINGS_STORAGE_SPACE_CRITICALLY_LOW_MESSAGE_LINE_2},
- {"storageExternal", IDS_SETTINGS_STORAGE_EXTERNAL},
- {"storageExternalStorageEmptyListHeader",
- IDS_SETTINGS_STORAGE_EXTERNAL_STORAGE_EMPTY_LIST_HEADER},
- {"storageExternalStorageListHeader",
- IDS_SETTINGS_STORAGE_EXTERNAL_STORAGE_LIST_HEADER},
- {"storageOverviewAriaLabel", IDS_SETTINGS_STORAGE_OVERVIEW_ARIA_LABEL}};
-
- AddLocalizedStringsBulk(html_source, kStorageStrings);
-
- html_source->AddString(
- "storageAndroidAppsExternalDrivesNote",
- l10n_util::GetStringFUTF16(
- IDS_SETTINGS_STORAGE_ANDROID_APPS_ACCESS_EXTERNAL_DRIVES_NOTE,
- base::ASCIIToUTF16(chrome::kArcExternalStorageLearnMoreURL)));
-
- static constexpr webui::LocalizedString kPowerStrings[] = {
- {"powerTitle", IDS_SETTINGS_POWER_TITLE},
- {"powerSourceLabel", IDS_SETTINGS_POWER_SOURCE_LABEL},
- {"powerSourceBattery", IDS_SETTINGS_POWER_SOURCE_BATTERY},
- {"powerSourceAcAdapter", IDS_SETTINGS_POWER_SOURCE_AC_ADAPTER},
- {"powerSourceLowPowerCharger",
- IDS_SETTINGS_POWER_SOURCE_LOW_POWER_CHARGER},
- {"calculatingPower", IDS_SETTINGS_POWER_SOURCE_CALCULATING},
- {"powerIdleLabel", IDS_SETTINGS_POWER_IDLE_LABEL},
- {"powerIdleDisplayOffSleep", IDS_SETTINGS_POWER_IDLE_DISPLAY_OFF_SLEEP},
- {"powerIdleDisplayOff", IDS_SETTINGS_POWER_IDLE_DISPLAY_OFF},
- {"powerIdleDisplayOn", IDS_SETTINGS_POWER_IDLE_DISPLAY_ON},
- {"powerIdleOther", IDS_SETTINGS_POWER_IDLE_OTHER},
- {"powerLidSleepLabel", IDS_SETTINGS_POWER_LID_CLOSED_SLEEP_LABEL},
- {"powerLidSignOutLabel", IDS_SETTINGS_POWER_LID_CLOSED_SIGN_OUT_LABEL},
- {"powerLidShutDownLabel", IDS_SETTINGS_POWER_LID_CLOSED_SHUT_DOWN_LABEL},
- };
- AddLocalizedStringsBulk(html_source, kPowerStrings);
-
- html_source->AddString("naturalScrollLearnMoreLink",
- GetHelpUrlWithBoard(chrome::kNaturalScrollHelpURL));
-}
-
-void AddFilesStrings(content::WebUIDataSource* html_source) {
- static constexpr webui::LocalizedString kLocalizedStrings[] = {
- {"filesPageTitle", IDS_OS_SETTINGS_FILES},
- {"smbSharesTitle", IDS_SETTINGS_DOWNLOADS_SMB_SHARES},
- {"smbSharesLearnMoreLabel",
- IDS_SETTINGS_DOWNLOADS_SMB_SHARES_LEARN_MORE_LABEL},
- {"addSmbShare", IDS_SETTINGS_DOWNLOADS_SMB_SHARES_ADD_SHARE},
- {"smbShareAddedSuccessfulMessage",
- IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_SUCCESS_MESSAGE},
- {"smbShareAddedErrorMessage",
- IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_ERROR_MESSAGE},
- {"smbShareAddedAuthFailedMessage",
- IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_AUTH_FAILED_MESSAGE},
- {"smbShareAddedNotFoundMessage",
- IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_NOT_FOUND_MESSAGE},
- {"smbShareAddedUnsupportedDeviceMessage",
- IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_UNSUPPORTED_DEVICE_MESSAGE},
- {"smbShareAddedMountExistsMessage",
- IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_MOUNT_EXISTS_MESSAGE},
- {"smbShareAddedInvalidURLMessage",
- IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_MOUNT_INVALID_URL_MESSAGE},
- {"smbShareAddedInvalidSSOURLMessage",
- IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_MOUNT_INVALID_SSO_URL_MESSAGE},
- };
- AddLocalizedStringsBulk(html_source, kLocalizedStrings);
-
- chromeos::smb_dialog::AddLocalizedStrings(html_source);
-
- html_source->AddString("smbSharesLearnMoreURL",
- GetHelpUrlWithBoard(chrome::kSmbSharesLearnMoreURL));
-}
-#endif // defined(OS_CHROMEOS)
-
void AddDownloadsStrings(content::WebUIDataSource* html_source) {
static constexpr webui::LocalizedString kLocalizedStrings[] = {
{"downloadsPageTitle", IDS_SETTINGS_DOWNLOADS},
{"downloadLocation", IDS_SETTINGS_DOWNLOAD_LOCATION},
{"changeDownloadLocation", IDS_SETTINGS_CHANGE_DOWNLOAD_LOCATION},
{"promptForDownload", IDS_SETTINGS_PROMPT_FOR_DOWNLOAD},
- {"disconnectGoogleDriveAccount", IDS_SETTINGS_DISCONNECT_GOOGLE_DRIVE},
{"openFileTypesAutomatically",
IDS_SETTINGS_OPEN_FILE_TYPES_AUTOMATICALLY},
};
@@ -1364,15 +538,7 @@ void AddResetStrings(content::WebUIDataSource* html_source) {
{"triggeredResetPageTitle", IDS_TRIGGERED_RESET_PROFILE_SETTINGS_TITLE},
{"resetDialogCommit", IDS_SETTINGS_RESET},
{"resetPageFeedback", IDS_SETTINGS_RESET_PROFILE_FEEDBACK},
-#if defined(OS_CHROMEOS)
- {"powerwashTitle", IDS_SETTINGS_FACTORY_RESET},
- {"powerwashDialogTitle", IDS_SETTINGS_FACTORY_RESET_HEADING},
- {"powerwashDialogExplanation", IDS_SETTINGS_FACTORY_RESET_WARNING},
- {"powerwashDialogButton", IDS_SETTINGS_RESTART},
- {"powerwashLearnMoreUrl", IDS_FACTORY_RESET_HELP_URL},
- {"powerwashButton", IDS_SETTINGS_FACTORY_RESET_BUTTON_LABEL},
- {"powerwashButtonRoleDescription", IDS_SETTINGS_FACTORY_RESET_BUTTON_ROLE},
-#endif
+
// Automatic reset banner (now a dialog).
{"resetAutomatedDialogTitle", IDS_SETTINGS_RESET_AUTOMATED_DIALOG_TITLE},
{"resetProfileBannerButton", IDS_SETTINGS_RESET_BANNER_RESET_BUTTON_TEXT},
@@ -1388,12 +554,6 @@ void AddResetStrings(content::WebUIDataSource* html_source) {
chrome::kResetProfileSettingsLearnMoreURL);
html_source->AddString("resetProfileBannerLearnMoreUrl",
chrome::kAutomaticSettingsResetLearnMoreURL);
-#if defined(OS_CHROMEOS)
- html_source->AddString(
- "powerwashDescription",
- l10n_util::GetStringFUTF16(IDS_SETTINGS_FACTORY_RESET_DESCRIPTION,
- l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)));
-#endif
}
#if !defined(OS_CHROMEOS)
@@ -1418,242 +578,20 @@ void AddImportDataStrings(content::WebUIDataSource* html_source) {
}
#endif
-#if defined(OS_CHROMEOS)
-void AddDateTimeStrings(content::WebUIDataSource* html_source) {
- static constexpr webui::LocalizedString kLocalizedStrings[] = {
- {"dateTimePageTitle", IDS_SETTINGS_DATE_TIME},
- {"timeZone", IDS_SETTINGS_TIME_ZONE},
- {"selectTimeZoneResolveMethod",
- IDS_SETTINGS_SELECT_TIME_ZONE_RESOLVE_METHOD},
- {"timeZoneGeolocation", IDS_SETTINGS_TIME_ZONE_GEOLOCATION},
- {"timeZoneButton", IDS_SETTINGS_TIME_ZONE_BUTTON},
- {"timeZoneSubpageTitle", IDS_SETTINGS_TIME_ZONE_SUBPAGE_TITLE},
- {"setTimeZoneAutomaticallyDisabled",
- IDS_SETTINGS_TIME_ZONE_DETECTION_MODE_DISABLED},
- {"setTimeZoneAutomaticallyOn",
- IDS_SETTINGS_TIME_ZONE_DETECTION_SET_AUTOMATICALLY},
- {"setTimeZoneAutomaticallyOff",
- IDS_SETTINGS_TIME_ZONE_DETECTION_CHOOSE_FROM_LIST},
- {"setTimeZoneAutomaticallyIpOnlyDefault",
- IDS_SETTINGS_TIME_ZONE_DETECTION_MODE_IP_ONLY_DEFAULT},
- {"setTimeZoneAutomaticallyWithWiFiAccessPointsData",
- IDS_SETTINGS_TIME_ZONE_DETECTION_MODE_SEND_WIFI_AP},
- {"setTimeZoneAutomaticallyWithAllLocationInfo",
- IDS_SETTINGS_TIME_ZONE_DETECTION_MODE_SEND_ALL_INFO},
- {"use24HourClock", IDS_SETTINGS_USE_24_HOUR_CLOCK},
- {"setDateTime", IDS_SETTINGS_SET_DATE_TIME},
- };
- AddLocalizedStringsBulk(html_source, kLocalizedStrings);
- html_source->AddString(
- "timeZoneSettingsLearnMoreURL",
- base::ASCIIToUTF16(base::StringPrintf(
- chrome::kTimeZoneSettingsLearnMoreURL,
- g_browser_process->GetApplicationLocale().c_str())));
-}
-
-void AddEasyUnlockStrings(content::WebUIDataSource* html_source) {
- static constexpr webui::LocalizedString kLocalizedStrings[] = {
- {"easyUnlockSectionTitle", IDS_SETTINGS_EASY_UNLOCK_SECTION_TITLE},
- {"easyUnlockUnlockDeviceOnly",
- IDS_SETTINGS_EASY_UNLOCK_UNLOCK_DEVICE_ONLY},
- {"easyUnlockUnlockDeviceAndAllowSignin",
- IDS_SETTINGS_EASY_UNLOCK_UNLOCK_DEVICE_AND_ALLOW_SIGNIN},
- };
- AddLocalizedStringsBulk(html_source, kLocalizedStrings);
-}
-
-void AddFingerprintStrings(content::WebUIDataSource* html_source) {
- int instruction_id, aria_label_id;
- using FingerprintLocation = chromeos::quick_unlock::FingerprintLocation;
- switch (chromeos::quick_unlock::GetFingerprintLocation()) {
- case FingerprintLocation::TABLET_POWER_BUTTON:
- instruction_id =
- IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_POWER_BUTTON;
- aria_label_id =
- IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_POWER_BUTTON_ARIA_LABEL;
- break;
- case FingerprintLocation::KEYBOARD_TOP_RIGHT:
- instruction_id =
- IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD;
- aria_label_id =
- IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD_TOP_RIGHT_ARIA_LABEL;
- break;
- case FingerprintLocation::KEYBOARD_BOTTOM_RIGHT:
- instruction_id =
- IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD;
- aria_label_id =
- IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD_BOTTOM_RIGHT_ARIA_LABEL;
- break;
- }
- html_source->AddLocalizedString(
- "configureFingerprintInstructionLocateScannerStep", instruction_id);
- html_source->AddLocalizedString("configureFingerprintScannerStepAriaLabel",
- aria_label_id);
-}
-
-void AddInternetStrings(content::WebUIDataSource* html_source) {
- static constexpr webui::LocalizedString kLocalizedStrings[] = {
- {"internetAddConnection", IDS_SETTINGS_INTERNET_ADD_CONNECTION},
- {"internetAddConnectionExpandA11yLabel",
- IDS_SETTINGS_INTERNET_ADD_CONNECTION_EXPAND_ACCESSIBILITY_LABEL},
- {"internetAddConnectionNotAllowed",
- IDS_SETTINGS_INTERNET_ADD_CONNECTION_NOT_ALLOWED},
- {"internetAddThirdPartyVPN", IDS_SETTINGS_INTERNET_ADD_THIRD_PARTY_VPN},
- {"internetAddVPN", IDS_SETTINGS_INTERNET_ADD_VPN},
- {"internetAddWiFi", IDS_SETTINGS_INTERNET_ADD_WIFI},
- {"internetConfigName", IDS_SETTINGS_INTERNET_CONFIG_NAME},
- {"internetDetailPageTitle", IDS_SETTINGS_INTERNET_DETAIL},
- {"internetDeviceEnabling", IDS_SETTINGS_INTERNET_DEVICE_ENABLING},
- {"internetDeviceInitializing", IDS_SETTINGS_INTERNET_DEVICE_INITIALIZING},
- {"internetJoinType", IDS_SETTINGS_INTERNET_JOIN_TYPE},
- {"internetKnownNetworksPageTitle", IDS_SETTINGS_INTERNET_KNOWN_NETWORKS},
- {"internetMobileSearching", IDS_SETTINGS_INTERNET_MOBILE_SEARCH},
- {"internetNoNetworks", IDS_SETTINGS_INTERNET_NO_NETWORKS},
- {"internetPageTitle", IDS_SETTINGS_INTERNET},
- {"internetSummaryButtonA11yLabel",
- IDS_SETTINGS_INTERNET_SUMMARY_BUTTON_ACCESSIBILITY_LABEL},
- {"internetToggleMobileA11yLabel",
- IDS_SETTINGS_INTERNET_TOGGLE_MOBILE_ACCESSIBILITY_LABEL},
- {"internetToggleTetherLabel", IDS_SETTINGS_INTERNET_TOGGLE_TETHER_LABEL},
- {"internetToggleTetherSubtext",
- IDS_SETTINGS_INTERNET_TOGGLE_TETHER_SUBTEXT},
- {"internetToggleWiFiA11yLabel",
- IDS_SETTINGS_INTERNET_TOGGLE_WIFI_ACCESSIBILITY_LABEL},
- {"knownNetworksAll", IDS_SETTINGS_INTERNET_KNOWN_NETWORKS_ALL},
- {"knownNetworksButton", IDS_SETTINGS_INTERNET_KNOWN_NETWORKS_BUTTON},
- {"knownNetworksMessage", IDS_SETTINGS_INTERNET_KNOWN_NETWORKS_MESSAGE},
- {"knownNetworksPreferred",
- IDS_SETTINGS_INTERNET_KNOWN_NETWORKS_PREFFERED},
- {"knownNetworksMenuAddPreferred",
- IDS_SETTINGS_INTERNET_KNOWN_NETWORKS_MENU_ADD_PREFERRED},
- {"knownNetworksMenuRemovePreferred",
- IDS_SETTINGS_INTERNET_KNOWN_NETWORKS_MENU_REMOVE_PREFERRED},
- {"knownNetworksMenuForget",
- IDS_SETTINGS_INTERNET_KNOWN_NETWORKS_MENU_FORGET},
- {"networkAllowDataRoaming",
- IDS_SETTINGS_SETTINGS_NETWORK_ALLOW_DATA_ROAMING},
- {"networkAllowDataRoamingEnabledHome",
- IDS_SETTINGS_SETTINGS_NETWORK_ALLOW_DATA_ROAMING_ENABLED_HOME},
- {"networkAllowDataRoamingEnabledRoaming",
- IDS_SETTINGS_SETTINGS_NETWORK_ALLOW_DATA_ROAMING_ENABLED_ROAMING},
- {"networkAllowDataRoamingDisabled",
- IDS_SETTINGS_SETTINGS_NETWORK_ALLOW_DATA_ROAMING_DISABLED},
- {"networkAlwaysOnVpn", IDS_SETTINGS_INTERNET_NETWORK_ALWAYS_ON_VPN},
- {"networkAutoConnect", IDS_SETTINGS_INTERNET_NETWORK_AUTO_CONNECT},
- {"networkAutoConnectCellular",
- IDS_SETTINGS_INTERNET_NETWORK_AUTO_CONNECT_CELLULAR},
- {"networkButtonActivate", IDS_SETTINGS_INTERNET_BUTTON_ACTIVATE},
- {"networkButtonConfigure", IDS_SETTINGS_INTERNET_BUTTON_CONFIGURE},
- {"networkButtonConnect", IDS_SETTINGS_INTERNET_BUTTON_CONNECT},
- {"networkButtonDisconnect", IDS_SETTINGS_INTERNET_BUTTON_DISCONNECT},
- {"networkButtonForget", IDS_SETTINGS_INTERNET_BUTTON_FORGET},
- {"networkButtonViewAccount", IDS_SETTINGS_INTERNET_BUTTON_VIEW_ACCOUNT},
- {"networkConnectNotAllowed", IDS_SETTINGS_INTERNET_CONNECT_NOT_ALLOWED},
- {"networkIPAddress", IDS_SETTINGS_INTERNET_NETWORK_IP_ADDRESS},
- {"networkIPConfigAuto", IDS_SETTINGS_INTERNET_NETWORK_IP_CONFIG_AUTO},
- {"networkNameserversLearnMore", IDS_LEARN_MORE},
- {"networkPrefer", IDS_SETTINGS_INTERNET_NETWORK_PREFER},
- {"networkPrimaryUserControlled",
- IDS_SETTINGS_INTERNET_NETWORK_PRIMARY_USER_CONTROLLED},
- {"networkScanningLabel", IDS_NETWORK_SCANNING_MESSAGE},
- {"networkSectionAdvanced",
- IDS_SETTINGS_INTERNET_NETWORK_SECTION_ADVANCED},
- {"networkSectionAdvancedA11yLabel",
- IDS_SETTINGS_INTERNET_NETWORK_SECTION_ADVANCED_ACCESSIBILITY_LABEL},
- {"networkSectionNetwork", IDS_SETTINGS_INTERNET_NETWORK_SECTION_NETWORK},
- {"networkSectionNetworkExpandA11yLabel",
- IDS_SETTINGS_INTERNET_NETWORK_SECTION_NETWORK_ACCESSIBILITY_LABEL},
- {"networkSectionProxy", IDS_SETTINGS_INTERNET_NETWORK_SECTION_PROXY},
- {"networkSectionProxyExpandA11yLabel",
- IDS_SETTINGS_INTERNET_NETWORK_SECTION_PROXY_ACCESSIBILITY_LABEL},
- {"networkShared", IDS_SETTINGS_INTERNET_NETWORK_SHARED},
- {"networkVpnBuiltin", IDS_NETWORK_TYPE_VPN_BUILTIN},
- {"networkOutOfRange", IDS_SETTINGS_INTERNET_WIFI_NETWORK_OUT_OF_RANGE},
- {"cellularContactSpecificCarrier",
- IDS_SETTINGS_INTERNET_CELLULAR_CONTACT_SPECIFIC_CARRIER},
- {"cellularContactDefaultCarrier",
- IDS_SETTINGS_INTERNET_CELLULAR_CONTACT_DEFAULT_CARRIER},
- {"tetherPhoneOutOfRange",
- IDS_SETTINGS_INTERNET_TETHER_PHONE_OUT_OF_RANGE},
- {"gmscoreNotificationsTitle",
- IDS_SETTINGS_INTERNET_GMSCORE_NOTIFICATIONS_TITLE},
- {"gmscoreNotificationsOneDeviceSubtitle",
- IDS_SETTINGS_INTERNET_GMSCORE_NOTIFICATIONS_ONE_DEVICE_SUBTITLE},
- {"gmscoreNotificationsTwoDevicesSubtitle",
- IDS_SETTINGS_INTERNET_GMSCORE_NOTIFICATIONS_TWO_DEVICES_SUBTITLE},
- {"gmscoreNotificationsManyDevicesSubtitle",
- IDS_SETTINGS_INTERNET_GMSCORE_NOTIFICATIONS_MANY_DEVICES_SUBTITLE},
- {"gmscoreNotificationsFirstStep",
- IDS_SETTINGS_INTERNET_GMSCORE_NOTIFICATIONS_FIRST_STEP},
- {"gmscoreNotificationsSecondStep",
- IDS_SETTINGS_INTERNET_GMSCORE_NOTIFICATIONS_SECOND_STEP},
- {"gmscoreNotificationsThirdStep",
- IDS_SETTINGS_INTERNET_GMSCORE_NOTIFICATIONS_THIRD_STEP},
- {"gmscoreNotificationsFourthStep",
- IDS_SETTINGS_INTERNET_GMSCORE_NOTIFICATIONS_FOURTH_STEP},
- {"tetherConnectionDialogTitle",
- IDS_SETTINGS_INTERNET_TETHER_CONNECTION_DIALOG_TITLE},
- {"tetherConnectionAvailableDeviceTitle",
- IDS_SETTINGS_INTERNET_TETHER_CONNECTION_AVAILABLE_DEVICE_TITLE},
- {"tetherConnectionBatteryPercentage",
- IDS_SETTINGS_INTERNET_TETHER_CONNECTION_BATTERY_PERCENTAGE},
- {"tetherConnectionExplanation",
- IDS_SETTINGS_INTERNET_TETHER_CONNECTION_EXPLANATION},
- {"tetherConnectionCarrierWarning",
- IDS_SETTINGS_INTERNET_TETHER_CONNECTION_CARRIER_WARNING},
- {"tetherConnectionDescriptionTitle",
- IDS_SETTINGS_INTERNET_TETHER_CONNECTION_DESCRIPTION_TITLE},
- {"tetherConnectionDescriptionMobileData",
- IDS_SETTINGS_INTERNET_TETHER_CONNECTION_DESCRIPTION_MOBILE_DATA},
- {"tetherConnectionDescriptionBattery",
- IDS_SETTINGS_INTERNET_TETHER_CONNECTION_DESCRIPTION_BATTERY},
- {"tetherConnectionDescriptionWiFi",
- IDS_SETTINGS_INTERNET_TETHER_CONNECTION_DESCRIPTION_WIFI},
- {"tetherConnectionNotNowButton",
- IDS_SETTINGS_INTERNET_TETHER_CONNECTION_NOT_NOW_BUTTON},
- {"tetherConnectionConnectButton",
- IDS_SETTINGS_INTERNET_TETHER_CONNECTION_CONNECT_BUTTON},
- {"tetherEnableBluetooth", IDS_ENABLE_BLUETOOTH},
- };
- AddLocalizedStringsBulk(html_source, kLocalizedStrings);
-
- html_source->AddString("networkGoogleNameserversLearnMoreUrl",
- chrome::kGoogleNameserversLearnMoreURL);
- html_source->AddString(
- "internetNoNetworksMobileData",
- l10n_util::GetStringFUTF16(
- IDS_SETTINGS_INTERNET_LOOKING_FOR_MOBILE_NETWORK,
- GetHelpUrlWithBoard(chrome::kInstantTetheringLearnMoreURL)));
-}
-#endif
-
-void AddLanguagesStrings(content::WebUIDataSource* html_source) {
+void AddLanguagesStrings(content::WebUIDataSource* html_source,
+ Profile* profile) {
static constexpr webui::LocalizedString kLocalizedStrings[] = {
{"languagesListTitle", IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_TITLE},
{"searchLanguages", IDS_SETTINGS_LANGUAGE_SEARCH},
{"languagesExpandA11yLabel",
IDS_SETTINGS_LANGUAGES_EXPAND_ACCESSIBILITY_LABEL},
- {"orderLanguagesInstructions",
- IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_ORDERING_INSTRUCTIONS},
+ {"orderBrowserLanguagesInstructions",
+ IDS_SETTINGS_LANGUAGES_BROWSER_LANGUAGES_LIST_ORDERING_INSTRUCTIONS},
{"moveToTop", IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_MOVE_TO_TOP},
{"moveUp", IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_MOVE_UP},
{"moveDown", IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_MOVE_DOWN},
{"removeLanguage", IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_REMOVE},
{"addLanguages", IDS_SETTINGS_LANGUAGES_LANGUAGES_ADD},
-#if defined(OS_CHROMEOS)
- {"osLanguagesPageTitle", IDS_OS_SETTINGS_LANGUAGES_AND_INPUT_PAGE_TITLE},
- {"osLanguagesListTitle", IDS_OS_SETTINGS_LANGUAGES_LIST_TITLE},
- {"inputMethodsListTitle", IDS_SETTINGS_LANGUAGES_INPUT_METHODS_LIST_TITLE},
- {"inputMethodEnabled", IDS_SETTINGS_LANGUAGES_INPUT_METHOD_ENABLED},
- {"inputMethodsExpandA11yLabel",
- IDS_SETTINGS_LANGUAGES_INPUT_METHODS_EXPAND_ACCESSIBILITY_LABEL},
- {"inputMethodsManagedbyPolicy",
- IDS_SETTINGS_LANGUAGES_INPUT_METHODS_MANAGED_BY_POLICY},
- {"manageInputMethods", IDS_SETTINGS_LANGUAGES_INPUT_METHODS_MANAGE},
- {"manageInputMethodsPageTitle",
- IDS_SETTINGS_LANGUAGES_MANAGE_INPUT_METHODS_TITLE},
- {"showImeMenu", IDS_SETTINGS_LANGUAGES_SHOW_IME_MENU},
-#endif
{"addLanguagesDialogTitle", IDS_SETTINGS_LANGUAGES_MANAGE_LANGUAGES_TITLE},
{"allLanguages", IDS_SETTINGS_LANGUAGES_ALL_LANGUAGES},
{"enabledLanguages", IDS_SETTINGS_LANGUAGES_ENABLED_LANGUAGES},
@@ -1704,18 +642,23 @@ void AddLanguagesStrings(content::WebUIDataSource* html_source) {
html_source->AddString(
"languagesLearnMoreURL",
base::ASCIIToUTF16(chrome::kLanguageSettingsLearnMoreUrl));
- // TODO(hsuregan): Remove once OS Browser split settings is complete.
html_source->AddString(
"languagesPageTitle",
- l10n_util::GetStringUTF16(
- base::FeatureList::IsEnabled(chromeos::features::kSplitSettings)
- ? IDS_SETTINGS_LANGUAGES_PAGE_TITLE
- : IDS_OS_SETTINGS_LANGUAGES_AND_INPUT_PAGE_TITLE));
+ l10n_util::GetStringUTF16(IDS_SETTINGS_LANGUAGES_PAGE_TITLE));
#else
html_source->AddString(
"languagesPageTitle",
l10n_util::GetStringUTF16(IDS_SETTINGS_LANGUAGES_PAGE_TITLE));
#endif
+#if defined(OS_CHROMEOS)
+ user_manager::UserManager* user_manager = user_manager::UserManager::Get();
+ const user_manager::User* user =
+ chromeos::ProfileHelper::Get()->GetUserByProfile(profile);
+ const user_manager::User* primary_user = user_manager->GetPrimaryUser();
+ html_source->AddBoolean(
+ "isSecondaryUser",
+ user && user->GetAccountId() != primary_user->GetAccountId());
+#endif // defined(OS_CHROMEOS)
}
#if defined(OS_CHROMEOS)
@@ -1723,34 +666,13 @@ void AddChromeOSUserStrings(content::WebUIDataSource* html_source,
Profile* profile) {
user_manager::UserManager* user_manager = user_manager::UserManager::Get();
- const user_manager::User* user =
- chromeos::ProfileHelper::Get()->GetUserByProfile(profile);
const user_manager::User* primary_user = user_manager->GetPrimaryUser();
std::string primary_user_email = primary_user->GetAccountId().GetUserEmail();
- html_source->AddString("primaryUserEmail", primary_user_email);
- html_source->AddBoolean(
- "isSecondaryUser",
- user && user->GetAccountId() != primary_user->GetAccountId());
- html_source->AddString(
- "secondaryUserBannerText",
- l10n_util::GetStringFUTF16(IDS_SETTINGS_SECONDARY_USER_BANNER,
- base::ASCIIToUTF16(primary_user_email)));
- html_source->AddString("browserSettingsBannerText",
- l10n_util::GetStringFUTF16(
- IDS_SETTINGS_BROWSER_SETTINGS_BANNER,
- base::ASCIIToUTF16(chrome::kChromeUISettingsURL)));
html_source->AddString(
"osSettingsBannerText",
l10n_util::GetStringFUTF16(
IDS_SETTINGS_OS_SETTINGS_BANNER,
base::ASCIIToUTF16(chrome::kChromeUIOSSettingsURL)));
- html_source->AddBoolean("isActiveDirectoryUser",
- user && user->IsActiveDirectoryUser());
-
- if (!IsDeviceManaged() && !user_manager->IsCurrentUserOwner()) {
- html_source->AddString("ownerEmail",
- user_manager->GetOwnerAccountId().GetUserEmail());
- }
}
#endif
@@ -1809,8 +731,42 @@ void AddAutofillStrings(content::WebUIDataSource* html_source,
static constexpr webui::LocalizedString kLocalizedStrings[] = {
{"autofillPageTitle", IDS_SETTINGS_AUTOFILL},
{"passwords", IDS_SETTINGS_PASSWORDS},
+ {"checkPasswords", IDS_SETTINGS_CHECK_PASSWORDS},
+ {"checkPasswordsCanceled", IDS_SETTINGS_CHECK_PASSWORDS_CANCELED},
+ {"checkedPasswords", IDS_SETTINGS_CHECKED_PASSWORDS},
+ {"checkPasswordsDescription", IDS_SETTINGS_CHECK_PASSWORDS_DESCRIPTION},
+ {"checkPasswordsAgain", IDS_SETTINGS_CHECK_PASSWORDS_AGAIN},
+ {"checkPasswordsAgainAfterError",
+ IDS_SETTINGS_CHECK_PASSWORDS_AGAIN_AFTER_ERROR},
+ {"checkPasswordsProgress", IDS_SETTINGS_CHECK_PASSWORDS_PROGRESS},
+ {"checkPasswordsStop", IDS_SETTINGS_CHECK_PASSWORDS_STOP},
+ {"compromisedPasswords", IDS_SETTINGS_COMPROMISED_PASSWORDS},
+ {"compromisedPasswordsDescription",
+ IDS_SETTINGS_COMPROMISED_PASSWORDS_ADVICE},
+ {"changePasswordButton", IDS_SETTINGS_CHANGE_PASSWORD_BUTTON},
+ {"changePasswordInApp", IDS_SETTINGS_CHANGE_PASSWORD_IN_APP_LABEL},
+ {"leakedPassword", IDS_SETTINGS_COMPROMISED_PASSWORD_REASON_LEAKED},
+ {"phishedPassword", IDS_SETTINGS_COMPROMISED_PASSWORD_REASON_PHISHED},
+ {"phishedAndLeakedPassword",
+ IDS_SETTINGS_COMPROMISED_PASSWORD_REASON_PHISHED_AND_LEAKED},
+ {"showCompromisedPassword", IDS_SETTINGS_COMPROMISED_PASSWORD_SHOW},
+ {"hideCompromisedPassword", IDS_SETTINGS_COMPROMISED_PASSWORD_HIDE},
+ {"editCompromisedPassword", IDS_SETTINGS_COMPROMISED_PASSWORD_EDIT},
+ {"removeCompromisedPassword", IDS_SETTINGS_COMPROMISED_PASSWORD_REMOVE},
+ {"removeCompromisedPasswordConfirmationTitle",
+ IDS_SETTINGS_REMOVE_COMPROMISED_PASSWORD_CONFIRMATION_TITLE},
+ {"removeCompromisedPasswordConfirmationDescription",
+ IDS_SETTINGS_REMOVE_COMPROMISED_PASSWORD_CONFIRMATION_DESCRIPTION},
+ {"editCompromisedPasswordTitle",
+ IDS_SETTINGS_COMPROMISED_EDIT_PASSWORD_TITLE},
+ {"editCompromisedPasswordFootnote",
+ IDS_SETTINGS_COMPROMISED_EDIT_PASSWORD_FOOTNOTE},
+ {"editCompromisedPasswordSite",
+ IDS_SETTINGS_COMPROMISED_EDIT_PASSWORD_SITE},
+ {"editCompromisedPasswordApp",
+ IDS_SETTINGS_COMPROMISED_EDIT_PASSWORD_APP},
{"creditCards", IDS_AUTOFILL_PAYMENT_METHODS},
- {"noCreditCardsFound", IDS_SETTINGS_PAYMENT_METHODS_NONE},
+ {"noPaymentMethodsFound", IDS_SETTINGS_PAYMENT_METHODS_NONE},
{"googlePayments", IDS_SETTINGS_GOOGLE_PAYMENTS},
{"googlePaymentsCached", IDS_SETTINGS_GOOGLE_PAYMENTS_CACHED},
{"enableProfilesLabel", IDS_AUTOFILL_ENABLE_PROFILES_TOGGLE_LABEL},
@@ -1844,6 +800,8 @@ void AddAutofillStrings(content::WebUIDataSource* html_source,
{"migratableCardsInfoSingle", IDS_SETTINGS_SINGLE_MIGRATABLE_CARD_INFO},
{"migratableCardsInfoMultiple",
IDS_SETTINGS_MULTIPLE_MIGRATABLE_CARDS_INFO},
+ {"upiIdLabel", IDS_SETTINGS_UPI_ID_LABEL},
+ {"upiIdExpirationNever", IDS_SETTINGS_UPI_ID_EXPIRATION_NEVER},
{"canMakePaymentToggleLabel", IDS_SETTINGS_CAN_MAKE_PAYMENT_TOGGLE_LABEL},
{"autofillDetail", IDS_SETTINGS_AUTOFILL_DETAIL},
{"passwordsSavePasswordsLabel",
@@ -1854,6 +812,8 @@ void AddAutofillStrings(content::WebUIDataSource* html_source,
IDS_SETTINGS_PASSWORDS_AUTOSIGNIN_CHECKBOX_DESC},
{"passwordsLeakDetectionLabel",
IDS_SETTINGS_PASSWORDS_LEAK_DETECTION_LABEL},
+ {"passwordsLeakDetectionGeneralDescription",
+ IDS_PASSWORD_MANAGER_LEAK_HELP_MESSAGE},
{"passwordsLeakDetectionSignedOutEnabledDescription",
IDS_SETTINGS_PASSWORDS_LEAK_DETECTION_SIGNED_OUT_ENABLED_DESC},
{"savedPasswordsHeading", IDS_SETTINGS_PASSWORDS_SAVED_HEADING},
@@ -1865,6 +825,7 @@ void AddAutofillStrings(content::WebUIDataSource* html_source,
{"hidePassword", IDS_SETTINGS_PASSWORD_HIDE},
{"passwordDetailsTitle", IDS_SETTINGS_PASSWORDS_VIEW_DETAILS_TITLE},
{"passwordViewDetails", IDS_SETTINGS_PASSWORD_DETAILS},
+ {"copyPassword", IDS_SETTINGS_PASSWORD_COPY},
{"editPasswordWebsiteLabel", IDS_SETTINGS_PASSWORDS_WEBSITE},
{"editPasswordUsernameLabel", IDS_SETTINGS_PASSWORDS_USERNAME},
{"editPasswordPasswordLabel", IDS_SETTINGS_PASSWORDS_PASSWORD},
@@ -1873,6 +834,10 @@ void AddAutofillStrings(content::WebUIDataSource* html_source,
{"noExceptionsFound", IDS_SETTINGS_PASSWORDS_EXCEPTIONS_NONE},
{"import", IDS_PASSWORD_MANAGER_IMPORT_BUTTON},
{"exportMenuItem", IDS_SETTINGS_PASSWORDS_EXPORT_MENU_ITEM},
+ {"optInAccountStorageLabel",
+ IDS_SETTINGS_PASSWORDS_OPT_IN_ACCOUNT_STORAGE_LABEL},
+ {"optOutAccountStorageLabel",
+ IDS_SETTINGS_PASSWORDS_OPT_OUT_ACCOUNT_STORAGE_LABEL},
{"undoRemovePassword", IDS_SETTINGS_PASSWORD_UNDO},
{"passwordDeleted", IDS_SETTINGS_PASSWORD_DELETED_PASSWORD},
{"passwordRowMoreActionsButton", IDS_SETTINGS_PASSWORD_ROW_MORE_ACTIONS},
@@ -1894,6 +859,33 @@ void AddAutofillStrings(content::WebUIDataSource* html_source,
{"savedToThisDeviceOnly",
IDS_SETTINGS_PAYMENTS_SAVED_TO_THIS_DEVICE_ONLY}};
+ const base::string16 short_product_name =
+ l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME);
+ html_source->AddString(
+ "checkPasswordsErrorOffline",
+ l10n_util::GetStringFUTF16(IDS_SETTINGS_CHECK_PASSWORDS_ERROR_OFFLINE,
+ short_product_name));
+ html_source->AddString(
+ "checkPasswordsErrorSignedOut",
+ l10n_util::GetStringFUTF16(IDS_SETTINGS_CHECK_PASSWORDS_ERROR_SIGNED_OUT,
+ short_product_name));
+ html_source->AddString(
+ "checkPasswordsErrorNoPasswords",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_CHECK_PASSWORDS_ERROR_NO_PASSWORDS, short_product_name));
+ html_source->AddString(
+ "checkPasswordsErrorQuota",
+ l10n_util::GetStringFUTF16(IDS_SETTINGS_CHECK_PASSWORDS_ERROR_QUOTA_LIMIT,
+ short_product_name));
+ html_source->AddString(
+ "checkPasswordsErrorGeneric",
+ l10n_util::GetStringFUTF16(IDS_SETTINGS_CHECK_PASSWORDS_ERROR_GENERIC,
+ short_product_name));
+ html_source->AddString(
+ "noCompromisedCredentials",
+ l10n_util::GetStringFUTF16(IDS_SETTINGS_NO_COMPROMISED_CREDENTIALS_LABEL,
+ short_product_name));
+
GURL google_password_manager_url = GetGooglePasswordManagerURL(
password_manager::ManagePasswordsReferrer::kChromeSettings);
@@ -1902,8 +894,19 @@ void AddAutofillStrings(content::WebUIDataSource* html_source,
l10n_util::GetStringFUTF16(
IDS_SETTINGS_PASSWORDS_MANAGE_PASSWORDS,
base::UTF8ToUTF16(google_password_manager_url.spec())));
+ html_source->AddString(
+ "checkPasswordsErrorQuotaGoogleAccount",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_CHECK_PASSWORDS_ERROR_QUOTA_LIMIT_GOOGLE_ACCOUNT,
+ short_product_name,
+ base::UTF8ToUTF16(
+ password_manager::GetPasswordCheckupURL(
+ password_manager::PasswordCheckupReferrer::kPasswordCheck)
+ .spec())));
html_source->AddString("googlePasswordManagerUrl",
google_password_manager_url.spec());
+ html_source->AddString("passwordCheckLearnMoreURL",
+ chrome::kPasswordCheckLearnMoreURL);
html_source->AddString("passwordManagerLearnMoreURL",
chrome::kPasswordManagerLearnMoreURL);
html_source->AddString("manageAddressesUrl",
@@ -1937,397 +940,119 @@ void AddAutofillStrings(content::WebUIDataSource* html_source,
"fidoAuthenticationAvailableForAutofill",
IsFidoAuthenticationAvailable(personal_data, web_contents));
- html_source->AddBoolean(
- "passwordsLeakDetectionEnabled",
- base::FeatureList::IsEnabled(password_manager::features::kLeakDetection));
-
ui::Accelerator undo_accelerator(ui::VKEY_Z, ui::EF_PLATFORM_ACCELERATOR);
html_source->AddString(
"undoDescription",
l10n_util::GetStringFUTF16(IDS_UNDO_DESCRIPTION,
undo_accelerator.GetShortcutText()));
+ html_source->AddBoolean("showUpiIdSettings",
+ base::FeatureList::IsEnabled(
+ autofill::features::kAutofillSaveAndFillVPA));
+
AddLocalizedStringsBulk(html_source, kLocalizedStrings);
}
-void AddPeopleStrings(content::WebUIDataSource* html_source, Profile* profile) {
- static constexpr webui::LocalizedString kLocalizedStrings[] = {
- {"peoplePageTitle", IDS_SETTINGS_PEOPLE},
- {"manageOtherPeople", IDS_SETTINGS_PEOPLE_MANAGE_OTHER_PEOPLE},
+void AddSignOutDialogStrings(content::WebUIDataSource* html_source,
+ Profile* profile) {
#if defined(OS_CHROMEOS)
- {"accountManagerDescription", IDS_SETTINGS_ACCOUNT_MANAGER_DESCRIPTION},
- {"accountManagerPageTitle", IDS_SETTINGS_ACCOUNT_MANAGER_PAGE_TITLE},
- {"accountManagerSubMenuLabel", IDS_SETTINGS_ACCOUNT_MANAGER_SUBMENU_LABEL},
- {"accountListHeader", IDS_SETTINGS_ACCOUNT_MANAGER_LIST_HEADER},
- {"addAccountLabel", IDS_SETTINGS_ACCOUNT_MANAGER_ADD_ACCOUNT_LABEL},
- {"removeAccountLabel", IDS_SETTINGS_ACCOUNT_MANAGER_REMOVE_ACCOUNT_LABEL},
- {"accountManagerPrimaryAccountTooltip",
- IDS_SETTINGS_ACCOUNT_MANAGER_PRIMARY_ACCOUNT_TOOLTIP},
- {"accountManagerSecondaryAccountsDisabledText",
- IDS_SETTINGS_ACCOUNT_MANAGER_SECONDARY_ACCOUNTS_DISABLED_TEXT},
- {"accountManagerSecondaryAccountsDisabledChildText",
- IDS_SETTINGS_ACCOUNT_MANAGER_SECONDARY_ACCOUNTS_DISABLED_CHILD_TEXT},
- {"accountManagerSignedOutAccountName",
- IDS_SETTINGS_ACCOUNT_MANAGER_SIGNED_OUT_ACCOUNT_PLACEHOLDER},
- {"accountManagerUnmigratedAccountName",
- IDS_SETTINGS_ACCOUNT_MANAGER_UNMIGRATED_ACCOUNT_PLACEHOLDER},
- {"accountManagerMigrationLabel",
- IDS_SETTINGS_ACCOUNT_MANAGER_MIGRATION_LABEL},
- {"accountManagerReauthenticationLabel",
- IDS_SETTINGS_ACCOUNT_MANAGER_REAUTHENTICATION_LABEL},
- {"accountManagerMigrationTooltip",
- IDS_SETTINGS_ACCOUNT_MANAGER_MIGRATION_TOOLTIP},
- {"accountManagerReauthenticationTooltip",
- IDS_SETTINGS_ACCOUNT_MANAGER_REAUTHENTICATION_TOOLTIP},
- {"accountManagerMoreActionsTooltip",
- IDS_SETTINGS_ACCOUNT_MANAGER_MORE_ACTIONS_TOOLTIP},
- {"accountManagerManagedLabel",
- IDS_SETTINGS_ACCOUNT_MANAGER_MANAGEMENT_STATUS_MANAGED_ACCOUNT},
- {"accountManagerUnmanagedLabel",
- IDS_SETTINGS_ACCOUNT_MANAGER_MANAGEMENT_STATUS_UNMANAGED_ACCOUNT},
- {"configureFingerprintTitle", IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_TITLE},
- {"configureFingerprintInstructionReadyStep",
- IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_READY},
- {"configureFingerprintLiftFinger",
- IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_LIFT_FINGER},
- {"configureFingerprintTryAgain",
- IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_TRY_AGAIN},
- {"configureFingerprintImmobile",
- IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_FINGER_IMMOBILE},
- {"configureFingerprintAddAnotherButton",
- IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_ADD_ANOTHER_BUTTON},
- {"configurePinChoosePinTitle",
- IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_CHOOSE_PIN_TITLE},
- {"configurePinConfirmPinTitle",
- IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_CONFIRM_PIN_TITLE},
- {"configurePinMismatched", IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_MISMATCHED},
- {"configurePinTooShort", IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_TOO_SHORT},
- {"configurePinTooLong", IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_TOO_LONG},
- {"configurePinWeakPin", IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_WEAK_PIN},
- {"enableScreenlock", IDS_SETTINGS_PEOPLE_ENABLE_SCREENLOCK},
- {"kerberosAccountsSubMenuLabel",
- IDS_SETTINGS_KERBEROS_ACCOUNTS_SUBMENU_LABEL},
- {"kerberosAccountsPageTitle", IDS_SETTINGS_KERBEROS_ACCOUNTS_PAGE_TITLE},
- {"kerberosAccountsListHeader", IDS_SETTINGS_KERBEROS_ACCOUNTS_LIST_HEADER},
- {"kerberosAccountsAddAccountLabel",
- IDS_SETTINGS_KERBEROS_ACCOUNTS_ADD_ACCOUNT_LABEL},
- {"kerberosAccountsRefreshNowLabel",
- IDS_SETTINGS_KERBEROS_ACCOUNTS_REFRESH_NOW_LABEL},
- {"kerberosAccountsSetAsActiveAccountLabel",
- IDS_SETTINGS_KERBEROS_ACCOUNTS_SET_AS_ACTIVE_ACCOUNT_LABEL},
- {"kerberosAccountsRemoveAccountLabel",
- IDS_SETTINGS_KERBEROS_ACCOUNTS_REMOVE_ACCOUNT_LABEL},
- {"kerberosAccountsAccountRemovedTip",
- IDS_SETTINGS_KERBEROS_ACCOUNTS_ACCOUNT_REMOVED_TIP},
- {"kerberosAccountsAccountRefreshedTip",
- IDS_SETTINGS_KERBEROS_ACCOUNTS_ACCOUNT_REFRESHED_TIP},
- {"kerberosAccountsSignedIn", IDS_SETTINGS_KERBEROS_ACCOUNTS_SIGNED_IN},
- {"kerberosAccountsSignedOut", IDS_SETTINGS_KERBEROS_ACCOUNTS_SIGNED_OUT},
- {"kerberosAccountsReauthenticationLabel",
- IDS_SETTINGS_KERBEROS_ACCOUNTS_REAUTHENTICATION_LABEL},
- {"kerberosAccountsTicketActive",
- IDS_SETTINGS_KERBEROS_ACCOUNTS_TICKET_ACTIVE},
- {"addKerberosAccount", IDS_SETTINGS_ADD_KERBEROS_ACCOUNT},
- {"refreshKerberosAccount", IDS_SETTINGS_REFRESH_KERBEROS_ACCOUNT},
- {"addKerberosAccountDescription",
- IDS_SETTINGS_ADD_KERBEROS_ACCOUNT_DESCRIPTION},
- {"addKerberosAccountRememberPassword",
- IDS_SETTINGS_ADD_KERBEROS_ACCOUNT_REMEMBER_PASSWORD},
- {"addKerberosAccountRefreshButtonLabel",
- IDS_SETTINGS_ADD_KERBEROS_ACCOUNT_REFRESH_BUTTON_LABEL},
- {"kerberosUsername", IDS_SETTINGS_KERBEROS_USERNAME},
- {"kerberosPassword", IDS_SETTINGS_KERBEROS_PASSWORD},
- {"kerberosAccountsAdvancedConfigLabel",
- IDS_SETTINGS_KERBEROS_ACCOUNTS_ADVANCED_CONFIG_LABEL},
- {"kerberosAdvancedConfigTitle",
- IDS_SETTINGS_KERBEROS_ADVANCED_CONFIG_TITLE},
- {"kerberosAdvancedConfigDesc", IDS_SETTINGS_KERBEROS_ADVANCED_CONFIG_DESC},
- {"kerberosErrorNetworkProblem",
- IDS_SETTINGS_KERBEROS_ERROR_NETWORK_PROBLEM},
- {"kerberosErrorUsernameInvalid",
- IDS_SETTINGS_KERBEROS_ERROR_USERNAME_INVALID},
- {"kerberosErrorUsernameUnknown",
- IDS_SETTINGS_KERBEROS_ERROR_USERNAME_UNKNOWN},
- {"kerberosErrorDuplicatePrincipalName",
- IDS_SETTINGS_KERBEROS_ERROR_DUPLICATE_PRINCIPAL_NAME},
- {"kerberosErrorContactingServer",
- IDS_SETTINGS_KERBEROS_ERROR_CONTACTING_SERVER},
- {"kerberosErrorPasswordInvalid",
- IDS_SETTINGS_KERBEROS_ERROR_PASSWORD_INVALID},
- {"kerberosErrorPasswordExpired",
- IDS_SETTINGS_KERBEROS_ERROR_PASSWORD_EXPIRED},
- {"kerberosErrorKdcEncType", IDS_SETTINGS_KERBEROS_ERROR_KDC_ENC_TYPE},
- {"kerberosErrorGeneral", IDS_SETTINGS_KERBEROS_ERROR_GENERAL},
- {"kerberosConfigErrorSectionNestedInGroup",
- IDS_SETTINGS_KERBEROS_CONFIG_ERROR_SECTION_NESTED_IN_GROUP},
- {"kerberosConfigErrorSectionSyntax",
- IDS_SETTINGS_KERBEROS_CONFIG_ERROR_SECTION_SYNTAX},
- {"kerberosConfigErrorExpectedOpeningCurlyBrace",
- IDS_SETTINGS_KERBEROS_CONFIG_ERROR_EXPECTED_OPENING_CURLY_BRACE},
- {"kerberosConfigErrorExtraCurlyBrace",
- IDS_SETTINGS_KERBEROS_CONFIG_ERROR_EXTRA_CURLY_BRACE},
- {"kerberosConfigErrorRelationSyntax",
- IDS_SETTINGS_KERBEROS_CONFIG_ERROR_RELATION_SYNTAX_ERROR},
- {"kerberosConfigErrorKeyNotSupported",
- IDS_SETTINGS_KERBEROS_CONFIG_ERROR_KEY_NOT_SUPPORTED},
- {"kerberosConfigErrorSectionNotSupported",
- IDS_SETTINGS_KERBEROS_CONFIG_ERROR_SECTION_NOT_SUPPORTED},
- {"kerberosConfigErrorKrb5FailedToParse",
- IDS_SETTINGS_KERBEROS_CONFIG_ERROR_KRB5_FAILED_TO_PARSE},
- {"lockScreenAddFingerprint",
- IDS_SETTINGS_PEOPLE_LOCK_SCREEN_ADD_FINGERPRINT_BUTTON},
- {"lockScreenChangePinButton",
- IDS_SETTINGS_PEOPLE_LOCK_SCREEN_CHANGE_PIN_BUTTON},
- {"lockScreenEditFingerprints",
- IDS_SETTINGS_PEOPLE_LOCK_SCREEN_EDIT_FINGERPRINTS},
- {"lockScreenEditFingerprintsDescription",
- IDS_SETTINGS_PEOPLE_LOCK_SCREEN_EDIT_FINGERPRINTS_DESCRIPTION},
- {"lockScreenSetupFingerprintButton",
- IDS_SETTINGS_PEOPLE_LOCK_SCREEN_FINGERPRINT_SETUP_BUTTON},
- {"lockScreenNumberFingerprints",
- IDS_SETTINGS_PEOPLE_LOCK_SCREEN_NUM_FINGERPRINTS},
- {"lockScreenNone", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_NONE},
- {"lockScreenFingerprintNewName",
- IDS_SETTINGS_PEOPLE_LOCK_SCREEN_NEW_FINGERPRINT_DEFAULT_NAME},
- {"lockScreenFingerprintTitle",
- IDS_SETTINGS_PEOPLE_LOCK_SCREEN_FINGERPRINT_SUBPAGE_TITLE},
- {"lockScreenFingerprintWarning",
- IDS_SETTINGS_PEOPLE_LOCK_SCREEN_FINGERPRINT_LESS_SECURE},
- {"lockScreenDeleteFingerprintLabel",
- IDS_SETTINGS_PEOPLE_LOCK_SCREEN_DELETE_FINGERPRINT_ARIA_LABEL},
- {"lockScreenNotificationHide",
- IDS_ASH_SETTINGS_LOCK_SCREEN_NOTIFICATION_HIDE},
- {"lockScreenNotificationHideSensitive",
- IDS_ASH_SETTINGS_LOCK_SCREEN_NOTIFICATION_HIDE_SENSITIVE},
- {"lockScreenNotificationShow",
- IDS_ASH_SETTINGS_LOCK_SCREEN_NOTIFICATION_SHOW},
- {"lockScreenNotificationTitle",
- IDS_ASH_SETTINGS_LOCK_SCREEN_NOTIFICATION_TITLE},
- {"lockScreenOptionsLock", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_OPTIONS_LOCK},
- {"lockScreenOptionsLoginLock",
- IDS_SETTINGS_PEOPLE_LOCK_SCREEN_OPTIONS_LOGIN_LOCK},
- {"lockScreenPasswordOnly", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_PASSWORD_ONLY},
- {"lockScreenPinOrPassword",
- IDS_SETTINGS_PEOPLE_LOCK_SCREEN_PIN_OR_PASSWORD},
- {"lockScreenRegisteredFingerprints",
- IDS_SETTINGS_PEOPLE_LOCK_SCREEN_REGISTERED_FINGERPRINTS_LABEL},
- {"lockScreenSetupPinButton",
- IDS_SETTINGS_PEOPLE_LOCK_SCREEN_SETUP_PIN_BUTTON},
- {"lockScreenTitleLock", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_TITLE_LOCK},
- {"lockScreenTitleLoginLock",
- IDS_SETTINGS_PEOPLE_LOCK_SCREEN_TITLE_LOGIN_LOCK},
- {"passwordPromptEnterPasswordLock",
- IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_ENTER_PASSWORD_LOCK},
- {"passwordPromptEnterPasswordLoginLock",
- IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_ENTER_PASSWORD_LOGIN_LOCK},
- {"passwordPromptInvalidPassword",
- IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_INVALID_PASSWORD},
- {"passwordPromptPasswordLabel",
- IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_PASSWORD_LABEL},
- {"passwordPromptTitle", IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_TITLE},
- {"pinKeyboardPlaceholderPin", IDS_PIN_KEYBOARD_HINT_TEXT_PIN},
- {"pinKeyboardPlaceholderPinPassword",
- IDS_PIN_KEYBOARD_HINT_TEXT_PIN_PASSWORD},
- {"pinKeyboardDeleteAccessibleName",
- IDS_PIN_KEYBOARD_DELETE_ACCESSIBLE_NAME},
- {"changePicturePageDescription", IDS_SETTINGS_CHANGE_PICTURE_DIALOG_TEXT},
- {"takePhoto", IDS_SETTINGS_CHANGE_PICTURE_TAKE_PHOTO},
- {"captureVideo", IDS_SETTINGS_CHANGE_PICTURE_CAPTURE_VIDEO},
- {"discardPhoto", IDS_SETTINGS_CHANGE_PICTURE_DISCARD_PHOTO},
- {"switchModeToCamera", IDS_SETTINGS_CHANGE_PICTURE_SWITCH_MODE_TO_CAMERA},
- {"switchModeToVideo", IDS_SETTINGS_CHANGE_PICTURE_SWITCH_MODE_TO_VIDEO},
- {"chooseFile", IDS_SETTINGS_CHANGE_PICTURE_CHOOSE_FILE},
- {"profilePhoto", IDS_SETTINGS_CHANGE_PICTURE_PROFILE_PHOTO},
- {"oldPhoto", IDS_SETTINGS_CHANGE_PICTURE_OLD_PHOTO},
- {"oldVideo", IDS_SETTINGS_CHANGE_PICTURE_OLD_VIDEO},
- {"previewAltText", IDS_SETTINGS_CHANGE_PICTURE_PREVIEW_ALT},
- {"authorCreditText", IDS_SETTINGS_CHANGE_PICTURE_AUTHOR_CREDIT_TEXT},
- {"photoCaptureAccessibleText", IDS_SETTINGS_PHOTO_CAPTURE_ACCESSIBLE_TEXT},
- {"photoDiscardAccessibleText", IDS_SETTINGS_PHOTO_DISCARD_ACCESSIBLE_TEXT},
- {"photoModeAccessibleText", IDS_SETTINGS_PHOTO_MODE_ACCESSIBLE_TEXT},
- {"syncOsAppsCheckboxLabel", IDS_OS_SETTINGS_SYNC_OS_APPS_CHECKBOX_LABEL},
- {"syncOsSettingsCheckboxLabel",
- IDS_OS_SETTINGS_SYNC_OS_SETTINGS_CHECKBOX_LABEL},
- {"syncPrintersCheckboxLabel", IDS_OS_SETTINGS_SYNC_PRINTERS_CHECKBOX_LABEL},
- {"videoModeAccessibleText", IDS_SETTINGS_VIDEO_MODE_ACCESSIBLE_TEXT},
- {"wifiConfigurationsCheckboxLabel",
- IDS_SETTINGS_WIFI_CONFIGURATIONS_CHECKBOX_LABEL},
-#else // !defined(OS_CHROMEOS)
- {"domainManagedProfile", IDS_SETTINGS_PEOPLE_DOMAIN_MANAGED_PROFILE},
- {"editPerson", IDS_SETTINGS_EDIT_PERSON},
- {"profileNameAndPicture", IDS_SETTINGS_PROFILE_NAME_AND_PICTURE},
- {"showShortcutLabel", IDS_SETTINGS_PROFILE_SHORTCUT_TOGGLE_LABEL},
- {"syncWillStart", IDS_SETTINGS_SYNC_WILL_START},
- {"syncSettingsSavedToast", IDS_SETTINGS_SYNC_SETTINGS_SAVED_TOAST_LABEL},
- {"cancelSync", IDS_SETTINGS_SYNC_SETTINGS_CANCEL_SYNC},
- {"syncSetupCancelDialogTitle", IDS_SETTINGS_SYNC_SETUP_CANCEL_DIALOG_TITLE},
- {"syncSetupCancelDialogBody", IDS_SETTINGS_SYNC_SETUP_CANCEL_DIALOG_BODY},
-#endif // defined(OS_CHROMEOS)
-#if BUILDFLAG(ENABLE_DICE_SUPPORT)
- {"peopleSignIn", IDS_PROFILES_DICE_SIGNIN_BUTTON},
- {"peopleSignOut", IDS_SETTINGS_PEOPLE_SIGN_OUT},
- {"peopleSignInPrompt", IDS_SETTINGS_PEOPLE_SIGN_IN_PROMPT},
- {"peopleSignInPromptSecondaryWithNoAccount",
- IDS_SETTINGS_PEOPLE_SIGN_IN_PROMPT_SECONDARY_WITH_ACCOUNT},
- {"peopleSignInPromptSecondaryWithAccount",
- IDS_SETTINGS_PEOPLE_SIGN_IN_PROMPT_SECONDARY_WITH_ACCOUNT},
- {"useAnotherAccount", IDS_SETTINGS_PEOPLE_SYNC_ANOTHER_ACCOUNT},
- {"syncingTo", IDS_SETTINGS_PEOPLE_SYNCING_TO_ACCOUNT},
- {"turnOffSync", IDS_SETTINGS_PEOPLE_SYNC_TURN_OFF},
- {"signInAgain", IDS_SYNC_ERROR_USER_MENU_SIGNIN_AGAIN_BUTTON},
- {"syncNotWorking", IDS_SETTINGS_PEOPLE_SYNC_NOT_WORKING},
- {"syncPasswordsNotWorking", IDS_SETTINGS_PEOPLE_SYNC_PASSWORDS_NOT_WORKING},
- {"syncPaused", IDS_SETTINGS_PEOPLE_SYNC_PAUSED},
- {"syncSignInPromptWithAccount",
- IDS_SETTINGS_SYNC_SIGN_IN_PROMPT_WITH_ACCOUNT},
- {"syncSignInPromptWithNoAccount",
- IDS_SETTINGS_SYNC_SIGN_IN_PROMPT_WITH_NO_ACCOUNT},
+ bool is_dice_enabled = false;
+ bool is_split_sync_consent_enabled =
+ chromeos::features::IsSplitSyncConsentEnabled();
+#else
+ bool is_dice_enabled =
+ AccountConsistencyModeManager::IsDiceEnabledForProfile(profile);
+ bool is_split_sync_consent_enabled = false;
#endif
- {"syncOverview", IDS_SETTINGS_SYNC_OVERVIEW},
- {"syncDisabled", IDS_PROFILES_DICE_SYNC_DISABLED_TITLE},
- {"syncDisabledByAdministrator", IDS_SIGNED_IN_WITH_SYNC_DISABLED_BY_POLICY},
- {"syncSignin", IDS_SETTINGS_SYNC_SIGNIN},
- {"syncDisconnect", IDS_SETTINGS_PEOPLE_SIGN_OUT},
- {"syncDisconnectTitle", IDS_SETTINGS_SYNC_DISCONNECT_TITLE},
- {"syncDisconnectDeleteProfile",
- IDS_SETTINGS_SYNC_DISCONNECT_DELETE_PROFILE},
- {"deleteProfileWarningExpandA11yLabel",
- IDS_SETTINGS_SYNC_DISCONNECT_EXPAND_ACCESSIBILITY_LABEL},
- {"deleteProfileWarningWithCountsSingular",
- IDS_SETTINGS_SYNC_DISCONNECT_DELETE_PROFILE_WARNING_WITH_COUNTS_SINGULAR},
- {"deleteProfileWarningWithCountsPlural",
- IDS_SETTINGS_SYNC_DISCONNECT_DELETE_PROFILE_WARNING_WITH_COUNTS_PLURAL},
- {"deleteProfileWarningWithoutCounts",
- IDS_SETTINGS_SYNC_DISCONNECT_DELETE_PROFILE_WARNING_WITHOUT_COUNTS},
- {"syncDisconnectConfirm", IDS_SETTINGS_SYNC_DISCONNECT_CONFIRM},
- {"sync", IDS_SETTINGS_SYNC},
- {"nonPersonalizedServicesSectionLabel",
- IDS_SETTINGS_NON_PERSONALIZED_SERVICES_SECTION_LABEL},
- {"syncAndNonPersonalizedServices",
- IDS_SETTINGS_SYNC_SYNC_AND_NON_PERSONALIZED_SERVICES},
- {"syncPageTitle", IDS_SETTINGS_SYNC_SYNC_AND_NON_PERSONALIZED_SERVICES},
- {"syncAdvancedPageTitle", IDS_SETTINGS_SYNC_ADVANCED_PAGE_TITLE},
- {"syncLoading", IDS_SETTINGS_SYNC_LOADING},
- {"syncTimeout", IDS_SETTINGS_SYNC_TIMEOUT},
- {"syncEverythingCheckboxLabel",
- IDS_SETTINGS_SYNC_EVERYTHING_CHECKBOX_LABEL},
- {"manageGoogleAccount", IDS_SETTINGS_MANAGE_GOOGLE_ACCOUNT},
- {"appCheckboxLabel", IDS_SETTINGS_APPS_CHECKBOX_LABEL},
- {"extensionsCheckboxLabel", IDS_SETTINGS_EXTENSIONS_CHECKBOX_LABEL},
- {"settingsCheckboxLabel", IDS_SETTINGS_SETTINGS_CHECKBOX_LABEL},
- {"autofillCheckboxLabel", IDS_SETTINGS_AUTOFILL_CHECKBOX_LABEL},
- {"historyCheckboxLabel", IDS_SETTINGS_HISTORY_CHECKBOX_LABEL},
- {"themesAndWallpapersCheckboxLabel",
- IDS_SETTINGS_THEMES_AND_WALLPAPERS_CHECKBOX_LABEL},
- {"bookmarksCheckboxLabel", IDS_SETTINGS_BOOKMARKS_CHECKBOX_LABEL},
- {"passwordsCheckboxLabel", IDS_SETTINGS_PASSWORDS_CHECKBOX_LABEL},
- {"openTabsCheckboxLabel", IDS_SETTINGS_OPEN_TABS_CHECKBOX_LABEL},
- {"driveSuggestPref", IDS_DRIVE_SUGGEST_PREF},
- {"driveSuggestPrefDesc", IDS_DRIVE_SUGGEST_PREF_DESC},
- {"manageSyncedDataTitle",
- IDS_SETTINGS_MANAGE_SYNCED_DATA_TITLE_UNIFIED_CONSENT},
- {"encryptionOptionsTitle", IDS_SETTINGS_ENCRYPTION_OPTIONS},
- {"syncDataEncryptedText", IDS_SETTINGS_SYNC_DATA_ENCRYPTED_TEXT},
- {"encryptWithGoogleCredentialsLabel",
- IDS_SETTINGS_ENCRYPT_WITH_GOOGLE_CREDENTIALS_LABEL},
- {"useDefaultSettingsButton", IDS_SETTINGS_USE_DEFAULT_SETTINGS},
- {"emptyPassphraseError", IDS_SETTINGS_EMPTY_PASSPHRASE_ERROR},
- {"mismatchedPassphraseError", IDS_SETTINGS_MISMATCHED_PASSPHRASE_ERROR},
- {"incorrectPassphraseError", IDS_SETTINGS_INCORRECT_PASSPHRASE_ERROR},
- {"passphrasePlaceholder", IDS_SETTINGS_PASSPHRASE_PLACEHOLDER},
- {"passphraseConfirmationPlaceholder",
- IDS_SETTINGS_PASSPHRASE_CONFIRMATION_PLACEHOLDER},
- {"submitPassphraseButton", IDS_SETTINGS_SUBMIT_PASSPHRASE},
- {"personalizeGoogleServicesTitle",
- IDS_SETTINGS_PERSONALIZE_GOOGLE_SERVICES_TITLE},
- {"existingPassphraseTitle", IDS_SETTINGS_EXISTING_PASSPHRASE_TITLE},
- {"enablePaymentsIntegrationCheckboxLabel",
- IDS_AUTOFILL_ENABLE_PAYMENTS_INTEGRATION_CHECKBOX_LABEL},
- };
- AddLocalizedStringsBulk(html_source, kLocalizedStrings);
-#if defined(OS_CHROMEOS)
- // TODO(crbug.com/1013466): String for this row label.
- html_source->AddString("peopleOsSyncRowLabel", "SYNC PLACEHOLDER LABEL");
- AddFingerprintStrings(html_source);
-#endif // OS_CHROMEOS
- html_source->AddString("managementPage",
- ManagementUI::GetManagementPageSubtitle(profile));
- // Format numbers to be used on the pin keyboard.
- for (int j = 0; j <= 9; j++) {
- html_source->AddString("pinKeyboard" + base::NumberToString(j),
- base::FormatNumber(int64_t{j}));
+ if (is_split_sync_consent_enabled || is_dice_enabled) {
+ static constexpr webui::LocalizedString kTurnOffStrings[] = {
+ {"syncDisconnect", IDS_SETTINGS_PEOPLE_SYNC_TURN_OFF},
+ {"syncDisconnectTitle",
+ IDS_SETTINGS_TURN_OFF_SYNC_AND_SIGN_OUT_DIALOG_TITLE},
+ };
+ AddLocalizedStringsBulk(html_source, kTurnOffStrings);
+ } else {
+ static constexpr webui::LocalizedString kSignOutStrings[] = {
+ {"syncDisconnect", IDS_SETTINGS_PEOPLE_SIGN_OUT},
+ {"syncDisconnectTitle", IDS_SETTINGS_SYNC_DISCONNECT_TITLE},
+ };
+ AddLocalizedStringsBulk(html_source, kSignOutStrings);
}
- html_source->AddString("syncLearnMoreUrl", chrome::kSyncLearnMoreURL);
- html_source->AddString("supervisedUsersUrl",
- chrome::kLegacySupervisedUserManagementURL);
-
- html_source->AddString(
- "encryptWithSyncPassphraseLabel",
- l10n_util::GetStringFUTF8(
- IDS_SETTINGS_ENCRYPT_WITH_SYNC_PASSPHRASE_LABEL,
-#if defined(OS_CHROMEOS)
- GetHelpUrlWithBoard(chrome::kSyncEncryptionHelpURL)));
-#else
- base::ASCIIToUTF16(chrome::kSyncEncryptionHelpURL)));
-#endif
-
std::string sync_dashboard_url =
google_util::AppendGoogleLocaleParam(
GURL(chrome::kSyncGoogleDashboardURL),
g_browser_process->GetApplicationLocale())
.spec();
- html_source->AddString("syncDashboardUrl", sync_dashboard_url);
-
- html_source->AddString(
- "passphraseExplanationText",
- l10n_util::GetStringFUTF8(IDS_SETTINGS_PASSPHRASE_EXPLANATION_TEXT,
- base::ASCIIToUTF16(sync_dashboard_url)));
- html_source->AddString(
- "passphraseResetHintEncryption",
- l10n_util::GetStringFUTF8(IDS_SETTINGS_PASSPHRASE_RESET_HINT_ENCRYPTION,
- base::ASCIIToUTF16(sync_dashboard_url)));
- html_source->AddString(
- "passphraseResetHintToggle",
- l10n_util::GetStringFUTF8(IDS_SETTINGS_PASSPHRASE_RESET_HINT_TOGGLE,
- base::ASCIIToUTF16(sync_dashboard_url)));
- html_source->AddString(
- "passphraseRecover",
- l10n_util::GetStringFUTF8(IDS_SETTINGS_PASSPHRASE_RECOVER,
- base::ASCIIToUTF16(sync_dashboard_url)));
- html_source->AddString(
- "syncDisconnectExplanation",
- l10n_util::GetStringFUTF8(IDS_SETTINGS_SYNC_DISCONNECT_EXPLANATION,
- base::ASCIIToUTF16(sync_dashboard_url)));
-#if !defined(OS_CHROMEOS)
- html_source->AddString(
- "syncDisconnectManagedProfileExplanation",
- l10n_util::GetStringFUTF8(
- IDS_SETTINGS_SYNC_DISCONNECT_MANAGED_PROFILE_EXPLANATION,
- base::ASCIIToUTF16("$1"), base::ASCIIToUTF16(sync_dashboard_url)));
- // The syncDisconnect text differs depending on Dice-enabledness.
- if (AccountConsistencyModeManager::IsDiceEnabledForProfile(profile)) {
+ if (is_dice_enabled) {
static constexpr webui::LocalizedString kSyncDisconnectStrings[] = {
- {"syncDisconnect", IDS_SETTINGS_PEOPLE_SYNC_TURN_OFF},
- {"syncDisconnectTitle",
- IDS_SETTINGS_TURN_OFF_SYNC_AND_SIGN_OUT_DIALOG_TITLE},
{"syncDisconnectDeleteProfile",
IDS_SETTINGS_TURN_OFF_SYNC_DIALOG_CHECKBOX},
{"syncDisconnectConfirm",
IDS_SETTINGS_TURN_OFF_SYNC_DIALOG_MANAGED_CONFIRM},
+ {"syncDisconnectExplanation",
+ IDS_SETTINGS_SYNC_DISCONNECT_AND_SIGN_OUT_EXPLANATION},
+ };
+ AddLocalizedStringsBulk(html_source, kSyncDisconnectStrings);
+ } else {
+ static constexpr webui::LocalizedString kSyncDisconnectStrings[] = {
+ {"syncDisconnectDeleteProfile",
+ IDS_SETTINGS_SYNC_DISCONNECT_DELETE_PROFILE},
+ {"syncDisconnectConfirm", IDS_SETTINGS_SYNC_DISCONNECT_CONFIRM},
};
AddLocalizedStringsBulk(html_source, kSyncDisconnectStrings);
- html_source->AddLocalizedString(
+ html_source->AddString(
"syncDisconnectExplanation",
- IDS_SETTINGS_SYNC_DISCONNECT_AND_SIGN_OUT_EXPLANATION);
+ l10n_util::GetStringFUTF8(IDS_SETTINGS_SYNC_DISCONNECT_EXPLANATION,
+ base::ASCIIToUTF16(sync_dashboard_url)));
}
+
+#if !defined(OS_CHROMEOS)
+ html_source->AddString(
+ "syncDisconnectManagedProfileExplanation",
+ l10n_util::GetStringFUTF8(
+ IDS_SETTINGS_SYNC_DISCONNECT_MANAGED_PROFILE_EXPLANATION,
+ base::ASCIIToUTF16("$1"), base::ASCIIToUTF16(sync_dashboard_url)));
#endif
+}
- html_source->AddString("activityControlsUrl",
- chrome::kGoogleAccountActivityControlsURL);
+void AddPeopleStrings(content::WebUIDataSource* html_source, Profile* profile) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ // Top level people strings:
+ {"peopleSignInPromptSecondaryWithAccount",
+ IDS_SETTINGS_PEOPLE_SIGN_IN_PROMPT_SECONDARY_WITH_ACCOUNT},
+ {"peopleSignInPromptSecondaryWithNoAccount",
+ IDS_SETTINGS_PEOPLE_SIGN_IN_PROMPT_SECONDARY_WITH_ACCOUNT},
+ {"peoplePageTitle", IDS_SETTINGS_PEOPLE},
+ {"syncSettingsSavedToast", IDS_SETTINGS_SYNC_SETTINGS_SAVED_TOAST_LABEL},
+ {"peopleSignInPrompt", IDS_SETTINGS_PEOPLE_SIGN_IN_PROMPT},
+ {"manageGoogleAccount", IDS_SETTINGS_MANAGE_GOOGLE_ACCOUNT},
+ {"syncAndNonPersonalizedServices",
+ IDS_SETTINGS_SYNC_SYNC_AND_NON_PERSONALIZED_SERVICES},
+#if defined(OS_CHROMEOS)
+ {"accountManagerSubMenuLabel", IDS_SETTINGS_ACCOUNT_MANAGER_SUBMENU_LABEL},
+#else
+ {"editPerson", IDS_SETTINGS_EDIT_PERSON},
+ {"profileNameAndPicture", IDS_SETTINGS_PROFILE_NAME_AND_PICTURE},
+#endif
+
+ // Manage profile strings:
+#if !defined(OS_CHROMEOS)
+ {"showShortcutLabel", IDS_SETTINGS_PROFILE_SHORTCUT_TOGGLE_LABEL},
+#endif
+ {"deleteProfileWarningExpandA11yLabel",
+ IDS_SETTINGS_SYNC_DISCONNECT_EXPAND_ACCESSIBILITY_LABEL},
+ {"deleteProfileWarningWithCountsSingular",
+ IDS_SETTINGS_SYNC_DISCONNECT_DELETE_PROFILE_WARNING_WITH_COUNTS_SINGULAR},
+ {"deleteProfileWarningWithCountsPlural",
+ IDS_SETTINGS_SYNC_DISCONNECT_DELETE_PROFILE_WARNING_WITH_COUNTS_PLURAL},
+ {"deleteProfileWarningWithoutCounts",
+ IDS_SETTINGS_SYNC_DISCONNECT_DELETE_PROFILE_WARNING_WITHOUT_COUNTS},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
// Add Google Account URL and include UTM parameter to signal the source of
// the navigation.
@@ -2336,52 +1061,21 @@ void AddPeopleStrings(content::WebUIDataSource* html_source, Profile* profile) {
net::AppendQueryParameter(GURL(chrome::kGoogleAccountURL), "utm_source",
"chrome-settings")
.spec());
-
html_source->AddBoolean("profileShortcutsEnabled",
ProfileShortcutManager::IsFeatureEnabled());
-
- html_source->AddBoolean(
- "changePictureVideoModeEnabled",
- base::FeatureList::IsEnabled(features::kChangePictureVideoMode));
-
- html_source->AddBoolean(
- "driveSuggestAvailable",
- base::FeatureList::IsEnabled(omnibox::kDocumentProvider));
-
#if defined(OS_CHROMEOS)
// Toggles the Chrome OS Account Manager submenu in the People section.
html_source->AddBoolean("isAccountManagerEnabled",
chromeos::IsAccountManagerAvailable(profile));
+#endif
- PrefService* local_state = g_browser_process->local_state();
-
- // Toggles the Chrome OS Kerberos Accounts submenu in the People section.
- // Note that the handler is also dependent on this pref.
- html_source->AddBoolean("isKerberosEnabled",
- local_state->GetBoolean(prefs::kKerberosEnabled));
-
- // Whether the 'Remember password' checkbox is enabled.
- html_source->AddBoolean(
- "kerberosRememberPasswordEnabled",
- local_state->GetBoolean(prefs::kKerberosRememberPasswordEnabled));
-
- // Whether new Kerberos accounts may be added.
- html_source->AddBoolean(
- "kerberosAddAccountsAllowed",
- local_state->GetBoolean(prefs::kKerberosAddAccountsAllowed));
-
- // Kerberos default configuration.
- html_source->AddString(
- "defaultKerberosConfig",
- chromeos::KerberosCredentialsManager::GetDefaultKerberosConfig());
-
- // Kerberos accounts page with "Learn more" link.
- html_source->AddString(
- "kerberosAccountsDescription",
- l10n_util::GetStringFUTF16(
- IDS_SETTINGS_KERBEROS_ACCOUNTS_DESCRIPTION,
- GetHelpUrlWithBoard(chrome::kKerberosAccountsLearnMoreURL)));
+ AddSignOutDialogStrings(html_source, profile);
+ AddSyncControlsStrings(html_source);
+ AddSyncAccountControlStrings(html_source);
+#if defined(OS_CHROMEOS)
+ AddPasswordPromptDialogStrings(html_source);
#endif
+ AddSyncPageStrings(html_source);
}
void AddPrintingStrings(content::WebUIDataSource* html_source) {
@@ -2393,126 +1087,7 @@ void AddPrintingStrings(content::WebUIDataSource* html_source) {
{"printingManageCloudPrintDevices",
IDS_SETTINGS_PRINTING_MANAGE_CLOUD_PRINT_DEVICES},
{"cloudPrintersTitle", IDS_SETTINGS_PRINTING_CLOUD_PRINTERS},
-#if defined(OS_CHROMEOS)
- {"cupsPrintersTitle", IDS_SETTINGS_PRINTING_CUPS_PRINTERS},
- {"cupsPrintersLearnMoreLabel",
- IDS_SETTINGS_PRINTING_CUPS_PRINTERS_LEARN_MORE_LABEL},
- {"addCupsPrinter", IDS_SETTINGS_PRINTING_CUPS_PRINTERS_ADD_PRINTER},
- {"editPrinter", IDS_SETTINGS_PRINTING_CUPS_PRINTERS_EDIT},
- {"removePrinter", IDS_SETTINGS_PRINTING_CUPS_PRINTERS_REMOVE},
- {"setupPrinter", IDS_SETTINGS_PRINTING_CUPS_PRINTER_SETUP_BUTTON},
- {"setupPrinterAria", IDS_SETTINGS_PRINTING_CUPS_PRINTER_SETUP_BUTTON_ARIA},
- {"savePrinter", IDS_SETTINGS_PRINTING_CUPS_PRINTER_SAVE_BUTTON},
- {"savePrinterAria", IDS_SETTINGS_PRINTING_CUPS_PRINTER_SAVE_BUTTON_ARIA},
- {"searchLabel", IDS_SETTINGS_PRINTING_CUPS_SEARCH_LABEL},
- {"noSearchResults", IDS_SEARCH_NO_RESULTS},
- {"printerDetailsTitle", IDS_SETTINGS_PRINTING_CUPS_PRINTER_DETAILS_TITLE},
- {"printerName", IDS_SETTINGS_PRINTING_CUPS_PRINTER_DETAILS_NAME},
- {"printerModel", IDS_SETTINGS_PRINTING_CUPS_PRINTER_DETAILS_MODEL},
- {"printerQueue", IDS_SETTINGS_PRINTING_CUPS_PRINTER_DETAILS_QUEUE},
- {"savedPrintersTitle", IDS_SETTINGS_PRINTING_CUPS_SAVED_PRINTERS_TITLE},
- {"savedPrintersCountMany",
- IDS_SETTINGS_PRINTING_CUPS_PRINTERS_SAVED_PRINTERS_COUNT_MANY},
- {"savedPrintersCountOne",
- IDS_SETTINGS_PRINTING_CUPS_PRINTERS_SAVED_PRINTERS_COUNT_ONE},
- {"savedPrintersCountNone",
- IDS_SETTINGS_PRINTING_CUPS_PRINTERS_SAVED_PRINTERS_COUNT_NONE},
- {"showMorePrinters", IDS_SETTINGS_PRINTING_CUPS_SHOW_MORE},
- {"addPrintersNearbyTitle",
- IDS_SETTINGS_PRINTING_CUPS_ADD_PRINTERS_NEARBY_TITLE},
- {"addPrintersManuallyTitle",
- IDS_SETTINGS_PRINTING_CUPS_ADD_PRINTERS_MANUALLY_TITLE},
- {"manufacturerAndModelDialogTitle",
- IDS_SETTINGS_PRINTING_CUPS_SELECT_MANUFACTURER_AND_MODEL_TITLE},
- {"nearbyPrintersListTitle",
- IDS_SETTINGS_PRINTING_CUPS_PRINTERS_AVAILABLE_PRINTERS},
- {"nearbyPrintersCountMany",
- IDS_SETTINGS_PRINTING_CUPS_PRINTERS_AVAILABLE_PRINTERS_COUNT_MANY},
- {"nearbyPrintersCountOne",
- IDS_SETTINGS_PRINTING_CUPS_PRINTERS_AVAILABLE_PRINTER_COUNT_ONE},
- {"nearbyPrintersCountNone",
- IDS_SETTINGS_PRINTING_CUPS_PRINTERS_AVAILABLE_PRINTER_COUNT_NONE},
- {"nearbyPrintersListDescription",
- IDS_SETTINGS_PRINTING_CUPS_PRINTERS_ADD_DETECTED_OR_NEW_PRINTER},
- {"manufacturerAndModelAdditionalInformation",
- IDS_SETTINGS_PRINTING_CUPS_MANUFACTURER_MODEL_ADDITIONAL_INFORMATION},
- {"addPrinterButtonText", IDS_SETTINGS_PRINTING_CUPS_ADD_PRINTER_BUTTON_ADD},
- {"printerDetailsAdvanced", IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADVANCED},
- {"printerDetailsA11yLabel",
- IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADVANCED_ACCESSIBILITY_LABEL},
- {"printerAddress", IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADVANCED_ADDRESS},
- {"printerProtocol", IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADVANCED_PROTOCOL},
- {"printerURI", IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADVANCED_URI},
- {"manuallyAddPrinterButtonText",
- IDS_SETTINGS_PRINTING_CUPS_ADD_PRINTER_BUTTON_MANUAL_ADD},
- {"discoverPrintersButtonText",
- IDS_SETTINGS_PRINTING_CUPS_ADD_PRINTER_BUTTON_DISCOVER_PRINTERS},
- {"printerProtocolIpp", IDS_SETTINGS_PRINTING_CUPS_PRINTER_PROTOCOL_IPP},
- {"printerProtocolIpps", IDS_SETTINGS_PRINTING_CUPS_PRINTER_PROTOCOL_IPPS},
- {"printerProtocolHttp", IDS_SETTINGS_PRINTING_CUPS_PRINTER_PROTOCOL_HTTP},
- {"printerProtocolHttps", IDS_SETTINGS_PRINTING_CUPS_PRINTER_PROTOCOL_HTTPS},
- {"printerProtocolAppSocket",
- IDS_SETTINGS_PRINTING_CUPS_PRINTER_PROTOCOL_APP_SOCKET},
- {"printerProtocolLpd", IDS_SETTINGS_PRINTING_CUPS_PRINTER_PROTOCOL_LPD},
- {"printerProtocolUsb", IDS_SETTINGS_PRINTING_CUPS_PRINTER_PROTOCOL_USB},
- {"printerProtocolIppUsb",
- IDS_SETTINGS_PRINTING_CUPS_PRINTER_PROTOCOL_IPPUSB},
- {"printerConfiguringMessage",
- IDS_SETTINGS_PRINTING_CUPS_PRINTER_CONFIGURING_MESSAGE},
- {"printerManufacturer", IDS_SETTINGS_PRINTING_CUPS_PRINTER_MANUFACTURER},
- {"selectDriver", IDS_SETTINGS_PRINTING_CUPS_PRINTER_SELECT_DRIVER},
- {"selectDriverButtonText",
- IDS_SETTINGS_PRINTING_CUPS_PRINTER_BUTTON_SELECT_DRIVER},
- {"selectDriverButtonAriaLabel",
- IDS_SETTINGS_PRINTING_CUPS_PRINTER_BUTTON_SELECT_DRIVER_ARIA_LABEL},
- {"selectDriverErrorMessage",
- IDS_SETTINGS_PRINTING_CUPS_PRINTER_INVALID_DRIVER},
- {"printerAddedSuccessfulMessage",
- IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_PRINTER_DONE_MESSAGE},
- {"printerEditedSuccessfulMessage",
- IDS_SETTINGS_PRINTING_CUPS_PRINTER_EDITED_PRINTER_DONE_MESSAGE},
- {"printerUnavailableMessage",
- IDS_SETTINGS_PRINTING_CUPS_PRINTER_UNAVAILABLE_MESSAGE},
- {"noPrinterNearbyMessage",
- IDS_SETTINGS_PRINTING_CUPS_PRINTER_NO_PRINTER_NEARBY},
- {"searchingNearbyPrinters",
- IDS_SETTINGS_PRINTING_CUPS_PRINTER_SEARCHING_NEARBY_PRINTER},
- {"printerAddedFailedMessage",
- IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_PRINTER_ERROR_MESSAGE},
- {"printerAddedFatalErrorMessage",
- IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_PRINTER_FATAL_ERROR_MESSAGE},
- {"printerAddedUnreachableMessage",
- IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_PRINTER_PRINTER_UNREACHABLE_MESSAGE},
- {"printerAddedPpdTooLargeMessage",
- IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_PRINTER_PPD_TOO_LARGE_MESSAGE},
- {"printerAddedInvalidPpdMessage",
- IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_PRINTER_INVALID_PPD_MESSAGE},
- {"printerAddedPpdNotFoundMessage",
- IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_PRINTER_PPD_NOT_FOUND},
- {"printerAddedPpdUnretrievableMessage",
- IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_PRINTER_PPD_UNRETRIEVABLE},
- {"printerAddedNativePrintersNotAllowedMessage",
- IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_NATIVE_PRINTERS_NOT_ALLOWED_MESSAGE},
- {"editPrinterInvalidPrinterUpdate",
- IDS_SETTINGS_PRINTING_CUPS_EDIT_PRINTER_INVALID_PRINTER_UPDATE},
- {"requireNetworkMessage",
- IDS_SETTINGS_PRINTING_CUPS_PRINTER_REQUIRE_INTERNET_MESSAGE},
- {"checkNetworkMessage",
- IDS_SETTINGS_PRINTING_CUPS_PRINTER_CHECK_CONNECTION_MESSAGE},
- {"noInternetConnection",
- IDS_SETTINGS_PRINTING_CUPS_PRINTER_NO_INTERNET_CONNECTION},
- {"checkNetworkAndTryAgain",
- IDS_SETTINGS_PRINTING_CUPS_PRINTER_CONNECT_TO_NETWORK_SUBTEXT},
- {"editPrinterDialogTitle",
- IDS_SETTINGS_PRINTING_CUPS_EDIT_PRINTER_DIALOG_TITLE},
- {"editPrinterButtonText", IDS_SETTINGS_PRINTING_CUPS_EDIT_PRINTER_BUTTON},
- {"currentPpdMessage",
- IDS_SETTINGS_PRINTING_CUPS_EDIT_PRINTER_CURRENT_PPD_MESSAGE},
- {"printerEulaNotice", IDS_SETTINGS_PRINTING_CUPS_EULA_NOTICE},
- {"ippPrinterUnreachable", IDS_SETTINGS_PRINTING_CUPS_IPP_URI_UNREACHABLE},
- {"generalPrinterDialogError",
- IDS_SETTINGS_PRINTING_CUPS_DIALOG_GENERAL_ERROR},
-#else
+#if !defined(OS_CHROMEOS)
{"localPrintersTitle", IDS_SETTINGS_PRINTING_LOCAL_PRINTERS_TITLE},
#endif
};
@@ -2521,18 +1096,6 @@ void AddPrintingStrings(content::WebUIDataSource* html_source) {
html_source->AddString("devicesUrl", chrome::kChromeUIDevicesURL);
html_source->AddString("printingCloudPrintLearnMoreUrl",
chrome::kCloudPrintLearnMoreURL);
-
-#if defined(OS_CHROMEOS)
- html_source->AddString("printingCUPSPrintLearnMoreUrl",
- GetHelpUrlWithBoard(chrome::kCupsPrintLearnMoreURL));
- html_source->AddString(
- "printingCUPSPrintPpdLearnMoreUrl",
- GetHelpUrlWithBoard(chrome::kCupsPrintPPDLearnMoreURL));
-
- html_source->AddBoolean(
- "updatedCupsPrintersUiEnabled",
- base::FeatureList::IsEnabled(features::kCupsPrintersUiOverhaul));
-#endif
}
void AddPrivacyStrings(content::WebUIDataSource* html_source,
@@ -2540,16 +1103,46 @@ void AddPrivacyStrings(content::WebUIDataSource* html_source,
static constexpr webui::LocalizedString kLocalizedStrings[] = {
{"privacyPageTitle", IDS_SETTINGS_PRIVACY},
{"privacyPageMore", IDS_SETTINGS_PRIVACY_MORE},
- {"signinAllowedTitle", IDS_SETTINGS_SIGNIN_ALLOWED},
- {"signinAllowedDescription", IDS_SETTINGS_SIGNIN_ALLOWED_DESC},
{"doNotTrack", IDS_SETTINGS_ENABLE_DO_NOT_TRACK},
{"doNotTrackDialogTitle", IDS_SETTINGS_ENABLE_DO_NOT_TRACK_DIALOG_TITLE},
- {"enableContentProtectionAttestation",
- IDS_SETTINGS_ENABLE_CONTENT_PROTECTION_ATTESTATION},
- {"wakeOnWifi", IDS_SETTINGS_WAKE_ON_WIFI_DESCRIPTION},
+ // TODO(crbug.com/1062607): This string is no longer used. Remove.
+ {"permissionsPageTitle", IDS_SETTINGS_PERMISSIONS},
+ {"permissionsPageDescription", IDS_SETTINGS_PERMISSIONS_DESCRIPTION},
+ {"securityPageTitle", IDS_SETTINGS_SECURITY},
+ {"securityPageDescription", IDS_SETTINGS_SECURITY_DESCRIPTION},
+ {"securityPageAdvancedSectionLabel",
+ IDS_SETTINGS_SECURITY_ADVANCED_SECTION_LABEL},
+ {"advancedProtectionProgramTitle",
+ IDS_SETTINGS_ADVANCED_PROTECTION_PROGRAM},
+ {"advancedProtectionProgramDesc",
+ IDS_SETTINGS_ADVANCED_PROTECTION_PROGRAM_DESC},
{"manageCertificates", IDS_SETTINGS_MANAGE_CERTIFICATES},
{"manageCertificatesDescription",
IDS_SETTINGS_MANAGE_CERTIFICATES_DESCRIPTION},
+ {"secureDns", IDS_SETTINGS_SECURE_DNS},
+ {"secureDnsDescription", IDS_SETTINGS_SECURE_DNS_DESCRIPTION},
+ {"secureDnsDisabledForManagedEnvironment",
+ IDS_SETTINGS_SECURE_DNS_DISABLED_FOR_MANAGED_ENVIRONMENT},
+ {"secureDnsDisabledForParentalControl",
+ IDS_SETTINGS_SECURE_DNS_DISABLED_FOR_PARENTAL_CONTROL},
+ {"secureDnsAutomaticModeDescription",
+ IDS_SETTINGS_AUTOMATIC_MODE_DESCRIPTION},
+ {"secureDnsAutomaticModeDescriptionSecondary",
+ IDS_SETTINGS_AUTOMATIC_MODE_DESCRIPTION_SECONDARY},
+ {"secureDnsSecureModeA11yLabel",
+ IDS_SETTINGS_SECURE_MODE_DESCRIPTION_ACCESSIBILITY_LABEL},
+ {"secureDnsDropdownA11yLabel",
+ IDS_SETTINGS_SECURE_DNS_DROPDOWN_ACCESSIBILITY_LABEL},
+ {"secureDnsSecureDropdownModeDescription",
+ IDS_SETTINGS_SECURE_DROPDOWN_MODE_DESCRIPTION},
+ {"secureDnsSecureDropdownModePrivacyPolicy",
+ IDS_SETTINGS_SECURE_DROPDOWN_MODE_PRIVACY_POLICY},
+ {"secureDnsCustomPlaceholder",
+ IDS_SETTINGS_SECURE_DNS_CUSTOM_PLACEHOLDER},
+ {"secureDnsCustomFormatError",
+ IDS_SETTINGS_SECURE_DNS_CUSTOM_FORMAT_ERROR},
+ {"secureDnsCustomConnectionError",
+ IDS_SETTINGS_SECURE_DNS_CUSTOM_CONNECTION_ERROR},
{"contentSettings", IDS_SETTINGS_CONTENT_SETTINGS},
{"siteSettings", IDS_SETTINGS_SITE_SETTINGS},
{"siteSettingsDescription", IDS_SETTINGS_SITE_SETTINGS_DESCRIPTION},
@@ -2561,37 +1154,125 @@ void AddPrivacyStrings(content::WebUIDataSource* html_source,
IDS_SETTINGS_SAFEBROWSING_ENABLE_REPORTING},
{"safeBrowsingEnableExtendedReportingDesc",
IDS_SETTINGS_SAFEBROWSING_ENABLE_REPORTING_DESC},
+ {"safeBrowsingEnhanced", IDS_SETTINGS_SAFEBROWSING_ENHANCED},
+ {"safeBrowsingEnhancedDesc", IDS_SETTINGS_SAFEBROWSING_ENHANCED_DESC},
+ {"safeBrowsingEnhancedBulOne",
+ IDS_SETTINGS_SAFEBROWSING_ENHANCED_BULLET_ONE},
+ {"safeBrowsingEnhancedBulTwo",
+ IDS_SETTINGS_SAFEBROWSING_ENHANCED_BULLET_TWO},
+ {"safeBrowsingEnhancedBulThree",
+ IDS_SETTINGS_SAFEBROWSING_ENHANCED_BULLET_THREE},
+ {"safeBrowsingEnhancedBulFour",
+ IDS_SETTINGS_SAFEBROWSING_ENHANCED_BULLET_FOUR},
+ {"safeBrowsingEnhancedBulFive",
+ IDS_SETTINGS_SAFEBROWSING_ENHANCED_BULLET_FIVE},
+ {"safeBrowsingStandard", IDS_SETTINGS_SAFEBROWSING_STANDARD},
+ {"safeBrowsingStandardDesc", IDS_SETTINGS_SAFEBROWSING_STANDARD_DESC},
+ {"safeBrowsingStandardBulOne",
+ IDS_SETTINGS_SAFEBROWSING_STANDARD_BULLET_ONE},
+ {"safeBrowsingStandardBulTwo",
+ IDS_SETTINGS_SAFEBROWSING_STANDARD_BULLET_TWO},
+ {"safeBrowsingStandardReportingLabel",
+ IDS_SETTINGS_SAFEBROWSING_STANDARD_HELP_IMPROVE},
+ {"safeBrowsingNone", IDS_SETTINGS_SAFEBROWSING_NONE},
+ {"safeBrowsingNoneDesc", IDS_SETTINGS_SAFEBROWSING_NONE_DESC},
+ {"safeBrowsingDisableDialog",
+ IDS_SETTINGS_SAFEBROWSING_DISABLE_DIALOG_TITLE},
+ {"safeBrowsingDisableDialogDesc",
+ IDS_SETTINGS_SAFEBROWSING_DISABLE_DIALOG_DESC},
+ {"safeBrowsingDisableDialogConfrim",
+ IDS_SETTINGS_SAFEBROWSING_DISABLE_DIALOG_CONFIRM},
{"safeBrowsingEnableProtection",
IDS_SETTINGS_SAFEBROWSING_ENABLEPROTECTION},
{"safeBrowsingEnableProtectionDesc",
IDS_SETTINGS_SAFEBROWSING_ENABLEPROTECTION_DESC},
+ {"safeBrowsingSectionLabel", IDS_SETTINGS_SAFEBROWSING_SECTION_LABEL},
{"syncAndGoogleServicesPrivacyDescription",
IDS_SETTINGS_SYNC_AND_GOOGLE_SERVICES_PRIVACY_DESC_UNIFIED_CONSENT},
{"urlKeyedAnonymizedDataCollection",
IDS_SETTINGS_ENABLE_URL_KEYED_ANONYMIZED_DATA_COLLECTION},
{"urlKeyedAnonymizedDataCollectionDesc",
IDS_SETTINGS_ENABLE_URL_KEYED_ANONYMIZED_DATA_COLLECTION_DESC},
- };
- AddLocalizedStringsBulk(html_source, kLocalizedStrings);
-
- static constexpr webui::LocalizedString kConditionalLocalizedStrings[] = {
- {"searchSuggestPref", IDS_SETTINGS_SUGGEST_PREF},
- {"searchSuggestPrefDesc", IDS_SETTINGS_SUGGEST_PREF_DESC},
+ {"noRecentPermissions", IDS_SETTINGS_RECENT_PERMISSIONS_NO_CHANGES},
+ {"recentPermissionChangeAutoblockedSentenceStart",
+ IDS_SETTINGS_RECENT_PERMISSIONS_CHANGE_AUTOBLOCKED_SENTENCE_START},
+ {"recentPermissionChangeBlockedSentenceStart",
+ IDS_SETTINGS_RECENT_PERMISSIONS_CHANGE_BLOCKED_SENTENCE_START},
+ {"recentPermissionChangeAllowedSentenceStart",
+ IDS_SETTINGS_RECENT_PERMISSIONS_CHANGE_ALLOWED_SENTENCE_START},
+ {"recentPermissionChangeAutoblocked",
+ IDS_SETTINGS_RECENT_PERMISSIONS_CHANGE_AUTOBLOCKED},
+ {"recentPermissionChangeBlocked",
+ IDS_SETTINGS_RECENT_PERMISSIONS_CHANGE_BLOCKED},
+ {"recentPermissionChangeAllowed",
+ IDS_SETTINGS_RECENT_PERMISSIONS_CHANGE_ALLOWED},
+ {"recentPermissionsTwoItems", IDS_SETTINGS_RECENT_PERMISSIONS_TWO_ITEMS},
+ {"recentPermissionsThreeItems",
+ IDS_SETTINGS_RECENT_PERMISSIONS_THREE_ITEMS},
+ {"recentPermissionsOverThreeItems",
+ IDS_SETTINGS_RECENT_PERMISSIONS_OVER_THREE_ITEMS},
+ {"recentPermissionsOneItemIncognito",
+ IDS_SETTINGS_RECENT_PERMISSIONS_ONE_ITEM_INCOGNITO},
+ {"recentPermissionsTwoItemsIncognito",
+ IDS_SETTINGS_RECENT_PERMISSIONS_TWO_ITEMS_INCOGNITO},
+ {"recentPermissionsThreeItemsIncognito",
+ IDS_SETTINGS_RECENT_PERMISSIONS_THREE_ITEMS_INCOGNITO},
+ {"recentPermissionsOverThreeItemsIncognito",
+ IDS_SETTINGS_RECENT_PERMISSIONS_OVER_THREE_ITEMS_INCOGNITO},
{"networkPredictionEnabled",
IDS_SETTINGS_NETWORK_PREDICTION_ENABLED_LABEL},
{"networkPredictionEnabledDesc",
IDS_SETTINGS_NETWORK_PREDICTION_ENABLED_DESC},
- {"linkDoctorPref", IDS_SETTINGS_LINKDOCTOR_PREF},
- {"linkDoctorPrefDesc", IDS_SETTINGS_LINKDOCTOR_PREF_DESC},
- {"spellingPref", IDS_SETTINGS_SPELLING_PREF},
- {"spellingDescription", IDS_SETTINGS_SPELLING_PREF_DESC},
- {"enableLogging", IDS_SETTINGS_ENABLE_LOGGING_PREF},
- {"enableLoggingDesc", IDS_SETTINGS_ENABLE_LOGGING_PREF_DESC},
+ {"networkPredictionEnabledDescCookiesPage",
+ IDS_SETTINGS_NETWORK_PREDICTION_ENABLED_DESC_COOKIES_PAGE},
+ {"safetyCheckSectionTitle", IDS_SETTINGS_SAFETY_CHECK_SECTION_TITLE},
+ {"safetyCheckParentPrimaryLabelBefore",
+ IDS_SETTINGS_SAFETY_CHECK_PARENT_PRIMARY_LABEL_BEFORE},
+ {"safetyCheckRunning", IDS_SETTINGS_SAFETY_CHECK_RUNNING},
+ {"safetyCheckParentPrimaryLabelAfter",
+ IDS_SETTINGS_SAFETY_CHECK_PARENT_PRIMARY_LABEL_AFTER},
+ {"safetyCheckAriaLiveRunning",
+ IDS_SETTINGS_SAFETY_CHECK_ARIA_LIVE_RUNNING},
+ {"safetyCheckAriaLiveAfter", IDS_SETTINGS_SAFETY_CHECK_ARIA_LIVE_AFTER},
+ {"safetyCheckParentButton", IDS_SETTINGS_SAFETY_CHECK_PARENT_BUTTON},
+ {"safetyCheckParentButtonAriaLabel",
+ IDS_SETTINGS_SAFETY_CHECK_PARENT_BUTTON_ARIA_LABEL},
+ {"safetyCheckIconRunningAriaLabel",
+ IDS_SETTINGS_SAFETY_CHECK_ICON_RUNNING_ARIA_LABEL},
+ {"safetyCheckIconSafeAriaLabel",
+ IDS_SETTINGS_SAFETY_CHECK_ICON_SAFE_ARIA_LABEL},
+ {"safetyCheckIconInfoAriaLabel",
+ IDS_SETTINGS_SAFETY_CHECK_ICON_INFO_ARIA_LABEL},
+ {"safetyCheckIconWarningAriaLabel",
+ IDS_SETTINGS_SAFETY_CHECK_ICON_WARNING_ARIA_LABEL},
+ {"safetyCheckUpdatesPrimaryLabel",
+ IDS_SETTINGS_SAFETY_CHECK_UPDATES_PRIMARY_LABEL},
+ {"safetyCheckUpdatesButtonAriaLabel",
+ IDS_UPDATE_RECOMMENDED_DIALOG_TITLE},
+ {"safetyCheckPasswordsButton",
+ IDS_SETTINGS_SAFETY_CHECK_PASSWORDS_BUTTON},
+ {"safetyCheckSafeBrowsingButton",
+ IDS_SETTINGS_SAFETY_CHECK_SAFE_BROWSING_BUTTON},
+ {"safetyCheckSafeBrowsingButtonAriaLabel",
+ IDS_SETTINGS_SAFETY_CHECK_SAFE_BROWSING_BUTTON_ARIA_LABEL},
+ {"safetyCheckExtensionsPrimaryLabel",
+ IDS_SETTINGS_SAFETY_CHECK_EXTENSIONS_PRIMARY_LABEL},
+ {"safetyCheckExtensionsButton",
+ IDS_SETTINGS_SAFETY_CHECK_EXTENSIONS_BUTTON},
+ {"safetyCheckExtensionsButtonAriaLabel",
+ IDS_SETTINGS_SAFETY_CHECK_EXTENSIONS_BUTTON_ARIA_LABEL},
};
- AddLocalizedStringsBulk(html_source, kConditionalLocalizedStrings);
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddString("cookiesSettingsHelpCenterURL",
+ chrome::kCookiesSettingsHelpCenterURL);
+
+ html_source->AddString("safeBrowsingHelpCenterURL",
+ chrome::kSafeBrowsingHelpCenterURL);
html_source->AddString("syncAndGoogleServicesLearnMoreURL",
chrome::kSyncAndGoogleServicesLearnMoreURL);
+
html_source->AddString(
"doNotTrackDialogMessage",
l10n_util::GetStringFUTF16(
@@ -2604,6 +1285,29 @@ void AddPrivacyStrings(content::WebUIDataSource* html_source,
html_source->AddString(
"exceptionsLearnMoreURL",
base::ASCIIToUTF16(chrome::kContentSettingsExceptionsLearnMoreURL));
+ html_source->AddBoolean(
+ "installedAppsInCbd",
+ base::FeatureList::IsEnabled(features::kStoragePressureUI));
+ html_source->AddBoolean(
+ "driveSuggestAvailable",
+ base::FeatureList::IsEnabled(omnibox::kDocumentProvider));
+ html_source->AddBoolean("showSecureDnsSetting",
+ features::kDnsOverHttpsShowUiParam.Get());
+
+ // The link to the Advanced Protection Program landing page, with a referrer
+ // from Chrome settings.
+ GURL advanced_protection_url(
+ "https://landing.google.com/advancedprotection/");
+ advanced_protection_url = net::AppendQueryParameter(advanced_protection_url,
+ "utm_source", "Chrome");
+ advanced_protection_url = net::AppendQueryParameter(
+ advanced_protection_url, "utm_medium", "ChromeSecuritySettings");
+ advanced_protection_url = net::AppendQueryParameter(
+ advanced_protection_url, "utm_campaign", "ChromeSettings");
+ html_source->AddString("advancedProtectionURL",
+ advanced_protection_url.spec());
+
+ AddPersonalizationOptionsStrings(html_source);
}
void AddSearchInSettingsStrings(content::WebUIDataSource* html_source) {
@@ -2623,52 +1327,18 @@ void AddSearchInSettingsStrings(content::WebUIDataSource* html_source) {
html_source->AddString("searchNoResultsHelp", help_text);
}
-void AddSearchStrings(content::WebUIDataSource* html_source, Profile* profile) {
-#if defined(OS_CHROMEOS)
- // NOTE: This will be false when the flag is disabled.
- const bool is_assistant_allowed =
- assistant::IsAssistantAllowedForProfile(profile) ==
- ash::mojom::AssistantAllowedState::ALLOWED;
- // SplitSettings moves Assistant to the OS settings window.
- const bool assistant_in_browser_settings =
- is_assistant_allowed && !chromeos::features::IsSplitSettingsEnabled();
-#endif
-
+void AddSearchStrings(content::WebUIDataSource* html_source) {
static constexpr webui::LocalizedString kLocalizedStrings[] = {
- {"searchEnginesManage", IDS_SETTINGS_SEARCH_MANAGE_SEARCH_ENGINES},
-#if defined(OS_CHROMEOS)
- {"osSearchEngineLabel", IDS_OS_SETTINGS_SEARCH_ENGINE_LABEL},
- {"searchGoogleAssistant", IDS_SETTINGS_SEARCH_GOOGLE_ASSISTANT},
- {"searchGoogleAssistantEnabled",
- IDS_SETTINGS_SEARCH_GOOGLE_ASSISTANT_ENABLED},
- {"searchGoogleAssistantDisabled",
- IDS_SETTINGS_SEARCH_GOOGLE_ASSISTANT_DISABLED},
-#endif
+ {"searchEnginesManage", IDS_SETTINGS_SEARCH_MANAGE_SEARCH_ENGINES},
+ {"searchPageTitle", IDS_SETTINGS_SEARCH},
+
};
AddLocalizedStringsBulk(html_source, kLocalizedStrings);
-#if defined(OS_CHROMEOS)
- html_source->AddLocalizedString("searchPageTitle",
- assistant_in_browser_settings
- ? IDS_SETTINGS_SEARCH_AND_ASSISTANT
- : IDS_SETTINGS_SEARCH);
- html_source->AddLocalizedString("osSearchPageTitle",
- is_assistant_allowed
- ? IDS_SETTINGS_SEARCH_AND_ASSISTANT
- : IDS_SETTINGS_SEARCH);
-#else
- html_source->AddLocalizedString("searchPageTitle", IDS_SETTINGS_SEARCH);
-#endif
- base::string16 search_explanation_text = l10n_util::GetStringFUTF16(
- IDS_SETTINGS_SEARCH_EXPLANATION,
- base::ASCIIToUTF16(chrome::kOmniboxLearnMoreURL));
- html_source->AddString("searchExplanation", search_explanation_text);
-#if defined(OS_CHROMEOS)
- html_source->AddString(
- "osSearchEngineTooltip",
- ui::SubstituteChromeOSDeviceType(IDS_OS_SETTINGS_SEARCH_ENGINE_TOOLTIP));
- html_source->AddBoolean("isAssistantAllowed", is_assistant_allowed);
-#endif
+ html_source->AddString("searchExplanation",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_SEARCH_EXPLANATION,
+ base::ASCIIToUTF16(chrome::kOmniboxLearnMoreURL)));
}
void AddSearchEnginesStrings(content::WebUIDataSource* html_source) {
@@ -2699,52 +1369,6 @@ void AddSearchEnginesStrings(content::WebUIDataSource* html_source) {
AddLocalizedStringsBulk(html_source, kLocalizedStrings);
}
-#if defined(OS_CHROMEOS)
-void AddGoogleAssistantStrings(content::WebUIDataSource* html_source,
- Profile* profile) {
- static constexpr webui::LocalizedString kLocalizedStrings[] = {
- {"googleAssistantPageTitle", IDS_SETTINGS_GOOGLE_ASSISTANT},
- {"googleAssistantEnableContext", IDS_ASSISTANT_SCREEN_CONTEXT_TITLE},
- {"googleAssistantEnableContextDescription",
- IDS_ASSISTANT_SCREEN_CONTEXT_DESC},
- {"googleAssistantEnableHotword",
- IDS_SETTINGS_GOOGLE_ASSISTANT_ENABLE_HOTWORD},
- {"googleAssistantEnableHotwordDescription",
- IDS_SETTINGS_GOOGLE_ASSISTANT_ENABLE_HOTWORD_DESCRIPTION},
- {"googleAssistantVoiceSettings",
- IDS_SETTINGS_GOOGLE_ASSISTANT_VOICE_SETTINGS},
- {"googleAssistantVoiceSettingsDescription",
- IDS_ASSISTANT_VOICE_MATCH_RECORDING},
- {"googleAssistantVoiceSettingsRetrainButton",
- IDS_SETTINGS_GOOGLE_ASSISTANT_VOICE_SETTINGS_RETRAIN},
- {"googleAssistantEnableHotwordWithoutDspDescription",
- IDS_SETTINGS_GOOGLE_ASSISTANT_ENABLE_HOTWORD_WITHOUT_DSP_DESCRIPTION},
- {"googleAssistantEnableHotwordWithoutDspRecommended",
- IDS_SETTINGS_GOOGLE_ASSISTANT_ENABLE_HOTWORD_WITHOUT_DSP_RECOMMENDED},
- {"googleAssistantEnableHotwordWithoutDspAlwaysOn",
- IDS_SETTINGS_GOOGLE_ASSISTANT_ENABLE_HOTWORD_WITHOUT_DSP_ALWAYS_ON},
- {"googleAssistantEnableHotwordWithoutDspOff",
- IDS_SETTINGS_GOOGLE_ASSISTANT_ENABLE_HOTWORD_WITHOUT_DSP_OFF},
- {"googleAssistantEnableNotification",
- IDS_SETTINGS_GOOGLE_ASSISTANT_ENABLE_NOTIFICATION},
- {"googleAssistantEnableNotificationDescription",
- IDS_SETTINGS_GOOGLE_ASSISTANT_ENABLE_NOTIFICATION_DESCRIPTION},
- {"googleAssistantLaunchWithMicOpen",
- IDS_SETTINGS_GOOGLE_ASSISTANT_LAUNCH_WITH_MIC_OPEN},
- {"googleAssistantLaunchWithMicOpenDescription",
- IDS_SETTINGS_GOOGLE_ASSISTANT_LAUNCH_WITH_MIC_OPEN_DESCRIPTION},
- {"googleAssistantSettings", IDS_SETTINGS_GOOGLE_ASSISTANT_SETTINGS},
- };
- AddLocalizedStringsBulk(html_source, kLocalizedStrings);
-
- html_source->AddBoolean("hotwordDspAvailable",
- chromeos::IsHotwordDspAvailable());
- html_source->AddBoolean(
- "voiceMatchDisabled",
- chromeos::assistant::features::IsVoiceMatchDisabled());
-}
-#endif
-
void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
Profile* profile) {
static constexpr webui::LocalizedString kLocalizedStrings[] = {
@@ -2800,6 +1424,8 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
{"mediaLicenseSize", IDS_SETTINGS_COOKIES_LOCAL_STORAGE_SIZE_ON_DISK_LABEL},
{"mediaLicenseLastModified",
IDS_SETTINGS_COOKIES_LOCAL_STORAGE_LAST_MODIFIED_LABEL},
+ {"noBluetoothDevicesFound", IDS_SETTINGS_NO_BLUETOOTH_DEVICES_FOUND},
+ {"noHidDevicesFound", IDS_SETTINGS_NO_HID_DEVICES_FOUND},
{"noSerialPortsFound", IDS_SETTINGS_NO_SERIAL_PORTS_FOUND},
{"noUsbDevicesFound", IDS_SETTINGS_NO_USB_DEVICES_FOUND},
{"serviceWorkerOrigin", IDS_SETTINGS_COOKIES_LOCAL_STORAGE_ORIGIN_LABEL},
@@ -2808,8 +1434,37 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
{"sharedWorkerWorker", IDS_SETTINGS_COOKIES_SHARED_WORKER_WORKER_LABEL},
{"sharedWorkerName", IDS_SETTINGS_COOKIES_COOKIE_NAME_LABEL},
{"siteSettingsCategoryPageTitle", IDS_SETTINGS_SITE_SETTINGS_CATEGORY},
+ {"siteSettingsRecentPermissionsSectionLabel",
+ IDS_SETTINGS_SITE_SETTINGS_RECENT_ACTIVITY},
{"siteSettingsCategoryCamera", IDS_SETTINGS_SITE_SETTINGS_CAMERA},
{"siteSettingsCameraLabel", IDS_SETTINGS_SITE_SETTINGS_CAMERA_LABEL},
+ {"cookiePageTitle", IDS_SETTINGS_COOKIES_PAGE},
+ {"cookiePageGeneralControls", IDS_SETTINGS_COOKIES_CONTROLS},
+ {"cookiePageAllowAll", IDS_SETTINGS_COOKIES_ALLOW_ALL},
+ {"cookiePageAllowAllBulOne", IDS_SETTINGS_COOKIES_ALLOW_ALL_BULLET_ONE},
+ {"cookiePageAllowAllBulTwo", IDS_SETTINGS_COOKIES_ALLOW_ALL_BULLET_TWO},
+ {"cookiePageBlockThirdIncognito",
+ IDS_SETTINGS_COOKIES_BLOCK_THIRD_PARTY_INCOGNITO},
+ {"cookiePageBlockThirdIncognitoBulOne",
+ IDS_SETTINGS_COOKIES_BLOCK_THIRD_PARTY_INCOGNITO_BULLET_ONE},
+ {"cookiePageBlockThirdIncognitoBulTwo",
+ IDS_SETTINGS_COOKIES_BLOCK_THIRD_PARTY_INCOGNITO_BULLET_TWO},
+ {"cookiePageBlockThird", IDS_SETTINGS_COOKIES_BLOCK_THIRD_PARTY},
+ {"cookiePageBlockThirdBulOne",
+ IDS_SETTINGS_COOKIES_BLOCK_THIRD_PARTY_BULLET_ONE},
+ {"cookiePageBlockThirdBulTwo",
+ IDS_SETTINGS_COOKIES_BLOCK_THIRD_PARTY_BULLET_TWO},
+ {"cookiePageBlockAll", IDS_SETTINGS_COOKIES_BLOCK_ALL},
+ {"cookiePageBlockAllBulOne", IDS_SETTINGS_COOKIES_BLOCK_ALL_BULLET_ONE},
+ {"cookiePageBlockAllBulTwo", IDS_SETTINGS_COOKIES_BLOCK_ALL_BULLET_TWO},
+ {"cookiePageBlockAllBulThree", IDS_SETTINGS_COOKIES_BLOCK_ALL_BULLET_THREE},
+ {"cookiePageClearOnExit", IDS_SETTINGS_COOKIES_CLEAR_ON_EXIT},
+ {"cookiePageAllowExceptions", IDS_SETTINGS_COOKIES_ALLOW_EXCEPTIONS},
+ {"cookiePageBlockExceptions", IDS_SETTINGS_COOKIES_BLOCK_EXCEPTIONS},
+ {"cookiePageSessionOnlyExceptions",
+ IDS_SETTINGS_COOKIES_SESSION_ONLY_EXCEPTIONS},
+ {"cookiesManageSiteSpecificExceptions",
+ IDS_SETTINGS_COOKIES_SITE_SPECIFIC_EXCEPTIONS},
{"siteSettingsCategoryCookies", IDS_SETTINGS_SITE_SETTINGS_COOKIES},
{"siteSettingsCategoryHandlers", IDS_SETTINGS_SITE_SETTINGS_HANDLERS},
{"siteSettingsCategoryImages", IDS_SETTINGS_SITE_SETTINGS_IMAGES},
@@ -2892,6 +1547,12 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
{"siteSettingsPopups", IDS_SETTINGS_SITE_SETTINGS_POPUPS},
{"siteSettingsUnsandboxedPlugins",
IDS_SETTINGS_SITE_SETTINGS_UNSANDBOXED_PLUGINS},
+ {"siteSettingsHidDevices", IDS_SETTINGS_SITE_SETTINGS_HID_DEVICES},
+ {"siteSettingsHidDevicesAsk", IDS_SETTINGS_SITE_SETTINGS_HID_DEVICES_ASK},
+ {"siteSettingsHidDevicesAskRecommended",
+ IDS_SETTINGS_SITE_SETTINGS_HID_DEVICES_ASK_RECOMMENDED},
+ {"siteSettingsHidDevicesBlock",
+ IDS_SETTINGS_SITE_SETTINGS_HID_DEVICES_BLOCK},
{"siteSettingsMidiDevices", IDS_SETTINGS_SITE_SETTINGS_MIDI_DEVICES},
{"siteSettingsMidiDevicesAsk", IDS_SETTINGS_SITE_SETTINGS_MIDI_DEVICES_ASK},
{"siteSettingsMidiDevicesAskRecommended",
@@ -2910,6 +1571,14 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
IDS_SETTINGS_SITE_SETTINGS_USB_DEVICES_ASK_RECOMMENDED},
{"siteSettingsUsbDevicesBlock",
IDS_SETTINGS_SITE_SETTINGS_USB_DEVICES_BLOCK},
+ {"siteSettingsBluetoothDevices",
+ IDS_SETTINGS_SITE_SETTINGS_BLUETOOTH_DEVICES},
+ {"siteSettingsBluetoothDevicesAsk",
+ IDS_SETTINGS_SITE_SETTINGS_BLUETOOTH_DEVICES_ASK},
+ {"siteSettingsBluetoothDevicesAskRecommended",
+ IDS_SETTINGS_SITE_SETTINGS_BLUETOOTH_DEVICES_ASK_RECOMMENDED},
+ {"siteSettingsBluetoothDevicesBlock",
+ IDS_SETTINGS_SITE_SETTINGS_BLUETOOTH_DEVICES_BLOCK},
{"siteSettingsNativeFileSystemWrite",
IDS_SETTINGS_SITE_SETTINGS_NATIVE_FILE_SYSTEM_WRITE},
{"siteSettingsNativeFileSystemWriteAsk",
@@ -2996,6 +1665,10 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
{"siteSettingsUsage", IDS_SETTINGS_SITE_SETTINGS_USAGE},
{"siteSettingsUsageNone", IDS_SETTINGS_SITE_SETTINGS_USAGE_NONE},
{"siteSettingsPermissions", IDS_SETTINGS_SITE_SETTINGS_PERMISSIONS},
+ {"siteSettingsPermissionsMore",
+ IDS_SETTINGS_SITE_SETTINGS_PERMISSIONS_MORE},
+ {"siteSettingsContent", IDS_SETTINGS_SITE_SETTINGS_CONTENT},
+ {"siteSettingsContentMore", IDS_SETTINGS_SITE_SETTINGS_CONTENT_MORE},
{"siteSettingsSourceExtensionAllow",
IDS_PAGE_INFO_PERMISSION_ALLOWED_BY_EXTENSION},
{"siteSettingsSourceExtensionBlock",
@@ -3048,6 +1721,24 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
{"siteSettingsCookieSearch", IDS_SETTINGS_SITE_SETTINGS_COOKIE_SEARCH},
{"siteSettingsCookieSubpage", IDS_SETTINGS_SITE_SETTINGS_COOKIE_SUBPAGE},
{"siteSettingsDelete", IDS_SETTINGS_SITE_SETTINGS_DELETE},
+ {"siteSettingsClearAllStorageDialogTitle",
+ IDS_SETTINGS_SITE_SETTINGS_CLEAR_ALL_STORAGE_DIALOG_TITLE},
+ {"siteSettingsClearAllStorageDescription",
+ IDS_SETTINGS_SITE_SETTINGS_CLEAR_ALL_STORAGE_DESCRIPTION},
+ {"siteSettingsClearAllStorageLabel",
+ IDS_SETTINGS_SITE_SETTINGS_CLEAR_ALL_STORAGE_LABEL},
+ {"siteSettingsClearAllStorageConfirmation",
+ IDS_SETTINGS_SITE_SETTINGS_CLEAR_ALL_STORAGE_CONFIRMATION},
+ {"siteSettingsClearAllStorageConfirmationInstalled",
+ IDS_SETTINGS_SITE_SETTINGS_CLEAR_ALL_STORAGE_CONFIRMATION_INSTALLED},
+ {"siteSettingsClearAllStorageSignOut",
+ IDS_SETTINGS_SITE_SETTINGS_CLEAR_ALL_STORAGE_SIGN_OUT},
+ {"siteSettingsOriginDeleteConfirmation",
+ IDS_SETTINGS_SITE_SETTINGS_ORIGIN_DELETE_CONFIRMATION},
+ {"siteSettingsOriginDeleteConfirmationInstalled",
+ IDS_SETTINGS_SITE_SETTINGS_ORIGIN_DELETE_CONFIRMATION_INSTALLED},
+ {"siteSettingsSiteGroupDeleteConfirmationInstalledPlural",
+ IDS_SETTINGS_SITE_SETTINGS_SITE_GROUP_DELETE_CONFIRMATION_INSTALLED_PLURAL},
{"siteSettingsSiteClearStorage",
IDS_SETTINGS_SITE_SETTINGS_SITE_CLEAR_STORAGE},
{"siteSettingsSiteClearStorageConfirmation",
@@ -3069,6 +1760,8 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
IDS_SETTINGS_SITE_SETTINGS_SITE_GROUP_DELETE_CONFIRMATION},
{"siteSettingsSiteGroupDeleteConfirmationNew",
IDS_SETTINGS_SITE_SETTINGS_SITE_GROUP_DELETE_CONFIRMATION_NEW},
+ {"siteSettingsSiteGroupDeleteConfirmationInstalled",
+ IDS_SETTINGS_SITE_SETTINGS_SITE_GROUP_DELETE_CONFIRMATION_INSTALLED},
{"siteSettingsSiteGroupDeleteSignOut",
IDS_SETTINGS_SITE_SETTINGS_SITE_GROUP_DELETE_SIGN_OUT},
{"siteSettingsSiteGroupDeleteOfflineData",
@@ -3083,18 +1776,17 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
{"siteSettingsSiteResetAll", IDS_SETTINGS_SITE_SETTINGS_SITE_RESET_ALL},
{"siteSettingsSiteResetConfirmation",
IDS_SETTINGS_SITE_SETTINGS_SITE_RESET_CONFIRMATION},
- {"thirdPartyCookie", IDS_SETTINGS_SITE_SETTINGS_THIRD_PARTY_COOKIE},
- {"thirdPartyCookieSublabel",
- IDS_SETTINGS_SITE_SETTINGS_THIRD_PARTY_COOKIE_SUBLABEL},
+ {"thirdPartyCookie", IDS_NEW_TAB_OTR_THIRD_PARTY_COOKIE},
+ {"thirdPartyCookieSublabel", IDS_NEW_TAB_OTR_THIRD_PARTY_COOKIE_SUBLABEL},
{"deleteDataPostSession",
IDS_SETTINGS_SITE_SETTINGS_DELETE_DATA_POST_SESSION},
{"handlerIsDefault", IDS_SETTINGS_SITE_SETTINGS_HANDLER_IS_DEFAULT},
{"handlerSetDefault", IDS_SETTINGS_SITE_SETTINGS_HANDLER_SET_DEFAULT},
{"handlerRemove", IDS_SETTINGS_SITE_SETTINGS_REMOVE},
{"adobeFlashStorage", IDS_SETTINGS_SITE_SETTINGS_ADOBE_FLASH_SETTINGS},
- {"incognitoSite", IDS_SETTINGS_SITE_SETTINGS_INCOGNITO},
{"incognitoSiteOnly", IDS_SETTINGS_SITE_SETTINGS_INCOGNITO_ONLY},
- {"embeddedIncognitoSite", IDS_SETTINGS_SITE_SETTINGS_INCOGNITO_EMBEDDED},
+ {"incognitoSiteExceptionDesc",
+ IDS_SETTINGS_SITE_SETTINGS_INCOGNITO_SITE_EXCEPTION_DESC},
{"noSitesAdded", IDS_SETTINGS_SITE_NO_SITES_ADDED},
{"siteSettingsAds", IDS_SETTINGS_SITE_SETTINGS_ADS},
{"siteSettingsAdsBlock", IDS_SETTINGS_SITE_SETTINGS_ADS_BLOCK},
@@ -3119,6 +1811,16 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
IDS_SETTINGS_SITE_SETTINGS_BLUETOOTH_SCANNING_ASK_RECOMMENDED},
{"siteSettingsBluetoothScanningBlock",
IDS_SETTINGS_SITE_SETTINGS_BLUETOOTH_SCANNING_BLOCK},
+ {"siteSettingsAr", IDS_SETTINGS_SITE_SETTINGS_AR},
+ {"siteSettingsArAsk", IDS_SETTINGS_SITE_SETTINGS_AR_ASK},
+ {"siteSettingsArAskRecommended",
+ IDS_SETTINGS_SITE_SETTINGS_AR_ASK_RECOMMENDED},
+ {"siteSettingsArBlock", IDS_SETTINGS_SITE_SETTINGS_AR_BLOCK},
+ {"siteSettingsVr", IDS_SETTINGS_SITE_SETTINGS_VR},
+ {"siteSettingsVrAsk", IDS_SETTINGS_SITE_SETTINGS_VR_ASK},
+ {"siteSettingsVrAskRecommended",
+ IDS_SETTINGS_SITE_SETTINGS_VR_ASK_RECOMMENDED},
+ {"siteSettingsVrBlock", IDS_SETTINGS_SITE_SETTINGS_VR_BLOCK},
};
AddLocalizedStringsBulk(html_source, kLocalizedStrings);
@@ -3187,25 +1889,15 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
html_source->AddBoolean(
"enableQuietNotificationPromptsSetting",
base::FeatureList::IsEnabled(features::kQuietNotificationPrompts));
-}
-#if defined(OS_CHROMEOS)
-void AddUsersStrings(content::WebUIDataSource* html_source) {
- static constexpr webui::LocalizedString kLocalizedStrings[] = {
- {"usersModifiedByOwnerLabel", IDS_SETTINGS_USERS_MODIFIED_BY_OWNER_LABEL},
- {"guestBrowsingLabel", IDS_SETTINGS_USERS_GUEST_BROWSING_LABEL},
- {"settingsManagedLabel", IDS_SETTINGS_USERS_MANAGED_LABEL},
- {"showOnSigninLabel", IDS_SETTINGS_USERS_SHOW_ON_SIGNIN_LABEL},
- {"restrictSigninLabel", IDS_SETTINGS_USERS_RESTRICT_SIGNIN_LABEL},
- {"deviceOwnerLabel", IDS_SETTINGS_USERS_DEVICE_OWNER_LABEL},
- {"removeUserTooltip", IDS_SETTINGS_USERS_REMOVE_USER_TOOLTIP},
- {"addUsers", IDS_SETTINGS_USERS_ADD_USERS},
- {"addUsersEmail", IDS_SETTINGS_USERS_ADD_USERS_EMAIL},
- {"userExistsError", IDS_SETTINGS_USER_EXISTS_ERROR},
- };
- AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+ html_source->AddBoolean("enableWebBluetoothNewPermissionsBackend",
+ base::FeatureList::IsEnabled(
+ features::kWebBluetoothNewPermissionsBackend));
+
+ html_source->AddBoolean(
+ "enableWebXrContentSetting",
+ base::FeatureList::IsEnabled(features::kWebXrPermissionsApi));
}
-#endif
#if !defined(OS_CHROMEOS)
void AddSystemStrings(content::WebUIDataSource* html_source) {
@@ -3237,110 +1929,6 @@ void AddSystemStrings(content::WebUIDataSource* html_source) {
}
#endif
-void AddWebContentStrings(content::WebUIDataSource* html_source) {
- static constexpr webui::LocalizedString kLocalizedStrings[] = {
- {"webContent", IDS_SETTINGS_WEB_CONTENT},
- {"pageZoom", IDS_SETTINGS_PAGE_ZOOM_LABEL},
- {"fontSize", IDS_SETTINGS_FONT_SIZE_LABEL},
- {"verySmall", IDS_SETTINGS_VERY_SMALL_FONT},
- {"small", IDS_SETTINGS_SMALL_FONT},
- {"medium", IDS_SETTINGS_MEDIUM_FONT},
- {"large", IDS_SETTINGS_LARGE_FONT},
- {"veryLarge", IDS_SETTINGS_VERY_LARGE_FONT},
- {"custom", IDS_SETTINGS_CUSTOM},
- {"customizeFonts", IDS_SETTINGS_CUSTOMIZE_FONTS},
- {"fonts", IDS_SETTINGS_FONTS},
- {"standardFont", IDS_SETTINGS_STANDARD_FONT_LABEL},
- {"serifFont", IDS_SETTINGS_SERIF_FONT_LABEL},
- {"sansSerifFont", IDS_SETTINGS_SANS_SERIF_FONT_LABEL},
- {"fixedWidthFont", IDS_SETTINGS_FIXED_WIDTH_FONT_LABEL},
- {"minimumFont", IDS_SETTINGS_MINIMUM_FONT_SIZE_LABEL},
- {"tiny", IDS_SETTINGS_TINY_FONT_SIZE},
- {"huge", IDS_SETTINGS_HUGE_FONT_SIZE},
- {"loremIpsum", IDS_SETTINGS_LOREM_IPSUM},
- {"loading", IDS_SETTINGS_LOADING},
- {"advancedFontSettings", IDS_SETTINGS_ADVANCED_FONT_SETTINGS},
- {"openAdvancedFontSettings", IDS_SETTINGS_OPEN_ADVANCED_FONT_SETTINGS},
- {"requiresWebStoreExtension", IDS_SETTINGS_REQUIRES_WEB_STORE_EXTENSION},
- {"quickBrownFox", IDS_SETTINGS_QUICK_BROWN_FOX},
- };
- AddLocalizedStringsBulk(html_source, kLocalizedStrings);
-}
-
-#if defined(OS_CHROMEOS)
-void AddMultideviceStrings(content::WebUIDataSource* html_source) {
- static constexpr webui::LocalizedString kLocalizedStrings[] = {
- {"multidevicePageTitle", IDS_SETTINGS_MULTIDEVICE},
- {"multideviceSetupButton", IDS_SETTINGS_MULTIDEVICE_SETUP_BUTTON},
- {"multideviceVerifyButton", IDS_SETTINGS_MULTIDEVICE_VERIFY_BUTTON},
- {"multideviceSetupItemHeading",
- IDS_SETTINGS_MULTIDEVICE_SETUP_ITEM_HEADING},
- {"multideviceEnabled", IDS_SETTINGS_MULTIDEVICE_ENABLED},
- {"multideviceDisabled", IDS_SETTINGS_MULTIDEVICE_DISABLED},
- {"multideviceSmartLockItemTitle", IDS_SETTINGS_EASY_UNLOCK_SECTION_TITLE},
- {"multideviceInstantTetheringItemTitle",
- IDS_SETTINGS_MULTIDEVICE_INSTANT_TETHERING},
- {"multideviceInstantTetheringItemSummary",
- IDS_SETTINGS_MULTIDEVICE_INSTANT_TETHERING_SUMMARY},
- {"multideviceAndroidMessagesItemTitle",
- IDS_SETTINGS_MULTIDEVICE_ANDROID_MESSAGES},
- {"multideviceForgetDevice", IDS_SETTINGS_MULTIDEVICE_FORGET_THIS_DEVICE},
- {"multideviceSmartLockOptions",
- IDS_SETTINGS_PEOPLE_LOCK_SCREEN_OPTIONS_LOCK},
- {"multideviceForgetDeviceDisconnect",
- IDS_SETTINGS_MULTIDEVICE_FORGET_THIS_DEVICE_DISCONNECT},
- };
- AddLocalizedStringsBulk(html_source, kLocalizedStrings);
-
- html_source->AddString(
- "multideviceForgetDeviceSummary",
- ui::SubstituteChromeOSDeviceType(
- IDS_SETTINGS_MULTIDEVICE_FORGET_THIS_DEVICE_EXPLANATION));
- html_source->AddString(
- "multideviceForgetDeviceDialogMessage",
- ui::SubstituteChromeOSDeviceType(
- IDS_SETTINGS_MULTIDEVICE_FORGET_DEVICE_DIALOG_MESSAGE));
- html_source->AddString(
- "multideviceVerificationText",
- l10n_util::GetStringFUTF16(
- IDS_SETTINGS_MULTIDEVICE_VERIFICATION_TEXT,
- base::UTF8ToUTF16(
- chromeos::multidevice_setup::
- GetBoardSpecificBetterTogetherSuiteLearnMoreUrl()
- .spec())));
- html_source->AddString(
- "multideviceSetupSummary",
- l10n_util::GetStringFUTF16(
- IDS_SETTINGS_MULTIDEVICE_SETUP_SUMMARY, ui::GetChromeOSDeviceName(),
- base::UTF8ToUTF16(
- chromeos::multidevice_setup::
- GetBoardSpecificBetterTogetherSuiteLearnMoreUrl()
- .spec())));
- html_source->AddString(
- "multideviceNoHostText",
- l10n_util::GetStringFUTF16(
- IDS_SETTINGS_MULTIDEVICE_NO_ELIGIBLE_HOSTS,
- base::UTF8ToUTF16(
- chromeos::multidevice_setup::
- GetBoardSpecificBetterTogetherSuiteLearnMoreUrl()
- .spec())));
- html_source->AddString(
- "multideviceAndroidMessagesItemSummary",
- l10n_util::GetStringFUTF16(
- IDS_SETTINGS_MULTIDEVICE_ANDROID_MESSAGES_SUMMARY,
- ui::GetChromeOSDeviceName(),
- base::UTF8ToUTF16(chromeos::multidevice_setup::
- GetBoardSpecificMessagesLearnMoreUrl()
- .spec())));
- html_source->AddString(
- "multideviceSmartLockItemSummary",
- l10n_util::GetStringFUTF16(
- IDS_SETTINGS_MULTIDEVICE_SMART_LOCK_SUMMARY,
- ui::GetChromeOSDeviceName(),
- GetHelpUrlWithBoard(chrome::kEasyUnlockLearnMoreUrl)));
-}
-#endif
-
void AddExtensionsStrings(content::WebUIDataSource* html_source) {
html_source->AddLocalizedString("extensionsPageTitle",
IDS_SETTINGS_EXTENSIONS_CHECKBOX_LABEL);
@@ -3358,6 +1946,10 @@ void AddSecurityKeysStrings(content::WebUIDataSource* html_source) {
IDS_SETTINGS_SECURITY_KEYS_BIO_ENROLLMENT_ENROLLING_COMPLETE_LABEL},
{"securityKeysBioEnrollmentEnrollingLabel",
IDS_SETTINGS_SECURITY_KEYS_BIO_ENROLLMENT_ENROLLING_LABEL},
+ {"securityKeysBioEnrollmentEnrollingFailedLabel",
+ IDS_SETTINGS_SECURITY_KEYS_BIO_ENROLLMENT_FAILED_LABEL},
+ {"securityKeysBioEnrollmentTryAgainLabel",
+ IDS_SETTINGS_SECURITY_KEYS_BIO_ENROLLMENT_TRY_AGAIN_LABEL},
{"securityKeysBioEnrollmentEnrollmentsLabel",
IDS_SETTINGS_SECURITY_KEYS_BIO_ENROLLMENT_ENROLLMENTS_LABEL},
{"securityKeysBioEnrollmentNoEnrollmentsLabel",
@@ -3453,11 +2045,11 @@ void AddSecurityKeysStrings(content::WebUIDataSource* html_source) {
} // namespace
-void AddLocalizedStrings(content::WebUIDataSource* html_source,
- Profile* profile,
- content::WebContents* web_contents) {
+void AddBrowserLocalizedStrings(content::WebUIDataSource* html_source,
+ Profile* profile,
+ content::WebContents* web_contents) {
AddA11yStrings(html_source);
- AddAboutStrings(html_source);
+ AddAboutStrings(html_source, profile);
AddAutofillStrings(html_source, profile, web_contents);
AddAppearanceStrings(html_source, profile);
@@ -3466,41 +2058,22 @@ void AddLocalizedStrings(content::WebUIDataSource* html_source,
AddIncompatibleApplicationsStrings(html_source);
#endif // defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
- AddChangePasswordStrings(html_source);
AddClearBrowsingDataStrings(html_source, profile);
AddCommonStrings(html_source, profile);
AddDownloadsStrings(html_source);
- AddLanguagesStrings(html_source);
+ AddLanguagesStrings(html_source, profile);
AddOnStartupStrings(html_source);
AddPeopleStrings(html_source, profile);
AddPrintingStrings(html_source);
AddPrivacyStrings(html_source, profile);
AddResetStrings(html_source);
AddSearchEnginesStrings(html_source);
-#if defined(OS_CHROMEOS)
- AddGoogleAssistantStrings(html_source, profile);
-#endif
AddSearchInSettingsStrings(html_source);
- AddSearchStrings(html_source, profile);
+ AddSearchStrings(html_source);
AddSiteSettingsStrings(html_source, profile);
- AddWebContentStrings(html_source);
#if defined(OS_CHROMEOS)
- AddAndroidAppStrings(html_source);
- AddAppManagementStrings(html_source);
- AddAppsStrings(html_source);
- AddBluetoothStrings(html_source);
AddChromeOSUserStrings(html_source, profile);
- AddCrostiniStrings(html_source, profile);
- AddDateTimeStrings(html_source);
- AddDeviceStrings(html_source);
- AddEasyUnlockStrings(html_source);
- AddFilesStrings(html_source);
- AddInternetStrings(html_source);
- AddMultideviceStrings(html_source);
- AddParentalControlStrings(html_source);
- AddPluginVmStrings(html_source, profile);
- AddUsersStrings(html_source);
#else
AddDefaultBrowserStrings(html_source);
AddImportDataStrings(html_source);
@@ -3512,13 +2085,6 @@ void AddLocalizedStrings(content::WebUIDataSource* html_source,
certificate_manager::AddLocalizedStrings(html_source);
#endif
-#if defined(OS_CHROMEOS)
- chromeos::network_element::AddLocalizedStrings(html_source);
- chromeos::network_element::AddOncLocalizedStrings(html_source);
- chromeos::network_element::AddDetailsLocalizedStrings(html_source);
- chromeos::network_element::AddConfigLocalizedStrings(html_source);
- chromeos::network_element::AddErrorLocalizedStrings(html_source);
-#endif
policy_indicator::AddLocalizedStrings(html_source);
AddSecurityKeysStrings(html_source);
diff --git a/chromium/chrome/browser/ui/webui/settings/settings_localized_strings_provider.h b/chromium/chrome/browser/ui/webui/settings/settings_localized_strings_provider.h
index a72290f479f..0940dc5a24e 100644
--- a/chromium/chrome/browser/ui/webui/settings/settings_localized_strings_provider.h
+++ b/chromium/chrome/browser/ui/webui/settings/settings_localized_strings_provider.h
@@ -14,12 +14,14 @@ class WebContents;
namespace settings {
-// Adds the strings needed by the settings page to |html_source|. This function
-// causes |html_source| to expose a strings.js file from its source which
-// contains a mapping from string's name to its translated value.
-void AddLocalizedStrings(content::WebUIDataSource* html_source,
- Profile* profile,
- content::WebContents* web_contents);
+// Adds the strings needed by the browser settings page to |html_source|
+// This function causes |html_source| to expose a strings.js file from its
+// source which contains a mapping from string's name to its translated value.
+// TODO(crbug/967888): This still contains OS Settings strings. Strings specific
+// to OS settings should be moved to os_settings_localized_strings_provider.cc.
+void AddBrowserLocalizedStrings(content::WebUIDataSource* html_source,
+ Profile* profile,
+ content::WebContents* web_contents);
} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc b/chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc
new file mode 100644
index 00000000000..0ba238f7959
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc
@@ -0,0 +1,314 @@
+// Copyright 2020 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 "chrome/browser/ui/webui/settings/settings_secure_dns_handler.h"
+
+#include <memory>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/rand_util.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/net/dns_util.h"
+#include "chrome/browser/net/stub_resolver_config_reader.h"
+#include "chrome/browser/net/system_network_context_manager.h"
+#include "chrome/common/chrome_features.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/grit/generated_resources.h"
+#include "components/country_codes/country_codes.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/storage_partition.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_ui.h"
+#include "net/dns/public/dns_over_https_server_config.h"
+#include "net/dns/public/doh_provider_list.h"
+#include "net/dns/public/util.h"
+#include "ui/base/l10n/l10n_util.h"
+
+namespace settings {
+
+namespace {
+
+const char kProbeHostname[] = "google.com";
+
+std::unique_ptr<base::DictionaryValue> CreateSecureDnsSettingDict() {
+ // Fetch the current host resolver configuration. It is not sufficient to read
+ // the secure DNS prefs directly since the host resolver configuration takes
+ // other factors into account such as whether a managed environment or
+ // parental controls have been detected.
+ bool insecure_stub_resolver_enabled = false;
+ net::DnsConfig::SecureDnsMode secure_dns_mode;
+ std::vector<net::DnsOverHttpsServerConfig> dns_over_https_servers;
+ chrome_browser_net::SecureDnsUiManagementMode management_mode;
+ SystemNetworkContextManager::GetStubResolverConfigReader()->GetConfiguration(
+ true /* force_check_parental_controls_for_automatic_mode */,
+ &insecure_stub_resolver_enabled, &secure_dns_mode,
+ &dns_over_https_servers, &management_mode);
+
+ std::string secure_dns_mode_str;
+ switch (secure_dns_mode) {
+ case net::DnsConfig::SecureDnsMode::SECURE:
+ secure_dns_mode_str = chrome_browser_net::kDnsOverHttpsModeSecure;
+ break;
+ case net::DnsConfig::SecureDnsMode::AUTOMATIC:
+ secure_dns_mode_str = chrome_browser_net::kDnsOverHttpsModeAutomatic;
+ break;
+ case net::DnsConfig::SecureDnsMode::OFF:
+ secure_dns_mode_str = chrome_browser_net::kDnsOverHttpsModeOff;
+ break;
+ default:
+ NOTREACHED();
+ }
+
+ auto secure_dns_templates = std::make_unique<base::ListValue>();
+ for (const auto& doh_server : dns_over_https_servers) {
+ secure_dns_templates->Append(doh_server.server_template);
+ }
+
+ auto dict = std::make_unique<base::DictionaryValue>();
+ dict->SetString("mode", secure_dns_mode_str);
+ dict->SetList("templates", std::move(secure_dns_templates));
+ dict->SetInteger("managementMode", static_cast<int>(management_mode));
+ return dict;
+}
+
+} // namespace
+
+SecureDnsHandler::SecureDnsHandler() = default;
+
+SecureDnsHandler::~SecureDnsHandler() = default;
+
+void SecureDnsHandler::RegisterMessages() {
+ web_ui()->RegisterMessageCallback(
+ "getSecureDnsResolverList",
+ base::BindRepeating(&SecureDnsHandler::HandleGetSecureDnsResolverList,
+ base::Unretained(this)));
+
+ web_ui()->RegisterMessageCallback(
+ "getSecureDnsSetting",
+ base::BindRepeating(&SecureDnsHandler::HandleGetSecureDnsSetting,
+ base::Unretained(this)));
+
+ web_ui()->RegisterMessageCallback(
+ "validateCustomDnsEntry",
+ base::BindRepeating(&SecureDnsHandler::HandleValidateCustomDnsEntry,
+ base::Unretained(this)));
+
+ web_ui()->RegisterMessageCallback(
+ "probeCustomDnsTemplate",
+ base::BindRepeating(&SecureDnsHandler::HandleProbeCustomDnsTemplate,
+ base::Unretained(this)));
+
+ web_ui()->RegisterMessageCallback(
+ "recordUserDropdownInteraction",
+ base::BindRepeating(
+ &SecureDnsHandler::HandleRecordUserDropdownInteraction,
+ base::Unretained(this)));
+}
+
+void SecureDnsHandler::OnJavascriptAllowed() {
+ // Register for updates to the underlying secure DNS prefs so that the
+ // secure DNS setting can be updated to reflect the current host resolver
+ // configuration.
+ pref_registrar_.Init(g_browser_process->local_state());
+ pref_registrar_.Add(
+ prefs::kDnsOverHttpsMode,
+ base::Bind(&SecureDnsHandler::SendSecureDnsSettingUpdatesToJavascript,
+ base::Unretained(this)));
+ pref_registrar_.Add(
+ prefs::kDnsOverHttpsTemplates,
+ base::Bind(&SecureDnsHandler::SendSecureDnsSettingUpdatesToJavascript,
+ base::Unretained(this)));
+}
+
+void SecureDnsHandler::OnJavascriptDisallowed() {
+ pref_registrar_.RemoveAll();
+}
+
+base::Value SecureDnsHandler::GetSecureDnsResolverListForCountry(
+ int country_id,
+ const std::vector<net::DohProviderEntry>& providers) {
+ std::vector<std::string> disabled_providers =
+ SplitString(features::kDnsOverHttpsDisabledProvidersParam.Get(), ",",
+ base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+
+ base::Value resolvers(base::Value::Type::LIST);
+ resolver_histogram_map_.clear();
+ // Add all non-disabled resolvers that should be displayed in |country_id|.
+ for (const auto& entry : providers) {
+ if (base::Contains(disabled_providers, entry.provider))
+ continue;
+
+ if (entry.display_globally ||
+ std::find_if(
+ entry.display_countries.begin(), entry.display_countries.end(),
+ [&country_id](const std::string& country_code) {
+ return country_codes::CountryCharsToCountryID(
+ country_code[0], country_code[1]) == country_id;
+ }) != entry.display_countries.end()) {
+ DCHECK(!entry.ui_name.empty());
+ DCHECK(!entry.privacy_policy.empty());
+ base::Value dict(base::Value::Type::DICTIONARY);
+ dict.SetKey("name", base::Value(entry.ui_name));
+ dict.SetKey("value", base::Value(entry.dns_over_https_template));
+ dict.SetKey("policy", base::Value(entry.privacy_policy));
+ resolvers.Append(std::move(dict));
+ DCHECK(entry.provider_id_for_histogram.has_value());
+ resolver_histogram_map_.insert({entry.dns_over_https_template,
+ entry.provider_id_for_histogram.value()});
+ }
+ }
+
+ // Randomize the order of the resolvers.
+ base::RandomShuffle(resolvers.GetList().begin(), resolvers.GetList().end());
+
+ // Add a custom option to the front of the list
+ base::Value custom(base::Value::Type::DICTIONARY);
+ custom.SetKey("name",
+ base::Value(l10n_util::GetStringUTF8(IDS_SETTINGS_CUSTOM)));
+ custom.SetKey("value", base::Value("custom"));
+ custom.SetKey("policy", base::Value(std::string()));
+ resolvers.Insert(resolvers.GetList().begin(), std::move(custom));
+ resolver_histogram_map_.insert(
+ {"custom", net::DohProviderIdForHistogram::kCustom});
+
+ return resolvers;
+}
+
+void SecureDnsHandler::SetNetworkContextForTesting(
+ network::mojom::NetworkContext* network_context) {
+ network_context_for_testing_ = network_context;
+}
+
+void SecureDnsHandler::HandleGetSecureDnsResolverList(
+ const base::ListValue* args) {
+ AllowJavascript();
+ std::string callback_id = args->GetList()[0].GetString();
+
+ ResolveJavascriptCallback(
+ base::Value(callback_id),
+ GetSecureDnsResolverListForCountry(country_codes::GetCurrentCountryID(),
+ net::GetDohProviderList()));
+}
+
+void SecureDnsHandler::HandleGetSecureDnsSetting(const base::ListValue* args) {
+ AllowJavascript();
+ CHECK_EQ(1u, args->GetList().size());
+ const base::Value& callback_id = args->GetList()[0];
+ ResolveJavascriptCallback(callback_id, *CreateSecureDnsSettingDict());
+}
+
+void SecureDnsHandler::HandleValidateCustomDnsEntry(
+ const base::ListValue* args) {
+ AllowJavascript();
+ const base::Value* callback_id;
+ std::string custom_entry;
+ CHECK(args->Get(0, &callback_id));
+ CHECK(args->GetString(1, &custom_entry));
+
+ // Return the first template, or none if the entry is invalid.
+ std::string first_template;
+ bool valid = !custom_entry.empty() &&
+ chrome_browser_net::IsValidDohTemplateGroup(custom_entry);
+ if (valid) {
+ first_template =
+ std::string(chrome_browser_net::SplitDohTemplateGroup(custom_entry)[0]);
+ }
+ UMA_HISTOGRAM_BOOLEAN("Net.DNS.UI.ValidationAttemptSuccess", valid);
+ ResolveJavascriptCallback(*callback_id, base::Value(first_template));
+}
+
+void SecureDnsHandler::HandleProbeCustomDnsTemplate(
+ const base::ListValue* args) {
+ AllowJavascript();
+ receiver_.reset();
+ host_resolver_.reset();
+
+ std::string server_template;
+ CHECK(args->GetString(0, &probe_callback_id_));
+ CHECK(args->GetString(1, &server_template));
+
+ net::DnsConfigOverrides overrides;
+ overrides.search = std::vector<std::string>();
+ overrides.attempts = 1;
+ overrides.randomize_ports = false;
+ overrides.secure_dns_mode = net::DnsConfig::SecureDnsMode::SECURE;
+ std::string server_method;
+ // We only send probe queries to templates that have already passed a format
+ // validation check.
+ CHECK(net::dns_util::IsValidDohTemplate(server_template, &server_method));
+ overrides.dns_over_https_servers.emplace({net::DnsOverHttpsServerConfig(
+ server_template, server_method == "POST")});
+ auto* network_context =
+ network_context_for_testing_
+ ? network_context_for_testing_
+ : content::BrowserContext::GetDefaultStoragePartition(
+ web_ui()->GetWebContents()->GetBrowserContext())
+ ->GetNetworkContext();
+ network_context->CreateHostResolver(
+ overrides, host_resolver_.BindNewPipeAndPassReceiver());
+
+ network::mojom::ResolveHostParametersPtr parameters =
+ network::mojom::ResolveHostParameters::New();
+ parameters->dns_query_type = net::DnsQueryType::A;
+ parameters->source = net::HostResolverSource::DNS;
+ parameters->cache_usage =
+ network::mojom::ResolveHostParameters::CacheUsage::DISALLOWED;
+ host_resolver_->ResolveHost(net::HostPortPair(kProbeHostname, 80),
+ net::NetworkIsolationKey::CreateTransient(),
+ std::move(parameters),
+ receiver_.BindNewPipeAndPassRemote());
+ receiver_.set_disconnect_handler(base::BindOnce(
+ &SecureDnsHandler::OnMojoConnectionError, base::Unretained(this)));
+}
+
+void SecureDnsHandler::HandleRecordUserDropdownInteraction(
+ const base::ListValue* args) {
+ CHECK_EQ(2U, args->GetSize());
+ std::string old_provider;
+ std::string new_provider;
+ CHECK(args->GetString(0, &old_provider));
+ CHECK(args->GetString(1, &new_provider));
+ DCHECK(resolver_histogram_map_.find(old_provider) !=
+ resolver_histogram_map_.end());
+ DCHECK(resolver_histogram_map_.find(new_provider) !=
+ resolver_histogram_map_.end());
+ for (auto& pair : resolver_histogram_map_) {
+ if (pair.first == old_provider) {
+ UMA_HISTOGRAM_ENUMERATION("Net.DNS.UI.DropdownSelectionEvent.Unselected",
+ pair.second);
+ } else if (pair.first == new_provider) {
+ UMA_HISTOGRAM_ENUMERATION("Net.DNS.UI.DropdownSelectionEvent.Selected",
+ pair.second);
+ } else {
+ UMA_HISTOGRAM_ENUMERATION("Net.DNS.UI.DropdownSelectionEvent.Ignored",
+ pair.second);
+ }
+ }
+}
+
+// network::ResolveHostClientBase impl:
+void SecureDnsHandler::OnComplete(
+ int result,
+ const net::ResolveErrorInfo& resolve_error_info,
+ const base::Optional<net::AddressList>& resolved_addresses) {
+ receiver_.reset();
+ host_resolver_.reset();
+ UMA_HISTOGRAM_BOOLEAN("Net.DNS.UI.ProbeAttemptSuccess", (result == 0));
+ ResolveJavascriptCallback(base::Value(probe_callback_id_),
+ base::Value(result == 0));
+}
+
+void SecureDnsHandler::OnMojoConnectionError() {
+ OnComplete(net::ERR_NAME_NOT_RESOLVED, net::ResolveErrorInfo(net::ERR_FAILED),
+ base::nullopt);
+}
+
+void SecureDnsHandler::SendSecureDnsSettingUpdatesToJavascript() {
+ FireWebUIListener("secure-dns-setting-changed",
+ *CreateSecureDnsSettingDict());
+}
+
+} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler.h b/chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler.h
new file mode 100644
index 00000000000..ed68ee5b664
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler.h
@@ -0,0 +1,89 @@
+// Copyright 2020 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 CHROME_BROWSER_UI_WEBUI_SETTINGS_SETTINGS_SECURE_DNS_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_SETTINGS_SECURE_DNS_HANDLER_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/values.h"
+#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+#include "components/prefs/pref_change_registrar.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "net/dns/public/doh_provider_list.h"
+#include "services/network/public/cpp/resolve_host_client_base.h"
+#include "services/network/public/mojom/host_resolver.mojom.h"
+#include "services/network/public/mojom/network_context.mojom.h"
+
+namespace settings {
+
+// Handler for the Secure DNS setting.
+class SecureDnsHandler : public SettingsPageUIHandler,
+ network::ResolveHostClientBase {
+ public:
+ SecureDnsHandler();
+ ~SecureDnsHandler() override;
+
+ // SettingsPageUIHandler:
+ void RegisterMessages() override;
+ void OnJavascriptAllowed() override;
+ void OnJavascriptDisallowed() override;
+
+ // Get the list of dropdown resolver options. Each option is represented
+ // as a dictionary with the following keys: "name" (the text to display in the
+ // UI), "value" (the DoH template for this provider), and "policy" (the URL of
+ // the provider's privacy policy).
+ base::Value GetSecureDnsResolverListForCountry(
+ int country_id,
+ const std::vector<net::DohProviderEntry>& providers);
+
+ void SetNetworkContextForTesting(
+ network::mojom::NetworkContext* network_context);
+
+ protected:
+ // Retrieves all pre-approved secure resolvers and returns them to WebUI.
+ void HandleGetSecureDnsResolverList(const base::ListValue* args);
+
+ // Intended to be called once upon creation of the secure DNS setting.
+ void HandleGetSecureDnsSetting(const base::ListValue* args);
+
+ // Returns the first template if a custom entry is valid.
+ void HandleValidateCustomDnsEntry(const base::ListValue* args);
+
+ // Returns whether or not a test query to the resolver succeeds.
+ void HandleProbeCustomDnsTemplate(const base::ListValue* args);
+
+ // Records metrics on the user-initiated dropdown selection event.
+ void HandleRecordUserDropdownInteraction(const base::ListValue* args);
+
+ // Retrieves the current host resolver configuration, computes the
+ // corresponding UI representation, and sends it to javascript.
+ void SendSecureDnsSettingUpdatesToJavascript();
+
+ private:
+ // network::ResolveHostClientBase impl:
+ void OnComplete(
+ int result,
+ const net::ResolveErrorInfo& resolve_error_info,
+ const base::Optional<net::AddressList>& resolved_addresses) override;
+
+ void OnMojoConnectionError();
+
+ std::map<std::string, net::DohProviderIdForHistogram> resolver_histogram_map_;
+ network::mojom::NetworkContext* network_context_for_testing_ = nullptr;
+ mojo::Receiver<network::mojom::ResolveHostClient> receiver_{this};
+ mojo::Remote<network::mojom::HostResolver> host_resolver_;
+ std::string probe_callback_id_;
+ PrefChangeRegistrar pref_registrar_;
+
+ DISALLOW_COPY_AND_ASSIGN(SecureDnsHandler);
+};
+
+} // namespace settings
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_SETTINGS_SECURE_DNS_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler_browsertest.cc b/chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler_browsertest.cc
new file mode 100644
index 00000000000..c57dde40d12
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler_browsertest.cc
@@ -0,0 +1,609 @@
+// Copyright 2020 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 "chrome/browser/ui/webui/settings/settings_secure_dns_handler.h"
+
+#include "base/test/metrics/histogram_tester.h"
+#include "build/build_config.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/net/dns_probe_test_util.h"
+#include "chrome/browser/net/dns_util.h"
+#include "chrome/common/chrome_features.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "components/country_codes/country_codes.h"
+#include "components/policy/core/browser/browser_policy_connector.h"
+#include "components/policy/core/common/mock_configuration_policy_provider.h"
+#include "components/policy/policy_constants.h"
+#include "components/prefs/pref_service.h"
+#include "content/public/test/test_web_ui.h"
+#include "net/dns/public/resolve_error_info.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+#if defined(OS_WIN)
+#include "base/win/win_util.h"
+#endif
+
+using net::DohProviderEntry;
+using testing::_;
+using testing::Return;
+
+namespace settings {
+
+namespace {
+
+constexpr char kGetSecureDnsResolverList[] = "getSecureDnsResolverList";
+constexpr char kValidateCustomDnsEntry[] = "validateCustomDnsEntry";
+constexpr char kProbeCustomDnsTemplate[] = "probeCustomDnsTemplate";
+constexpr char kRecordUserDropdownInteraction[] =
+ "recordUserDropdownInteraction";
+constexpr char kWebUiFunctionName[] = "webUiCallbackName";
+
+const std::vector<DohProviderEntry>& GetDohProviderListForTesting() {
+ static const base::NoDestructor<std::vector<DohProviderEntry>> test_providers{
+ {
+ DohProviderEntry(
+ "Provider_Global1", net::DohProviderIdForHistogram(-1),
+ {} /*ip_strs */, {} /* dot_hostnames */,
+ "https://global1.provider/dns-query{?dns}",
+ "Global Provider 1" /* ui_name */,
+ "https://global1.provider/privacy_policy/" /* privacy_policy */,
+ true /* display_globally */, {} /* display_countries */),
+ DohProviderEntry(
+ "Provider_NoDisplay", net::DohProviderIdForHistogram(-2),
+ {} /*ip_strs */, {} /* dot_hostnames */,
+ "https://nodisplay.provider/dns-query{?dns}",
+ "No Display Provider" /* ui_name */,
+ "https://nodisplay.provider/privacy_policy/" /* privacy_policy */,
+ false /* display_globally */, {} /* display_countries */),
+ DohProviderEntry(
+ "Provider_EE_FR", net::DohProviderIdForHistogram(-3),
+ {} /*ip_strs */, {} /* dot_hostnames */,
+ "https://ee.fr.provider/dns-query{?dns}",
+ "EE/FR Provider" /* ui_name */,
+ "https://ee.fr.provider/privacy_policy/" /* privacy_policy */,
+ false /* display_globally */,
+ {"EE", "FR"} /* display_countries */),
+ DohProviderEntry(
+ "Provider_FR", net::DohProviderIdForHistogram(-4),
+ {} /*ip_strs */, {} /* dot_hostnames */,
+ "https://fr.provider/dns-query{?dns}",
+ "FR Provider" /* ui_name */,
+ "https://fr.provider/privacy_policy/" /* privacy_policy */,
+ false /* display_globally */, {"FR"} /* display_countries */),
+ DohProviderEntry(
+ "Provider_Global2", net::DohProviderIdForHistogram(-5),
+ {} /*ip_strs */, {} /* dot_hostnames */,
+ "https://global2.provider/dns-query{?dns}",
+ "Global Provider 2" /* ui_name */,
+ "https://global2.provider/privacy_policy/" /* privacy_policy */,
+ true /* display_globally */, {} /* display_countries */),
+ }};
+ return *test_providers;
+}
+
+bool FindDropdownItem(const base::Value& resolvers,
+ const std::string& name,
+ const std::string& value,
+ const std::string& policy) {
+ base::Value dict(base::Value::Type::DICTIONARY);
+ dict.SetKey("name", base::Value(name));
+ dict.SetKey("value", base::Value(value));
+ dict.SetKey("policy", base::Value(policy));
+
+ return std::find(resolvers.GetList().begin(), resolvers.GetList().end(),
+ dict) != resolvers.GetList().end();
+}
+
+} // namespace
+
+class TestSecureDnsHandler : public SecureDnsHandler {
+ public:
+ // Pull WebUIMessageHandler::set_web_ui() into public so tests can call it.
+ using SecureDnsHandler::set_web_ui;
+};
+
+class SecureDnsHandlerTest : public InProcessBrowserTest {
+ protected:
+#if defined(OS_WIN)
+ SecureDnsHandlerTest()
+ // Mark as not enterprise managed to prevent the secure DNS mode from
+ // being downgraded to off.
+ : scoped_domain_(false) {}
+#else
+ SecureDnsHandlerTest() = default;
+#endif
+ ~SecureDnsHandlerTest() override = default;
+
+ // InProcessBrowserTest:
+ void SetUpInProcessBrowserTestFixture() override {
+ // Initialize user policy.
+ ON_CALL(provider_, IsInitializationComplete(_)).WillByDefault(Return(true));
+ policy::BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_);
+ }
+
+ void SetUpOnMainThread() override {
+ handler_ = std::make_unique<TestSecureDnsHandler>();
+ handler_->set_web_ui(&web_ui_);
+ handler_->RegisterMessages();
+ handler_->AllowJavascriptForTesting();
+ base::RunLoop().RunUntilIdle();
+ }
+
+ void TearDownOnMainThread() override { handler_.reset(); }
+
+ // Updates out-params from the last message sent to WebUI about a secure DNS
+ // change. Returns false if the message was invalid or not found.
+ bool GetLastSettingsChangedMessage(
+ std::string* secure_dns_mode,
+ std::vector<std::string>* secure_dns_templates,
+ int* management_mode) {
+ for (auto it = web_ui_.call_data().rbegin();
+ it != web_ui_.call_data().rend(); ++it) {
+ const content::TestWebUI::CallData* data = it->get();
+ if (data->function_name() != "cr.webUIListenerCallback" ||
+ !data->arg1()->is_string() ||
+ data->arg1()->GetString() != "secure-dns-setting-changed") {
+ continue;
+ }
+
+ const base::DictionaryValue* dict = nullptr;
+ if (!data->arg2()->GetAsDictionary(&dict))
+ return false;
+
+ // Get the secure DNS mode.
+ if (!dict->FindStringPath("mode"))
+ return false;
+ *secure_dns_mode = *dict->FindStringPath("mode");
+
+ // Get the secure DNS templates.
+ if (!dict->FindListPath("templates"))
+ return false;
+ secure_dns_templates->clear();
+ for (const auto& template_str :
+ dict->FindListPath("templates")->GetList()) {
+ if (!template_str.is_string())
+ return false;
+ secure_dns_templates->push_back(template_str.GetString());
+ }
+
+ // Get the forced management description.
+ if (!dict->FindIntPath("managementMode"))
+ return false;
+ *management_mode = *dict->FindIntPath("managementMode");
+
+ return true;
+ }
+ return false;
+ }
+
+ // Sets a policy update which will cause power pref managed change.
+ void SetPolicyForPolicyKey(policy::PolicyMap* policy_map,
+ const std::string& policy_key,
+ std::unique_ptr<base::Value> value) {
+ policy_map->Set(policy_key, policy::POLICY_LEVEL_MANDATORY,
+ policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
+ std::move(value), nullptr);
+ provider_.UpdateChromePolicy(*policy_map);
+ base::RunLoop().RunUntilIdle();
+ }
+
+ std::unique_ptr<TestSecureDnsHandler> handler_;
+ content::TestWebUI web_ui_;
+ policy::MockConfigurationPolicyProvider provider_;
+
+ private:
+#if defined(OS_WIN)
+ base::win::ScopedDomainStateForTesting scoped_domain_;
+#endif
+
+ DISALLOW_COPY_AND_ASSIGN(SecureDnsHandlerTest);
+};
+
+IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, SecureDnsModes) {
+ PrefService* local_state = g_browser_process->local_state();
+ std::string secure_dns_mode;
+ std::vector<std::string> secure_dns_templates;
+ int management_mode;
+
+ local_state->SetString(prefs::kDnsOverHttpsMode,
+ chrome_browser_net::kDnsOverHttpsModeOff);
+ EXPECT_TRUE(GetLastSettingsChangedMessage(
+ &secure_dns_mode, &secure_dns_templates, &management_mode));
+ EXPECT_EQ(chrome_browser_net::kDnsOverHttpsModeOff, secure_dns_mode);
+
+ local_state->SetString(prefs::kDnsOverHttpsMode,
+ chrome_browser_net::kDnsOverHttpsModeAutomatic);
+ EXPECT_TRUE(GetLastSettingsChangedMessage(
+ &secure_dns_mode, &secure_dns_templates, &management_mode));
+ EXPECT_EQ(chrome_browser_net::kDnsOverHttpsModeAutomatic, secure_dns_mode);
+
+ local_state->SetString(prefs::kDnsOverHttpsMode,
+ chrome_browser_net::kDnsOverHttpsModeSecure);
+ EXPECT_TRUE(GetLastSettingsChangedMessage(
+ &secure_dns_mode, &secure_dns_templates, &management_mode));
+ EXPECT_EQ(chrome_browser_net::kDnsOverHttpsModeSecure, secure_dns_mode);
+
+ local_state->SetString(prefs::kDnsOverHttpsMode, "unknown");
+ EXPECT_TRUE(GetLastSettingsChangedMessage(
+ &secure_dns_mode, &secure_dns_templates, &management_mode));
+ EXPECT_EQ(chrome_browser_net::kDnsOverHttpsModeOff, secure_dns_mode);
+}
+
+IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, SecureDnsPolicy) {
+ policy::PolicyMap policy_map;
+ SetPolicyForPolicyKey(&policy_map, policy::key::kDnsOverHttpsMode,
+ std::make_unique<base::Value>(
+ chrome_browser_net::kDnsOverHttpsModeAutomatic));
+
+ PrefService* local_state = g_browser_process->local_state();
+ local_state->SetString(prefs::kDnsOverHttpsMode,
+ chrome_browser_net::kDnsOverHttpsModeSecure);
+
+ std::string secure_dns_mode;
+ std::vector<std::string> secure_dns_templates;
+ int management_mode;
+ EXPECT_TRUE(GetLastSettingsChangedMessage(
+ &secure_dns_mode, &secure_dns_templates, &management_mode));
+ EXPECT_EQ(chrome_browser_net::kDnsOverHttpsModeAutomatic, secure_dns_mode);
+ EXPECT_EQ(static_cast<int>(
+ chrome_browser_net::SecureDnsUiManagementMode::kNoOverride),
+ management_mode);
+}
+
+IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, SecureDnsPolicyChange) {
+ policy::PolicyMap policy_map;
+ SetPolicyForPolicyKey(&policy_map, policy::key::kDnsOverHttpsMode,
+ std::make_unique<base::Value>(
+ chrome_browser_net::kDnsOverHttpsModeAutomatic));
+
+ std::string secure_dns_mode;
+ std::vector<std::string> secure_dns_templates;
+ int management_mode;
+ EXPECT_TRUE(GetLastSettingsChangedMessage(
+ &secure_dns_mode, &secure_dns_templates, &management_mode));
+ EXPECT_EQ(chrome_browser_net::kDnsOverHttpsModeAutomatic, secure_dns_mode);
+ EXPECT_EQ(static_cast<int>(
+ chrome_browser_net::SecureDnsUiManagementMode::kNoOverride),
+ management_mode);
+
+ SetPolicyForPolicyKey(
+ &policy_map, policy::key::kDnsOverHttpsMode,
+ std::make_unique<base::Value>(chrome_browser_net::kDnsOverHttpsModeOff));
+ EXPECT_TRUE(GetLastSettingsChangedMessage(
+ &secure_dns_mode, &secure_dns_templates, &management_mode));
+ EXPECT_EQ(chrome_browser_net::kDnsOverHttpsModeOff, secure_dns_mode);
+ EXPECT_EQ(static_cast<int>(
+ chrome_browser_net::SecureDnsUiManagementMode::kNoOverride),
+ management_mode);
+}
+
+// On platforms where enterprise policies do not have default values, test
+// that DoH is disabled when non-DoH policies are set.
+#if !defined(OS_CHROMEOS)
+IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, OtherPoliciesSet) {
+ policy::PolicyMap policy_map;
+ SetPolicyForPolicyKey(&policy_map, policy::key::kIncognitoModeAvailability,
+ std::make_unique<base::Value>(1));
+
+ PrefService* local_state = g_browser_process->local_state();
+ local_state->SetString(prefs::kDnsOverHttpsMode,
+ chrome_browser_net::kDnsOverHttpsModeSecure);
+
+ std::string secure_dns_mode;
+ std::vector<std::string> secure_dns_templates;
+ int management_mode;
+ EXPECT_TRUE(GetLastSettingsChangedMessage(
+ &secure_dns_mode, &secure_dns_templates, &management_mode));
+ EXPECT_EQ(chrome_browser_net::kDnsOverHttpsModeOff, secure_dns_mode);
+ EXPECT_EQ(
+ static_cast<int>(
+ chrome_browser_net::SecureDnsUiManagementMode::kDisabledManaged),
+ management_mode);
+}
+#endif
+
+// This test makes no assumptions about the country or underlying resolver list.
+IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, DropdownList) {
+ base::ListValue args;
+ args.AppendString(kWebUiFunctionName);
+
+ web_ui_.HandleReceivedMessage(kGetSecureDnsResolverList, &args);
+ const content::TestWebUI::CallData& call_data = *web_ui_.call_data().back();
+ EXPECT_EQ("cr.webUIResponse", call_data.function_name());
+ EXPECT_EQ(kWebUiFunctionName, call_data.arg1()->GetString());
+ ASSERT_TRUE(call_data.arg2()->GetBool());
+
+ // Check results.
+ base::Value::ConstListView resolver_list = call_data.arg3()->GetList();
+ ASSERT_GE(resolver_list.size(), 1U);
+ EXPECT_EQ("custom", resolver_list[0].FindKey("value")->GetString());
+}
+
+IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, DropdownListForCountry) {
+ // The 'EE' list should start with the custom entry, followed by the two
+ // global providers and the 'EE' provider in some random order.
+ base::Value resolver_list = handler_->GetSecureDnsResolverListForCountry(
+ country_codes::CountryCharsToCountryID('E', 'E'),
+ GetDohProviderListForTesting());
+ EXPECT_EQ(4u, resolver_list.GetList().size());
+ EXPECT_EQ("custom", resolver_list.GetList()[0].FindKey("value")->GetString());
+ EXPECT_TRUE(FindDropdownItem(resolver_list, "Global Provider 1",
+ "https://global1.provider/dns-query{?dns}",
+ "https://global1.provider/privacy_policy/"));
+ EXPECT_TRUE(FindDropdownItem(resolver_list, "Global Provider 2",
+ "https://global2.provider/dns-query{?dns}",
+ "https://global2.provider/privacy_policy/"));
+ EXPECT_TRUE(FindDropdownItem(resolver_list, "EE/FR Provider",
+ "https://ee.fr.provider/dns-query{?dns}",
+ "https://ee.fr.provider/privacy_policy/"));
+
+ // The 'FR' list should start with the custom entry, followed by the two
+ // global providers and the two 'FR' providers in some random order.
+ resolver_list = handler_->GetSecureDnsResolverListForCountry(
+ country_codes::CountryCharsToCountryID('F', 'R'),
+ GetDohProviderListForTesting());
+ EXPECT_EQ(5u, resolver_list.GetList().size());
+ EXPECT_EQ("custom", resolver_list.GetList()[0].FindKey("value")->GetString());
+ EXPECT_TRUE(FindDropdownItem(resolver_list, "Global Provider 1",
+ "https://global1.provider/dns-query{?dns}",
+ "https://global1.provider/privacy_policy/"));
+ EXPECT_TRUE(FindDropdownItem(resolver_list, "Global Provider 2",
+ "https://global2.provider/dns-query{?dns}",
+ "https://global2.provider/privacy_policy/"));
+ EXPECT_TRUE(FindDropdownItem(resolver_list, "EE/FR Provider",
+ "https://ee.fr.provider/dns-query{?dns}",
+ "https://ee.fr.provider/privacy_policy/"));
+ EXPECT_TRUE(FindDropdownItem(resolver_list, "FR Provider",
+ "https://fr.provider/dns-query{?dns}",
+ "https://fr.provider/privacy_policy/"));
+
+ // The 'CA' list should start with the custom entry, followed by the two
+ // global providers.
+ resolver_list = handler_->GetSecureDnsResolverListForCountry(
+ country_codes::CountryCharsToCountryID('C', 'A'),
+ GetDohProviderListForTesting());
+ EXPECT_EQ(3u, resolver_list.GetList().size());
+ EXPECT_EQ("custom", resolver_list.GetList()[0].FindKey("value")->GetString());
+ EXPECT_TRUE(FindDropdownItem(resolver_list, "Global Provider 1",
+ "https://global1.provider/dns-query{?dns}",
+ "https://global1.provider/privacy_policy/"));
+ EXPECT_TRUE(FindDropdownItem(resolver_list, "Global Provider 2",
+ "https://global2.provider/dns-query{?dns}",
+ "https://global2.provider/privacy_policy/"));
+}
+
+IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, DropdownListChange) {
+ // Populate the map for recording dropdown change metrics.
+ base::Value resolver_list = handler_->GetSecureDnsResolverListForCountry(
+ country_codes::CountryCharsToCountryID('E', 'E'),
+ GetDohProviderListForTesting());
+ EXPECT_EQ(4u, resolver_list.GetList().size());
+
+ base::HistogramTester histograms;
+ base::ListValue args;
+ args.AppendString("custom" /* old_provider */);
+ args.AppendString(
+ "https://global1.provider/dns-query{?dns}" /* new_provider */);
+ web_ui_.HandleReceivedMessage(kRecordUserDropdownInteraction, &args);
+
+ const std::string uma_base("Net.DNS.UI.DropdownSelectionEvent");
+ histograms.ExpectTotalCount(uma_base + ".Ignored", 2u);
+ histograms.ExpectTotalCount(uma_base + ".Selected", 1u);
+ histograms.ExpectTotalCount(uma_base + ".Unselected", 1u);
+}
+
+class SecureDnsHandlerTestWithDisabledProviders : public SecureDnsHandlerTest {
+ protected:
+ SecureDnsHandlerTestWithDisabledProviders() {
+ scoped_features_.InitAndEnableFeatureWithParameters(
+ features::kDnsOverHttps,
+ {{"DisabledProviders",
+ "Provider_Global2, , Provider_EE_FR,Unexpected"}});
+ }
+
+ private:
+ base::test::ScopedFeatureList scoped_features_;
+
+ DISALLOW_COPY_AND_ASSIGN(SecureDnsHandlerTestWithDisabledProviders);
+};
+
+IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTestWithDisabledProviders,
+ DropdownListDisabledProviders) {
+ // The 'FR' list should start with the custom entry, followed by the two
+ // global providers and the two 'FR' providers in some random order.
+ base::Value resolver_list = handler_->GetSecureDnsResolverListForCountry(
+ country_codes::CountryCharsToCountryID('F', 'R'),
+ GetDohProviderListForTesting());
+ EXPECT_EQ(3u, resolver_list.GetList().size());
+ EXPECT_EQ("custom", resolver_list.GetList()[0].FindKey("value")->GetString());
+ EXPECT_TRUE(FindDropdownItem(resolver_list, "Global Provider 1",
+ "https://global1.provider/dns-query{?dns}",
+ "https://global1.provider/privacy_policy/"));
+ EXPECT_TRUE(FindDropdownItem(resolver_list, "FR Provider",
+ "https://fr.provider/dns-query{?dns}",
+ "https://fr.provider/privacy_policy/"));
+}
+
+IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTestWithDisabledProviders,
+ SecureDnsTemplates) {
+ std::string good_post_template = "https://foo.test/";
+ std::string good_get_template = "https://bar.test/dns-query{?dns}";
+ std::string bad_template = "dns-query{?dns}";
+
+ std::string secure_dns_mode;
+ std::vector<std::string> secure_dns_templates;
+ int management_mode;
+ PrefService* local_state = g_browser_process->local_state();
+ local_state->SetString(prefs::kDnsOverHttpsTemplates, good_post_template);
+ EXPECT_TRUE(GetLastSettingsChangedMessage(
+ &secure_dns_mode, &secure_dns_templates, &management_mode));
+ EXPECT_EQ(1u, secure_dns_templates.size());
+ EXPECT_EQ(good_post_template, secure_dns_templates[0]);
+
+ local_state->SetString(prefs::kDnsOverHttpsTemplates,
+ good_post_template + " " + good_get_template);
+ EXPECT_TRUE(GetLastSettingsChangedMessage(
+ &secure_dns_mode, &secure_dns_templates, &management_mode));
+ EXPECT_EQ(2u, secure_dns_templates.size());
+ EXPECT_EQ(good_post_template, secure_dns_templates[0]);
+ EXPECT_EQ(good_get_template, secure_dns_templates[1]);
+
+ local_state->SetString(prefs::kDnsOverHttpsTemplates, bad_template);
+ EXPECT_TRUE(GetLastSettingsChangedMessage(
+ &secure_dns_mode, &secure_dns_templates, &management_mode));
+ EXPECT_EQ(0u, secure_dns_templates.size());
+
+ local_state->SetString(prefs::kDnsOverHttpsTemplates,
+ bad_template + " " + good_post_template);
+ EXPECT_TRUE(GetLastSettingsChangedMessage(
+ &secure_dns_mode, &secure_dns_templates, &management_mode));
+ EXPECT_EQ(1u, secure_dns_templates.size());
+ EXPECT_EQ(good_post_template, secure_dns_templates[0]);
+
+ // Should still return a provider that was disabled.
+ local_state->SetString(prefs::kDnsOverHttpsTemplates,
+ "https://global2.provider/dns-query{?dns}");
+ EXPECT_TRUE(GetLastSettingsChangedMessage(
+ &secure_dns_mode, &secure_dns_templates, &management_mode));
+ EXPECT_EQ(1u, secure_dns_templates.size());
+ EXPECT_EQ("https://global2.provider/dns-query{?dns}",
+ secure_dns_templates[0]);
+}
+
+IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, TemplateValid) {
+ base::ListValue args;
+ args.AppendString(kWebUiFunctionName);
+ args.AppendString("https://example.template/dns-query");
+
+ base::HistogramTester histograms;
+ web_ui_.HandleReceivedMessage(kValidateCustomDnsEntry, &args);
+ const content::TestWebUI::CallData& call_data = *web_ui_.call_data().back();
+ EXPECT_EQ("cr.webUIResponse", call_data.function_name());
+ EXPECT_EQ(kWebUiFunctionName, call_data.arg1()->GetString());
+ // The request should be successful.
+ ASSERT_TRUE(call_data.arg2()->GetBool());
+ // The template should be valid.
+ ASSERT_EQ("https://example.template/dns-query",
+ call_data.arg3()->GetString());
+ histograms.ExpectBucketCount("Net.DNS.UI.ValidationAttemptSuccess", false, 0);
+ histograms.ExpectBucketCount("Net.DNS.UI.ValidationAttemptSuccess", true, 1);
+}
+
+IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, TemplateInvalid) {
+ base::ListValue args;
+ args.AppendString(kWebUiFunctionName);
+ args.AppendString("invalid_template");
+
+ base::HistogramTester histograms;
+ web_ui_.HandleReceivedMessage(kValidateCustomDnsEntry, &args);
+ const content::TestWebUI::CallData& call_data = *web_ui_.call_data().back();
+ EXPECT_EQ("cr.webUIResponse", call_data.function_name());
+ EXPECT_EQ(kWebUiFunctionName, call_data.arg1()->GetString());
+ // The request should be successful.
+ ASSERT_TRUE(call_data.arg2()->GetBool());
+ // The template should be invalid.
+ ASSERT_EQ(std::string(), call_data.arg3()->GetString());
+ histograms.ExpectBucketCount("Net.DNS.UI.ValidationAttemptSuccess", false, 1);
+ histograms.ExpectBucketCount("Net.DNS.UI.ValidationAttemptSuccess", true, 0);
+}
+
+IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, MultipleTemplates) {
+ base::HistogramTester histograms;
+ base::ListValue args_valid;
+ args_valid.AppendString(kWebUiFunctionName);
+ args_valid.AppendString(
+ "https://example1.template/dns https://example2.template/dns-query");
+ web_ui_.HandleReceivedMessage(kValidateCustomDnsEntry, &args_valid);
+ const content::TestWebUI::CallData& call_data_valid =
+ *web_ui_.call_data().back();
+ EXPECT_EQ("cr.webUIResponse", call_data_valid.function_name());
+ EXPECT_EQ(kWebUiFunctionName, call_data_valid.arg1()->GetString());
+ // The request should be successful.
+ ASSERT_TRUE(call_data_valid.arg2()->GetBool());
+ // Both templates are valid, so validate returns the first.
+ ASSERT_EQ("https://example1.template/dns",
+ call_data_valid.arg3()->GetString());
+ histograms.ExpectBucketCount("Net.DNS.UI.ValidationAttemptSuccess", false, 0);
+ histograms.ExpectBucketCount("Net.DNS.UI.ValidationAttemptSuccess", true, 1);
+
+ base::ListValue args_invalid;
+ args_invalid.AppendString(kWebUiFunctionName);
+ args_invalid.AppendString("invalid_template https://example.template/dns");
+ web_ui_.HandleReceivedMessage(kValidateCustomDnsEntry, &args_invalid);
+ const content::TestWebUI::CallData& call_data_invalid =
+ *web_ui_.call_data().back();
+ EXPECT_EQ("cr.webUIResponse", call_data_invalid.function_name());
+ EXPECT_EQ(kWebUiFunctionName, call_data_invalid.arg1()->GetString());
+ // The request should be successful.
+ ASSERT_TRUE(call_data_invalid.arg2()->GetBool());
+ // The entry should be invalid.
+ ASSERT_EQ(std::string(), call_data_invalid.arg3()->GetString());
+ histograms.ExpectBucketCount("Net.DNS.UI.ValidationAttemptSuccess", false, 1);
+ histograms.ExpectBucketCount("Net.DNS.UI.ValidationAttemptSuccess", true, 1);
+}
+
+IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, TemplateProbeSuccess) {
+ auto network_context_ =
+ std::make_unique<chrome_browser_net::FakeHostResolverNetworkContext>(
+ std::vector<chrome_browser_net::FakeHostResolver::SingleResult>(
+ {chrome_browser_net::FakeHostResolver::SingleResult(
+ net::OK, net::ResolveErrorInfo(net::OK),
+ chrome_browser_net::FakeHostResolver::
+ kOneAddressResponse)}) /* current_config_result_list */,
+ std::vector<chrome_browser_net::FakeHostResolver::
+ SingleResult>() /* google_config_result_list */);
+ handler_->SetNetworkContextForTesting(network_context_.get());
+ base::HistogramTester histograms;
+ base::ListValue args_valid;
+ args_valid.AppendString(kWebUiFunctionName);
+ args_valid.AppendString("https://example.template/dns-query");
+ web_ui_.HandleReceivedMessage(kProbeCustomDnsTemplate, &args_valid);
+ base::RunLoop().RunUntilIdle();
+
+ const content::TestWebUI::CallData& call_data_valid =
+ *web_ui_.call_data().back();
+ EXPECT_EQ("cr.webUIResponse", call_data_valid.function_name());
+ EXPECT_EQ(kWebUiFunctionName, call_data_valid.arg1()->GetString());
+ // The request should be successful.
+ ASSERT_TRUE(call_data_valid.arg2()->GetBool());
+ // The probe query should have succeeded.
+ ASSERT_TRUE(call_data_valid.arg3()->GetBool());
+ histograms.ExpectBucketCount("Net.DNS.UI.ProbeAttemptSuccess", false, 0);
+ histograms.ExpectBucketCount("Net.DNS.UI.ProbeAttemptSuccess", true, 1);
+}
+
+IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, TemplateProbeFailure) {
+ auto network_context_ =
+ std::make_unique<chrome_browser_net::FakeHostResolverNetworkContext>(
+ std::vector<chrome_browser_net::FakeHostResolver::SingleResult>(
+ {chrome_browser_net::FakeHostResolver::SingleResult(
+ net::ERR_NAME_NOT_RESOLVED,
+ net::ResolveErrorInfo(net::ERR_DNS_MALFORMED_RESPONSE),
+ chrome_browser_net::FakeHostResolver::
+ kNoResponse)}) /* current_config_result_list */,
+ std::vector<chrome_browser_net::FakeHostResolver::
+ SingleResult>() /* google_config_result_list */);
+ handler_->SetNetworkContextForTesting(network_context_.get());
+ base::HistogramTester histograms;
+ base::ListValue args_valid;
+ args_valid.AppendString(kWebUiFunctionName);
+ args_valid.AppendString("https://example.template/dns-query");
+ web_ui_.HandleReceivedMessage(kProbeCustomDnsTemplate, &args_valid);
+ base::RunLoop().RunUntilIdle();
+
+ const content::TestWebUI::CallData& call_data_valid =
+ *web_ui_.call_data().back();
+ EXPECT_EQ("cr.webUIResponse", call_data_valid.function_name());
+ EXPECT_EQ(kWebUiFunctionName, call_data_valid.arg1()->GetString());
+ // The request should be successful.
+ ASSERT_TRUE(call_data_valid.arg2()->GetBool());
+ // The probe query should have failed.
+ ASSERT_FALSE(call_data_valid.arg3()->GetBool());
+ histograms.ExpectBucketCount("Net.DNS.UI.ProbeAttemptSuccess", false, 1);
+ histograms.ExpectBucketCount("Net.DNS.UI.ProbeAttemptSuccess", true, 0);
+}
+
+} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/settings_security_key_handler.cc b/chromium/chrome/browser/ui/webui/settings/settings_security_key_handler.cc
index b949500f09a..112a3e1dc4b 100644
--- a/chromium/chrome/browser/ui/webui/settings/settings_security_key_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/settings_security_key_handler.cc
@@ -15,7 +15,6 @@
#include "chrome/browser/ui/webui/settings/settings_security_key_handler.h"
#include "chrome/grit/generated_resources.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/system_connector.h"
#include "content/public/browser/web_ui.h"
#include "content/public/common/service_manager_connection.h"
#include "device/fido/bio/enrollment_handler.h"
@@ -103,7 +102,7 @@ void SecurityKeysPINHandler::HandleStartSetPIN(const base::ListValue* args) {
callback_id_ = args->GetList()[0].GetString();
state_ = State::kStartSetPIN;
set_pin_ = std::make_unique<device::SetPINRequestHandler>(
- content::GetSystemConnector(), supported_transports(),
+ supported_transports(),
base::BindOnce(&SecurityKeysPINHandler::OnGatherPIN,
weak_factory_.GetWeakPtr()),
base::BindRepeating(&SecurityKeysPINHandler::OnSetPINComplete,
@@ -203,7 +202,7 @@ void SecurityKeysResetHandler::HandleReset(const base::ListValue* args) {
state_ = State::kStartReset;
reset_ = std::make_unique<device::ResetRequestHandler>(
- content::GetSystemConnector(), supported_transports(),
+ supported_transports(),
base::BindOnce(&SecurityKeysResetHandler::OnResetSent,
weak_factory_.GetWeakPtr()),
base::BindOnce(&SecurityKeysResetHandler::OnResetFinished,
@@ -334,7 +333,6 @@ void SecurityKeysCredentialHandler::HandleStart(const base::ListValue* args) {
discovery_factory_ = std::make_unique<device::FidoDiscoveryFactory>();
credential_management_ =
std::make_unique<device::CredentialManagementHandler>(
- content::ServiceManagerConnection::GetForProcess()->GetConnector(),
discovery_factory_.get(), supported_transports(),
base::BindOnce(
&SecurityKeysCredentialHandler::OnCredentialManagementReady,
@@ -589,7 +587,6 @@ void SecurityKeysBioEnrollmentHandler::HandleStart(
callback_id_ = args->GetList()[0].GetString();
discovery_factory_ = std::make_unique<device::FidoDiscoveryFactory>();
bio_ = std::make_unique<device::BioEnrollmentHandler>(
- content::ServiceManagerConnection::GetForProcess()->GetConnector(),
supported_transports(),
base::BindOnce(&SecurityKeysBioEnrollmentHandler::OnReady,
weak_factory_.GetWeakPtr()),
diff --git a/chromium/chrome/browser/ui/webui/settings/settings_ui.cc b/chromium/chrome/browser/ui/webui/settings/settings_ui.cc
index 1f4acc97c4d..84d467e2229 100644
--- a/chromium/chrome/browser/ui/webui/settings/settings_ui.cc
+++ b/chromium/chrome/browser/ui/webui/settings/settings_ui.cc
@@ -19,10 +19,14 @@
#include "build/build_config.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/identity_manager_factory.h"
+#include "chrome/browser/ui/hats/hats_service.h"
+#include "chrome/browser/ui/hats/hats_service_factory.h"
#include "chrome/browser/ui/passwords/manage_passwords_view_utils.h"
+#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/webui/favicon_source.h"
#include "chrome/browser/ui/webui/managed_ui_handler.h"
#include "chrome/browser/ui/webui/metrics_handler.h"
+#include "chrome/browser/ui/webui/plural_string_handler.h"
#include "chrome/browser/ui/webui/settings/about_handler.h"
#include "chrome/browser/ui/webui/settings/accessibility_main_handler.h"
#include "chrome/browser/ui/webui/settings/appearance_handler.h"
@@ -31,22 +35,28 @@
#include "chrome/browser/ui/webui/settings/downloads_handler.h"
#include "chrome/browser/ui/webui/settings/extension_control_handler.h"
#include "chrome/browser/ui/webui/settings/font_handler.h"
+#include "chrome/browser/ui/webui/settings/hats_handler.h"
+#include "chrome/browser/ui/webui/settings/import_data_handler.h"
#include "chrome/browser/ui/webui/settings/metrics_reporting_handler.h"
#include "chrome/browser/ui/webui/settings/on_startup_handler.h"
#include "chrome/browser/ui/webui/settings/people_handler.h"
#include "chrome/browser/ui/webui/settings/profile_info_handler.h"
#include "chrome/browser/ui/webui/settings/protocol_handlers_handler.h"
#include "chrome/browser/ui/webui/settings/reset_settings_handler.h"
+#include "chrome/browser/ui/webui/settings/safe_browsing_handler.h"
+#include "chrome/browser/ui/webui/settings/safety_check_handler.h"
#include "chrome/browser/ui/webui/settings/search_engines_handler.h"
#include "chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h"
#include "chrome/browser/ui/webui/settings/settings_cookies_view_handler.h"
-#include "chrome/browser/ui/webui/settings/settings_import_data_handler.h"
#include "chrome/browser/ui/webui/settings/settings_localized_strings_provider.h"
#include "chrome/browser/ui/webui/settings/settings_media_devices_selection_handler.h"
#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+#include "chrome/browser/ui/webui/settings/settings_secure_dns_handler.h"
#include "chrome/browser/ui/webui/settings/settings_security_key_handler.h"
#include "chrome/browser/ui/webui/settings/settings_startup_pages_handler.h"
+#include "chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.h"
#include "chrome/browser/ui/webui/settings/site_settings_handler.h"
+#include "chrome/browser/ui/webui/webui_util.h"
#include "chrome/browser/web_applications/components/app_registrar.h"
#include "chrome/browser/web_applications/web_app_provider.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
@@ -56,14 +66,19 @@
#include "chrome/grit/generated_resources.h"
#include "chrome/grit/settings_resources.h"
#include "chrome/grit/settings_resources_map.h"
+#include "components/content_settings/core/common/features.h"
#include "components/favicon_base/favicon_url_parser.h"
#include "components/password_manager/core/common/password_manager_features.h"
#include "components/pref_registry/pref_registry_syncable.h"
+#include "components/prefs/pref_service.h"
+#include "components/safe_browsing/core/features.h"
+#include "components/signin/public/base/signin_pref_names.h"
#include "content/public/browser/url_data_source.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_data_source.h"
#include "printing/buildflags/buildflags.h"
+#include "ui/resources/grit/webui_resources.h"
#if defined(OS_WIN)
#include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h"
@@ -78,64 +93,28 @@
#if defined(OS_WIN) || defined(OS_CHROMEOS)
#include "chrome/browser/ui/webui/settings/languages_handler.h"
-#include "chrome/browser/ui/webui/settings/tts_handler.h"
#endif // defined(OS_WIN) || defined(OS_CHROMEOS)
#if defined(OS_CHROMEOS)
-#include "ash/public/cpp/network_config_service.h"
-#include "ash/public/cpp/resources/grit/ash_public_unscaled_resources.h"
-#include "ash/public/cpp/stylus_utils.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browser_process_platform_part.h"
#include "chrome/browser/chromeos/account_manager/account_manager_util.h"
#include "chrome/browser/chromeos/android_sms/android_sms_app_manager.h"
#include "chrome/browser/chromeos/android_sms/android_sms_service_factory.h"
-#include "chrome/browser/chromeos/arc/arc_util.h"
-#include "chrome/browser/chromeos/crostini/crostini_features.h"
-#include "chrome/browser/chromeos/login/demo_mode/demo_session.h"
-#include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.h"
#include "chrome/browser/chromeos/multidevice_setup/multidevice_setup_client_factory.h"
-#include "chrome/browser/chromeos/plugin_vm/plugin_vm_util.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
-#include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h"
-#include "chrome/browser/ui/webui/chromeos/smb_shares/smb_handler.h"
-#include "chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h"
#include "chrome/browser/ui/webui/settings/chromeos/account_manager_handler.h"
#include "chrome/browser/ui/webui/settings/chromeos/android_apps_handler.h"
-#include "chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h"
-#include "chrome/browser/ui/webui/settings/chromeos/crostini_handler.h"
-#include "chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h"
-#include "chrome/browser/ui/webui/settings/chromeos/date_time_handler.h"
-#include "chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.h"
-#include "chrome/browser/ui/webui/settings/chromeos/device_pointer_handler.h"
-#include "chrome/browser/ui/webui/settings/chromeos/device_power_handler.h"
-#include "chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h"
-#include "chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.h"
-#include "chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.h"
-#include "chrome/browser/ui/webui/settings/chromeos/google_assistant_handler.h"
-#include "chrome/browser/ui/webui/settings/chromeos/internet_handler.h"
-#include "chrome/browser/ui/webui/settings/chromeos/kerberos_accounts_handler.h"
#include "chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h"
-#include "chrome/browser/ui/webui/settings/chromeos/parental_controls_handler.h"
-#include "chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.h"
-#include "chrome/browser/ui/webui/settings/chromeos/wallpaper_handler.h"
-#include "chrome/browser/web_applications/system_web_app_manager.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/grit/browser_resources.h"
#include "chromeos/components/account_manager/account_manager.h"
#include "chromeos/components/account_manager/account_manager_factory.h"
#include "chromeos/constants/chromeos_features.h"
-#include "chromeos/constants/chromeos_pref_names.h"
#include "chromeos/login/auth/password_visibility_utils.h"
-#include "chromeos/services/multidevice_setup/public/cpp/prefs.h"
-#include "chromeos/services/network_config/public/mojom/constants.mojom.h" // nogncheck
-#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h" // nogncheck
#include "components/arc/arc_util.h"
-#include "components/prefs/pref_service.h"
#include "components/user_manager/user.h"
#include "ui/base/ui_base_features.h"
-#include "ui/chromeos/resources/grit/ui_chromeos_resources.h"
-#include "ui/resources/grit/webui_resources.h"
#else // !defined(OS_CHROMEOS)
#include "chrome/browser/signin/account_consistency_mode_manager.h"
#include "chrome/browser/ui/webui/settings/settings_default_browser_handler.h"
@@ -154,6 +133,12 @@
#endif
namespace settings {
+
+#if !BUILDFLAG(OPTIMIZE_WEBUI)
+constexpr char kGeneratedPath[] =
+ "@out_folder@/gen/chrome/browser/resources/settings/";
+#endif
+
// static
void SettingsUI::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) {
@@ -169,11 +154,7 @@ web_app::AppRegistrar& GetRegistrarForProfile(Profile* profile) {
}
SettingsUI::SettingsUI(content::WebUI* web_ui)
-#if defined(OS_CHROMEOS)
- : ui::MojoWebUIController(web_ui, /*enable_chrome_send =*/true),
-#else
: content::WebUIController(web_ui),
-#endif
webui_load_timer_(web_ui->GetWebContents(),
"Settings.LoadDocumentTime.MD",
"Settings.LoadCompletedTime.MD") {
@@ -181,6 +162,18 @@ SettingsUI::SettingsUI(content::WebUI* web_ui)
content::WebUIDataSource* html_source =
content::WebUIDataSource::Create(chrome::kChromeUISettingsHost);
+ // TODO(dpapad): Replace the following calls with
+ // SetupBundledWebUIDataSource() when Settings is migrated to Polymer3.
+ // Currently only used for testing the Polymer 3 version of
+ // certificate-manager.
+#if BUILDFLAG(OPTIMIZE_WEBUI)
+ html_source->EnableReplaceI18nInJS();
+ html_source->OverrideContentSecurityPolicyScriptSrc(
+ "script-src chrome://resources chrome://test 'self';");
+ html_source->AddResourcePath("test_loader.js", IDR_WEBUI_JS_TEST_LOADER);
+ html_source->AddResourcePath("test_loader.html", IDR_WEBUI_HTML_TEST_LOADER);
+#endif
+
AddSettingsPageUIHandler(std::make_unique<AppearanceHandler>(web_ui));
#if defined(USE_NSS_CERTS)
@@ -192,12 +185,15 @@ SettingsUI::SettingsUI(content::WebUI* web_ui)
AddSettingsPageUIHandler(std::make_unique<AccessibilityMainHandler>());
AddSettingsPageUIHandler(std::make_unique<BrowserLifetimeHandler>());
- AddSettingsPageUIHandler(std::make_unique<ClearBrowsingDataHandler>(web_ui));
+ AddSettingsPageUIHandler(
+ std::make_unique<ClearBrowsingDataHandler>(web_ui, profile));
+ AddSettingsPageUIHandler(std::make_unique<SafetyCheckHandler>());
AddSettingsPageUIHandler(std::make_unique<CookiesViewHandler>());
AddSettingsPageUIHandler(std::make_unique<DownloadsHandler>(profile));
AddSettingsPageUIHandler(std::make_unique<ExtensionControlHandler>());
AddSettingsPageUIHandler(std::make_unique<FontHandler>(web_ui));
AddSettingsPageUIHandler(std::make_unique<ImportDataHandler>());
+ AddSettingsPageUIHandler(std::make_unique<HatsHandler>());
#if defined(OS_WIN) || defined(OS_CHROMEOS)
AddSettingsPageUIHandler(std::make_unique<LanguagesHandler>(web_ui));
@@ -212,7 +208,9 @@ SettingsUI::SettingsUI(content::WebUI* web_ui)
AddSettingsPageUIHandler(std::make_unique<PeopleHandler>(profile));
AddSettingsPageUIHandler(std::make_unique<ProfileInfoHandler>(profile));
AddSettingsPageUIHandler(std::make_unique<ProtocolHandlersHandler>());
+ AddSettingsPageUIHandler(std::make_unique<SafeBrowsingHandler>(profile));
AddSettingsPageUIHandler(std::make_unique<SearchEnginesHandler>(profile));
+ AddSettingsPageUIHandler(std::make_unique<SecureDnsHandler>());
AddSettingsPageUIHandler(std::make_unique<SiteSettingsHandler>(
profile, GetRegistrarForProfile(profile)));
AddSettingsPageUIHandler(std::make_unique<StartupPagesHandler>(web_ui));
@@ -227,9 +225,7 @@ SettingsUI::SettingsUI(content::WebUI* web_ui)
#endif
#if defined(OS_CHROMEOS)
- // TODO(950007): Remove this when SplitSettings is the default and there are
- // no Chrome OS settings in the browser settings page.
- InitOSWebUIHandlers(profile, web_ui, html_source);
+ InitBrowserSettingsWebUIHandlers();
#else
AddSettingsPageUIHandler(std::make_unique<DefaultBrowserHandler>());
AddSettingsPageUIHandler(std::make_unique<ManageProfileHandler>(profile));
@@ -256,60 +252,77 @@ SettingsUI::SettingsUI(content::WebUI* web_ui)
std::make_unique<IncompatibleApplicationsHandler>());
#endif // OS_WIN && BUILDFLAG(GOOGLE_CHROME_BRANDING)
-#if !defined(OS_CHROMEOS)
+ html_source->AddBoolean("signinAllowed", !profile->IsGuestSession() &&
+ profile->GetPrefs()->GetBoolean(
+ prefs::kSigninAllowed));
html_source->AddBoolean(
- "diceEnabled",
- AccountConsistencyModeManager::IsDiceEnabledForProfile(profile));
-#endif // !defined(OS_CHROMEOS)
+ "improvedCookieControlsEnabled",
+ base::FeatureList::IsEnabled(content_settings::kImprovedCookieControls));
html_source->AddBoolean(
"privacySettingsRedesignEnabled",
base::FeatureList::IsEnabled(features::kPrivacySettingsRedesign));
html_source->AddBoolean(
+ "safeBrowsingEnhancedEnabled",
+ base::FeatureList::IsEnabled(safe_browsing::kEnhancedProtection));
+
+ html_source->AddBoolean(
"navigateToGooglePasswordManager",
ShouldManagePasswordsinGooglePasswordManager(profile));
+ html_source->AddBoolean(
+ "enablePasswordCheck",
+ base::FeatureList::IsEnabled(password_manager::features::kPasswordCheck));
+
html_source->AddBoolean("showImportPasswords",
base::FeatureList::IsEnabled(
password_manager::features::kPasswordImport));
+ html_source->AddBoolean(
+ "enableAccountStorage",
+ base::FeatureList::IsEnabled(
+ password_manager::features::kEnablePasswordsAccountStorage));
+
+ html_source->AddBoolean(
+ "syncSetupFriendlySettings",
+ base::FeatureList::IsEnabled(features::kSyncSetupFriendlySettings));
+
#if defined(OS_CHROMEOS)
+ html_source->AddBoolean("splitSettingsSyncEnabled",
+ chromeos::features::IsSplitSettingsSyncEnabled());
+ html_source->AddBoolean("splitSyncConsent",
+ chromeos::features::IsSplitSyncConsentEnabled());
+
html_source->AddBoolean(
- "showParentalControls",
- chromeos::settings::ShouldShowParentalControls(profile));
+ "userCannotManuallyEnterPassword",
+ !chromeos::password_visibility::AccountHasUserFacingPassword(
+ chromeos::ProfileHelper::Get()
+ ->GetUserByProfile(profile)
+ ->GetAccountId()));
#endif
#if defined(OS_CHROMEOS)
// This is the browser settings page.
html_source->AddBoolean("isOSSettings", false);
- // If false, hides OS-specific settings (like networks) in browser settings.
- html_source->AddBoolean(
- "showOSSettings",
- !base::FeatureList::IsEnabled(chromeos::features::kSplitSettings));
-#else
- html_source->AddBoolean("showOSSettings", false);
#endif
+ // TODO(crbug.com/1026455): Delete this as part of the SplitSettings cleanup.
+ html_source->AddBoolean("showOSSettings", false);
AddSettingsPageUIHandler(
base::WrapUnique(AboutHandler::Create(html_source, profile)));
AddSettingsPageUIHandler(
base::WrapUnique(ResetSettingsHandler::Create(html_source, profile)));
+ // Add a handler to provide pluralized strings.
+ auto plural_string_handler = std::make_unique<PluralStringHandler>();
+ plural_string_handler->AddLocalizedString(
+ "compromisedPasswords", IDS_SETTINGS_COMPROMISED_PASSWORDS_COUNT);
+ web_ui->AddMessageHandler(std::move(plural_string_handler));
+
// Add the metrics handler to write uma stats.
web_ui->AddMessageHandler(std::make_unique<MetricsHandler>());
-#if defined(OS_CHROMEOS)
- // Add the System Web App resources for Settings.
- // TODO(jamescook|calamity): Migrate to chromeos::settings::OSSettingsUI.
- if (web_app::SystemWebAppManager::IsEnabled()) {
- html_source->AddResourcePath("icon-192.png", IDR_SETTINGS_LOGO_192);
- html_source->AddResourcePath("pwa.html", IDR_PWA_HTML);
- web_app::SetManifestRequestFilter(html_source, IDR_SETTINGS_MANIFEST,
- IDS_SETTINGS_SETTINGS);
- }
-#endif // defined (OS_CHROMEOS)
-
#if BUILDFLAG(OPTIMIZE_WEBUI)
html_source->AddResourcePath("crisper.js", IDR_SETTINGS_CRISPER_JS);
html_source->AddResourcePath("lazy_load.crisper.js",
@@ -317,16 +330,52 @@ SettingsUI::SettingsUI(content::WebUI* web_ui)
html_source->AddResourcePath("lazy_load.html",
IDR_SETTINGS_LAZY_LOAD_VULCANIZED_HTML);
html_source->SetDefaultResource(IDR_SETTINGS_VULCANIZED_HTML);
+
+ // Register SVG images that are purposefully not inlined in the HTML bundle
+ // above.
+ html_source->AddResourcePath("images/cookies_banner.svg",
+ IDR_SETTINGS_IMAGES_COOKIES_BANNER_SVG);
+ html_source->AddResourcePath("images/cookies_banner_dark.svg",
+ IDR_SETTINGS_IMAGES_COOKIES_BANNER_DARK_SVG);
+ html_source->AddResourcePath("images/permissions_banner.svg",
+ IDR_SETTINGS_IMAGES_PERMISSIONS_BANNER_SVG);
+ html_source->AddResourcePath("images/permissions_banner_dark.svg",
+ IDR_SETTINGS_IMAGES_PERMISSIONS_BANNER_DARK_SVG);
+ html_source->AddResourcePath("images/safe_browsing_banner.svg",
+ IDR_SETTINGS_IMAGES_SAFE_BROWSING_BANNER_SVG);
+ html_source->AddResourcePath(
+ "images/safe_browsing_banner_dark.svg",
+ IDR_SETTINGS_IMAGES_SAFE_BROWSING_BANNER_DARK_SVG);
+ html_source->AddResourcePath("images/sync_banner.svg",
+ IDR_SETTINGS_IMAGES_SYNC_BANNER_SVG);
+ html_source->AddResourcePath("images/sync_banner_dark.svg",
+ IDR_SETTINGS_IMAGES_SYNC_BANNER_DARK_SVG);
+ html_source->AddResourcePath("images/password_check_neutral.svg",
+ IDR_SETTINGS_IMAGES_PASSWORD_CHECK_NEUTRAL_SVG);
+ html_source->AddResourcePath(
+ "images/password_check_neutral_dark.svg",
+ IDR_SETTINGS_IMAGES_PASSWORD_CHECK_NEUTRAL_DARK_SVG);
+ html_source->AddResourcePath("images/password_check_positive.svg",
+ IDR_SETTINGS_IMAGES_PASSWORD_CHECK_POSITIVE_SVG);
+ html_source->AddResourcePath(
+ "images/password_check_positive_dark.svg",
+ IDR_SETTINGS_IMAGES_PASSWORD_CHECK_POSITIVE_DARK_SVG);
+
+ // Only used in Polymer 3, see https://crbug.com/1026426.
+ html_source->AddResourcePath("settings.js", IDR_SETTINGS_SETTINGS_ROLLUP_JS);
+ html_source->AddResourcePath("shared.rollup.js",
+ IDR_SETTINGS_SHARED_ROLLUP_JS);
+ html_source->AddResourcePath("lazy_load.js",
+ IDR_SETTINGS_LAZY_LOAD_ROLLUP_JS);
+ html_source->AddResourcePath("settings_v3.html",
+ IDR_SETTINGS_SETTINGS_V3_HTML);
#else
- // Add all settings resources.
- for (size_t i = 0; i < kSettingsResourcesSize; ++i) {
- html_source->AddResourcePath(kSettingsResources[i].name,
- kSettingsResources[i].value);
- }
- html_source->SetDefaultResource(IDR_SETTINGS_SETTINGS_HTML);
+ webui::SetupWebUIDataSource(
+ html_source, base::make_span(kSettingsResources, kSettingsResourcesSize),
+ kGeneratedPath, IDR_SETTINGS_SETTINGS_HTML);
#endif
- AddLocalizedStrings(html_source, profile, web_ui->GetWebContents());
+ AddBrowserLocalizedStrings(html_source, profile, web_ui->GetWebContents());
ManagedUIHandler::Initialize(web_ui, html_source);
@@ -337,19 +386,15 @@ SettingsUI::SettingsUI(content::WebUI* web_ui)
profile, std::make_unique<FaviconSource>(
profile, chrome::FaviconUrlFormat::kFavicon2));
-#if defined(OS_CHROMEOS)
- AddHandlerToRegistry(base::BindRepeating(&SettingsUI::BindCrosNetworkConfig,
- base::Unretained(this)));
-#endif // defined (OS_CHROMEOS)
+ TryShowHatsSurveyWithTimeout();
}
SettingsUI::~SettingsUI() = default;
#if defined(OS_CHROMEOS)
-// static
-void SettingsUI::InitOSWebUIHandlers(Profile* profile,
- content::WebUI* web_ui,
- content::WebUIDataSource* html_source) {
+void SettingsUI::InitBrowserSettingsWebUIHandlers() {
+ Profile* profile = Profile::FromWebUI(web_ui());
+
// TODO(jamescook): Sort out how account management is split between Chrome OS
// and browser settings.
if (chromeos::IsAccountManagerAvailable(profile)) {
@@ -359,75 +404,19 @@ void SettingsUI::InitOSWebUIHandlers(Profile* profile,
factory->GetAccountManager(profile->GetPath().value());
DCHECK(account_manager);
- web_ui->AddMessageHandler(
+ web_ui()->AddMessageHandler(
std::make_unique<chromeos::settings::AccountManagerUIHandler>(
account_manager, IdentityManagerFactory::GetForProfile(profile)));
- html_source->AddBoolean(
- "secondaryGoogleAccountSigninAllowed",
- profile->GetPrefs()->GetBoolean(
- chromeos::prefs::kSecondaryGoogleAccountSigninAllowed));
- }
-
- web_ui->AddMessageHandler(
- std::make_unique<chromeos::settings::ChangePictureHandler>());
-
- web_ui->AddMessageHandler(
- std::make_unique<chromeos::settings::AccessibilityHandler>(web_ui));
- web_ui->AddMessageHandler(
- std::make_unique<chromeos::settings::AndroidAppsHandler>(profile));
- if (crostini::CrostiniFeatures::Get()->IsUIAllowed(profile,
- /*check_policy=*/false)) {
- web_ui->AddMessageHandler(
- std::make_unique<chromeos::settings::CrostiniHandler>(profile));
- }
- web_ui->AddMessageHandler(
- chromeos::settings::CupsPrintersHandler::Create(web_ui));
- web_ui->AddMessageHandler(base::WrapUnique(
- chromeos::settings::DateTimeHandler::Create(html_source)));
- web_ui->AddMessageHandler(
- std::make_unique<chromeos::settings::FingerprintHandler>(profile));
- web_ui->AddMessageHandler(
- std::make_unique<chromeos::settings::GoogleAssistantHandler>(profile));
-
- std::unique_ptr<chromeos::settings::KerberosAccountsHandler>
- kerberos_accounts_handler =
- chromeos::settings::KerberosAccountsHandler::CreateIfKerberosEnabled(
- profile);
- if (kerberos_accounts_handler) {
- // Note that the UI is enabled only if Kerberos is enabled.
- web_ui->AddMessageHandler(std::move(kerberos_accounts_handler));
}
- web_ui->AddMessageHandler(
- std::make_unique<chromeos::settings::KeyboardHandler>());
-
- // TODO(crbug/950007): Remove adding WallpaperHandler when
- // SplitSettings complete.
- web_ui->AddMessageHandler(
- std::make_unique<chromeos::settings::WallpaperHandler>(web_ui));
-
- if (plugin_vm::IsPluginVmEnabled(profile)) {
- web_ui->AddMessageHandler(
- std::make_unique<chromeos::settings::PluginVmHandler>(profile));
- }
- web_ui->AddMessageHandler(
- std::make_unique<chromeos::settings::PointerHandler>());
- web_ui->AddMessageHandler(
- std::make_unique<chromeos::settings::StorageHandler>(profile,
- html_source));
- web_ui->AddMessageHandler(
- std::make_unique<chromeos::settings::StylusHandler>());
- web_ui->AddMessageHandler(
- std::make_unique<chromeos::settings::InternetHandler>(profile));
- web_ui->AddMessageHandler(std::make_unique<TtsHandler>());
- web_ui->AddMessageHandler(
- std::make_unique<chromeos::smb_dialog::SmbHandler>(profile));
-
+ // MultideviceHandler is required in browser settings to show a special note
+ // under the notification permission that is auto-granted for Android Messages
+ // integration in ChromeOS.
if (!profile->IsGuestSession()) {
chromeos::android_sms::AndroidSmsService* android_sms_service =
chromeos::android_sms::AndroidSmsServiceFactory::GetForBrowserContext(
profile);
- web_ui->AddMessageHandler(
+ web_ui()->AddMessageHandler(
std::make_unique<chromeos::settings::MultideviceHandler>(
profile->GetPrefs(),
chromeos::multidevice_setup::MultiDeviceSetupClientFactory::
@@ -437,93 +426,10 @@ void SettingsUI::InitOSWebUIHandlers(Profile* profile,
: nullptr,
android_sms_service ? android_sms_service->android_sms_app_manager()
: nullptr));
- if (chromeos::settings::ShouldShowParentalControls(profile)) {
- web_ui->AddMessageHandler(
- std::make_unique<chromeos::settings::ParentalControlsHandler>(
- profile));
- }
- }
-
- html_source->AddBoolean(
- "privacySettingsRedesignEnabled",
- base::FeatureList::IsEnabled(::features::kPrivacySettingsRedesign));
-
- html_source->AddBoolean(
- "multideviceAllowedByPolicy",
- chromeos::multidevice_setup::AreAnyMultiDeviceFeaturesAllowed(
- profile->GetPrefs()));
- html_source->AddBoolean(
- "quickUnlockEnabled",
- chromeos::quick_unlock::IsPinEnabled(profile->GetPrefs()));
- html_source->AddBoolean(
- "quickUnlockDisabledByPolicy",
- chromeos::quick_unlock::IsPinDisabledByPolicy(profile->GetPrefs()));
- html_source->AddBoolean(
- "userCannotManuallyEnterPassword",
- !chromeos::password_visibility::AccountHasUserFacingPassword(
- chromeos::ProfileHelper::Get()
- ->GetUserByProfile(profile)
- ->GetAccountId()));
- const bool fingerprint_unlock_enabled =
- chromeos::quick_unlock::IsFingerprintEnabled(profile);
- html_source->AddBoolean("fingerprintUnlockEnabled",
- fingerprint_unlock_enabled);
- if (fingerprint_unlock_enabled) {
- html_source->AddInteger(
- "fingerprintReaderLocation",
- static_cast<int32_t>(chromeos::quick_unlock::GetFingerprintLocation()));
-
- // To use lottie, the worker-src CSP needs to be updated for the web ui that
- // is using it. Since as of now there are only a couple of webuis using
- // lottie animations, this update has to be performed manually. As the usage
- // increases, set this as the default so manual override is no longer
- // required.
- html_source->OverrideContentSecurityPolicyWorkerSrc(
- "worker-src blob: 'self';");
- html_source->AddResourcePath("finger_print.json",
- IDR_LOGIN_FINGER_PRINT_TABLET_ANIMATION);
}
- html_source->AddBoolean("lockScreenNotificationsEnabled",
- ash::features::IsLockScreenNotificationsEnabled());
- html_source->AddBoolean(
- "lockScreenHideSensitiveNotificationsSupported",
- ash::features::IsLockScreenHideSensitiveNotificationsSupported());
- html_source->AddBoolean("showTechnologyBadge",
- !ash::features::IsSeparateNetworkIconsEnabled());
- html_source->AddBoolean("hasInternalStylus",
- ash::stylus_utils::HasInternalStylus());
-
- html_source->AddBoolean("showCrostini",
- crostini::CrostiniFeatures::Get()->IsUIAllowed(
- profile, /*check_policy=*/false));
-
- html_source->AddBoolean(
- "allowCrostini", crostini::CrostiniFeatures::Get()->IsUIAllowed(profile));
- html_source->AddBoolean("showPluginVm",
- plugin_vm::IsPluginVmEnabled(profile));
-
- html_source->AddBoolean("isDemoSession",
- chromeos::DemoSession::IsDeviceInDemoMode());
-
- // We have 2 variants of Android apps settings. Default case, when the Play
- // Store app exists we show expandable section that allows as to
- // enable/disable the Play Store and link to Android settings which is
- // available once settings app is registered in the system.
- // For AOSP images we don't have the Play Store app. In last case we Android
- // apps settings consists only from root link to Android settings and only
- // visible once settings app is registered.
- html_source->AddBoolean("androidAppsVisible",
- arc::IsArcAllowedForProfile(profile));
- html_source->AddBoolean("havePlayStoreApp", arc::IsPlayStoreAvailable());
-
- html_source->AddBoolean("enablePowerSettings", true);
- web_ui->AddMessageHandler(
- std::make_unique<chromeos::settings::PowerHandler>(profile->GetPrefs()));
-
- html_source->AddBoolean(
- "showParentalControlsSettings",
- chromeos::settings::ShouldShowParentalControls(profile));
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::AndroidAppsHandler>(profile));
}
#endif // defined(OS_CHROMEOS)
@@ -533,12 +439,14 @@ void SettingsUI::AddSettingsPageUIHandler(
web_ui()->AddMessageHandler(std::move(handler));
}
-#if defined(OS_CHROMEOS)
-void SettingsUI::BindCrosNetworkConfig(
- mojo::PendingReceiver<chromeos::network_config::mojom::CrosNetworkConfig>
- receiver) {
- ash::GetNetworkConfigService(std::move(receiver));
+void SettingsUI::TryShowHatsSurveyWithTimeout() {
+ HatsService* hats_service =
+ HatsServiceFactory::GetForProfile(Profile::FromWebUI(web_ui()),
+ /* create_if_necessary = */ true);
+ if (hats_service) {
+ hats_service->LaunchDelayedSurveyForWebContents(
+ kHatsSurveyTriggerSettings, web_ui()->GetWebContents(), 20000);
+ }
}
-#endif // defined(OS_CHROMEOS)
} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/settings_ui.h b/chromium/chrome/browser/ui/webui/settings/settings_ui.h
index 0353806fc15..ff4a05c608e 100644
--- a/chromium/chrome/browser/ui/webui/settings/settings_ui.h
+++ b/chromium/chrome/browser/ui/webui/settings/settings_ui.h
@@ -8,19 +8,9 @@
#include "base/macros.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/webui_load_timer.h"
-
-#if defined(OS_CHROMEOS)
-#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom-forward.h" // nogncheck
-#include "mojo/public/cpp/bindings/pending_receiver.h"
-#include "ui/webui/mojo_web_ui_controller.h"
-#else
#include "content/public/browser/web_ui_controller.h"
-#endif
-
-class Profile;
namespace content {
-class WebUIDataSource;
class WebUIMessageHandler;
} // namespace content
@@ -31,13 +21,7 @@ class PrefRegistrySyncable;
namespace settings {
// The WebUI handler for chrome://settings.
-class SettingsUI
-#if defined(OS_CHROMEOS)
- : public ui::MojoWebUIController
-#else
- : public content::WebUIController
-#endif
-{
+class SettingsUI : public content::WebUIController {
public:
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
@@ -45,20 +29,17 @@ class SettingsUI
~SettingsUI() override;
#if defined(OS_CHROMEOS)
- // Initializes the WebUI message handlers for OS-specific settings.
- static void InitOSWebUIHandlers(Profile* profile,
- content::WebUI* web_ui,
- content::WebUIDataSource* html_source);
+ // Initializes the WebUI message handlers for CrOS-specific settings that are
+ // still shown in the browser settings UI.
+ void InitBrowserSettingsWebUIHandlers();
#endif // defined(OS_CHROMEOS)
private:
void AddSettingsPageUIHandler(
std::unique_ptr<content::WebUIMessageHandler> handler);
-#if defined(OS_CHROMEOS)
- void BindCrosNetworkConfig(
- mojo::PendingReceiver<chromeos::network_config::mojom::CrosNetworkConfig>
- receiver);
-#endif
+
+ // Makes a request to show a HaTS survey.
+ void TryShowHatsSurveyWithTimeout();
WebuiLoadTimer webui_load_timer_;
diff --git a/chromium/chrome/browser/ui/webui/settings/settings_ui_browsertest.cc b/chromium/chrome/browser/ui/webui/settings/settings_ui_browsertest.cc
index 459f2165900..c19638cf1bc 100644
--- a/chromium/chrome/browser/ui/webui/settings/settings_ui_browsertest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/settings_ui_browsertest.cc
@@ -5,7 +5,10 @@
#include <string>
#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/hats/hats_service_factory.h"
+#include "chrome/browser/ui/hats/mock_hats_service.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/browser/ui/webui/settings/settings_ui.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
@@ -17,6 +20,7 @@
typedef InProcessBrowserTest SettingsUITest;
+using ::testing::_;
using ui_test_utils::NavigateToURL;
IN_PROC_BROWSER_TEST_F(SettingsUITest, ViewSourceDoesntCrash) {
@@ -43,3 +47,13 @@ IN_PROC_BROWSER_TEST_F(SettingsUITest, ToggleJavaScript) {
handler->AllowJavascriptForTesting();
}
}
+
+IN_PROC_BROWSER_TEST_F(SettingsUITest, TriggerHappinessTrackingSurveys) {
+ MockHatsService* mock_hats_service_ = static_cast<MockHatsService*>(
+ HatsServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+ browser()->profile(), base::BindRepeating(&BuildMockHatsService)));
+ EXPECT_CALL(*mock_hats_service_, LaunchDelayedSurveyForWebContents(
+ kHatsSurveyTriggerSettings, _, _));
+ NavigateToURL(browser(), GURL(chrome::kChromeUISettingsURL));
+ base::RunLoop().RunUntilIdle();
+}
diff --git a/chromium/chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.cc b/chromium/chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.cc
new file mode 100644
index 00000000000..9a461686fd3
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.cc
@@ -0,0 +1,243 @@
+// Copyright 2020 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 "chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.h"
+
+#include "base/feature_list.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/system/sys_info.h"
+#include "build/build_config.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/browser_process_platform_part.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
+#include "chrome/browser/ui/ui_features.h"
+#include "chrome/browser/ui/webui/webui_util.h"
+#include "chrome/common/chrome_features.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/grit/chromium_strings.h"
+#include "chrome/grit/generated_resources.h"
+#include "chromeos/constants/chromeos_features.h"
+#include "components/google/core/common/google_util.h"
+#include "components/strings/grit/components_strings.h"
+#include "components/user_manager/user_manager.h"
+#include "content/public/browser/web_ui_data_source.h"
+#include "content/public/common/content_features.h"
+#include "media/base/media_switches.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/webui/web_ui_util.h"
+
+#if defined(OS_CHROMEOS)
+#include "ui/base/l10n/l10n_util.h"
+#endif
+
+namespace settings {
+#if defined(OS_CHROMEOS)
+namespace {
+
+// Generates a Google Help URL which includes a "board type" parameter. Some
+// help pages need to be adjusted depending on the type of CrOS device that is
+// accessing the page.
+base::string16 GetHelpUrlWithBoard(const std::string& original_url) {
+ return base::ASCIIToUTF16(original_url +
+ "&b=" + base::SysInfo::GetLsbReleaseBoard());
+}
+
+} // namespace
+#endif
+
+void AddCaptionSubpageStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"captionsTitle", IDS_SETTINGS_CAPTIONS},
+ {"captionsSettings", IDS_SETTINGS_CAPTIONS_SETTINGS},
+ {"captionsPreview", IDS_SETTINGS_CAPTIONS_PREVIEW},
+ {"captionsTextSize", IDS_SETTINGS_CAPTIONS_TEXT_SIZE},
+ {"captionsTextFont", IDS_SETTINGS_CAPTIONS_TEXT_FONT},
+ {"captionsTextColor", IDS_SETTINGS_CAPTIONS_TEXT_COLOR},
+ {"captionsTextOpacity", IDS_SETTINGS_CAPTIONS_TEXT_OPACITY},
+ {"captionsBackgroundOpacity", IDS_SETTINGS_CAPTIONS_BACKGROUND_OPACITY},
+ {"captionsOpacityOpaque", IDS_SETTINGS_CAPTIONS_OPACITY_OPAQUE},
+ {"captionsOpacitySemiTransparent",
+ IDS_SETTINGS_CAPTIONS_OPACITY_SEMI_TRANSPARENT},
+ {"captionsOpacityTransparent", IDS_SETTINGS_CAPTIONS_OPACITY_TRANSPARENT},
+ {"captionsTextShadow", IDS_SETTINGS_CAPTIONS_TEXT_SHADOW},
+ {"captionsTextShadowNone", IDS_SETTINGS_CAPTIONS_TEXT_SHADOW_NONE},
+ {"captionsTextShadowRaised", IDS_SETTINGS_CAPTIONS_TEXT_SHADOW_RAISED},
+ {"captionsTextShadowDepressed",
+ IDS_SETTINGS_CAPTIONS_TEXT_SHADOW_DEPRESSED},
+ {"captionsTextShadowUniform", IDS_SETTINGS_CAPTIONS_TEXT_SHADOW_UNIFORM},
+ {"captionsTextShadowDropShadow",
+ IDS_SETTINGS_CAPTIONS_TEXT_SHADOW_DROP_SHADOW},
+ {"captionsBackgroundColor", IDS_SETTINGS_CAPTIONS_BACKGROUND_COLOR},
+ {"captionsColorBlack", IDS_SETTINGS_CAPTIONS_COLOR_BLACK},
+ {"captionsColorWhite", IDS_SETTINGS_CAPTIONS_COLOR_WHITE},
+ {"captionsColorRed", IDS_SETTINGS_CAPTIONS_COLOR_RED},
+ {"captionsColorGreen", IDS_SETTINGS_CAPTIONS_COLOR_GREEN},
+ {"captionsColorBlue", IDS_SETTINGS_CAPTIONS_COLOR_BLUE},
+ {"captionsColorYellow", IDS_SETTINGS_CAPTIONS_COLOR_YELLOW},
+ {"captionsColorCyan", IDS_SETTINGS_CAPTIONS_COLOR_CYAN},
+ {"captionsColorMagenta", IDS_SETTINGS_CAPTIONS_COLOR_MAGENTA},
+ {"captionsDefaultSetting", IDS_SETTINGS_CAPTIONS_DEFAULT_SETTING},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+}
+
+void AddPersonalizationOptionsStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"urlKeyedAnonymizedDataCollection",
+ IDS_SETTINGS_ENABLE_URL_KEYED_ANONYMIZED_DATA_COLLECTION},
+ {"urlKeyedAnonymizedDataCollectionDesc",
+ IDS_SETTINGS_ENABLE_URL_KEYED_ANONYMIZED_DATA_COLLECTION_DESC},
+ {"spellingPref", IDS_SETTINGS_SPELLING_PREF},
+#if !defined(OS_CHROMEOS)
+ {"signinAllowedTitle", IDS_SETTINGS_SIGNIN_ALLOWED},
+ {"signinAllowedDescription", IDS_SETTINGS_SIGNIN_ALLOWED_DESC},
+#endif
+ {"searchSuggestPref", IDS_SETTINGS_SUGGEST_PREF},
+ {"enablePersonalizationLogging", IDS_SETTINGS_ENABLE_LOGGING_PREF},
+ {"enablePersonalizationLoggingDesc", IDS_SETTINGS_ENABLE_LOGGING_PREF_DESC},
+ {"spellingDescription", IDS_SETTINGS_SPELLING_PREF_DESC},
+ {"searchSuggestPrefDesc", IDS_SETTINGS_SUGGEST_PREF_DESC},
+ {"linkDoctorPref", IDS_SETTINGS_LINKDOCTOR_PREF},
+ {"linkDoctorPrefDesc", IDS_SETTINGS_LINKDOCTOR_PREF_DESC},
+ {"driveSuggestPref", IDS_DRIVE_SUGGEST_PREF},
+ {"driveSuggestPrefDesc", IDS_DRIVE_SUGGEST_PREF_DESC},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+}
+
+void AddSyncControlsStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"autofillCheckboxLabel", IDS_SETTINGS_AUTOFILL_CHECKBOX_LABEL},
+ {"historyCheckboxLabel", IDS_SETTINGS_HISTORY_CHECKBOX_LABEL},
+ {"extensionsCheckboxLabel", IDS_SETTINGS_EXTENSIONS_CHECKBOX_LABEL},
+ {"openTabsCheckboxLabel", IDS_SETTINGS_OPEN_TABS_CHECKBOX_LABEL},
+ {"syncEverythingCheckboxLabel",
+ IDS_SETTINGS_SYNC_EVERYTHING_CHECKBOX_LABEL},
+ {"appCheckboxLabel", IDS_SETTINGS_APPS_CHECKBOX_LABEL},
+ {"enablePaymentsIntegrationCheckboxLabel",
+ IDS_AUTOFILL_ENABLE_PAYMENTS_INTEGRATION_CHECKBOX_LABEL},
+ {"nonPersonalizedServicesSectionLabel",
+ IDS_SETTINGS_NON_PERSONALIZED_SERVICES_SECTION_LABEL},
+ {"customizeSyncLabel", IDS_SETTINGS_CUSTOMIZE_SYNC},
+ {"syncData", IDS_SETTINGS_SYNC_DATA},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+}
+
+void AddSyncAccountControlStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"syncingTo", IDS_SETTINGS_PEOPLE_SYNCING_TO_ACCOUNT},
+ {"peopleSignIn", IDS_PROFILES_DICE_SIGNIN_BUTTON},
+ {"syncPaused", IDS_SETTINGS_PEOPLE_SYNC_PAUSED},
+ {"turnOffSync", IDS_SETTINGS_PEOPLE_SYNC_TURN_OFF},
+ {"settingsCheckboxLabel", IDS_SETTINGS_SETTINGS_CHECKBOX_LABEL},
+ {"syncNotWorking", IDS_SETTINGS_PEOPLE_SYNC_NOT_WORKING},
+ {"syncDisabled", IDS_PROFILES_DICE_SYNC_DISABLED_TITLE},
+ {"syncPasswordsNotWorking",
+ IDS_SETTINGS_PEOPLE_SYNC_PASSWORDS_NOT_WORKING},
+ {"peopleSignOut", IDS_SETTINGS_PEOPLE_SIGN_OUT},
+ {"useAnotherAccount", IDS_SETTINGS_PEOPLE_SYNC_ANOTHER_ACCOUNT},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+ if (base::FeatureList::IsEnabled(features::kSyncSetupFriendlySettings)) {
+ html_source->AddLocalizedString("syncAdvancedPageTitle",
+ IDS_SETTINGS_NEW_SYNC_ADVANCED_PAGE_TITLE);
+
+ } else {
+ html_source->AddLocalizedString("syncAdvancedPageTitle",
+ IDS_SETTINGS_SYNC_ADVANCED_PAGE_TITLE);
+ }
+}
+
+#if defined(OS_CHROMEOS)
+void AddPasswordPromptDialogStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"passwordPromptTitle", IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_TITLE},
+ {"passwordPromptInvalidPassword",
+ IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_INVALID_PASSWORD},
+ {"passwordPromptPasswordLabel",
+ IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_PASSWORD_LABEL},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+}
+#endif
+
+void AddSyncPageStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"syncDisabledByAdministrator",
+ IDS_SIGNED_IN_WITH_SYNC_DISABLED_BY_POLICY},
+ {"passwordsCheckboxLabel", IDS_SETTINGS_PASSWORDS_CHECKBOX_LABEL},
+ {"passphrasePlaceholder", IDS_SETTINGS_PASSPHRASE_PLACEHOLDER},
+ {"peopleSignInSyncPagePromptSecondaryWithAccount",
+ IDS_SETTINGS_PEOPLE_SIGN_IN_PROMPT_SECONDARY_WITH_ACCOUNT},
+ {"peopleSignInSyncPagePromptSecondaryWithNoAccount",
+ IDS_SETTINGS_PEOPLE_SIGN_IN_PROMPT_SECONDARY_WITH_ACCOUNT},
+ {"existingPassphraseTitle", IDS_SETTINGS_EXISTING_PASSPHRASE_TITLE},
+ {"submitPassphraseButton", IDS_SETTINGS_SUBMIT_PASSPHRASE},
+ {"encryptWithGoogleCredentialsLabel",
+ IDS_SETTINGS_ENCRYPT_WITH_GOOGLE_CREDENTIALS_LABEL},
+ {"bookmarksCheckboxLabel", IDS_SETTINGS_BOOKMARKS_CHECKBOX_LABEL},
+ {"encryptionOptionsTitle", IDS_SETTINGS_ENCRYPTION_OPTIONS},
+ {"mismatchedPassphraseError", IDS_SETTINGS_MISMATCHED_PASSPHRASE_ERROR},
+ {"emptyPassphraseError", IDS_SETTINGS_EMPTY_PASSPHRASE_ERROR},
+ {"incorrectPassphraseError", IDS_SETTINGS_INCORRECT_PASSPHRASE_ERROR},
+ {"syncPageTitle", IDS_SETTINGS_SYNC_SYNC_AND_NON_PERSONALIZED_SERVICES},
+ {"passphraseConfirmationPlaceholder",
+ IDS_SETTINGS_PASSPHRASE_CONFIRMATION_PLACEHOLDER},
+ {"syncLoading", IDS_SETTINGS_SYNC_LOADING},
+ {"themesAndWallpapersCheckboxLabel",
+ IDS_SETTINGS_THEMES_AND_WALLPAPERS_CHECKBOX_LABEL},
+ {"syncDataEncryptedText", IDS_SETTINGS_SYNC_DATA_ENCRYPTED_TEXT},
+ {"sync", IDS_SETTINGS_SYNC},
+ {"cancelSync", IDS_SETTINGS_SYNC_SETTINGS_CANCEL_SYNC},
+ {"syncSetupCancelDialogTitle",
+ IDS_SETTINGS_SYNC_SETUP_CANCEL_DIALOG_TITLE},
+ {"syncSetupCancelDialogBody", IDS_SETTINGS_SYNC_SETUP_CANCEL_DIALOG_BODY},
+ {"personalizeGoogleServicesTitle",
+ IDS_SETTINGS_PERSONALIZE_GOOGLE_SERVICES_TITLE},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ std::string sync_dashboard_url =
+ google_util::AppendGoogleLocaleParam(
+ GURL(chrome::kSyncGoogleDashboardURL),
+ g_browser_process->GetApplicationLocale())
+ .spec();
+
+ html_source->AddString(
+ "passphraseResetHintEncryption",
+ l10n_util::GetStringFUTF8(IDS_SETTINGS_PASSPHRASE_RESET_HINT_ENCRYPTION,
+ base::ASCIIToUTF16(sync_dashboard_url)));
+ html_source->AddString(
+ "passphraseRecover",
+ l10n_util::GetStringFUTF8(IDS_SETTINGS_PASSPHRASE_RECOVER,
+ base::ASCIIToUTF16(sync_dashboard_url)));
+ html_source->AddString("activityControlsUrl",
+ chrome::kGoogleAccountActivityControlsURL);
+ html_source->AddString("syncDashboardUrl", sync_dashboard_url);
+ html_source->AddString(
+ "passphraseExplanationText",
+ l10n_util::GetStringFUTF8(IDS_SETTINGS_PASSPHRASE_EXPLANATION_TEXT,
+ base::ASCIIToUTF16(sync_dashboard_url)));
+ html_source->AddString(
+ "encryptWithSyncPassphraseLabel",
+ l10n_util::GetStringFUTF8(
+ IDS_SETTINGS_ENCRYPT_WITH_SYNC_PASSPHRASE_LABEL,
+#if defined(OS_CHROMEOS)
+ GetHelpUrlWithBoard(chrome::kSyncEncryptionHelpURL)));
+#else
+ base::ASCIIToUTF16(chrome::kSyncEncryptionHelpURL)));
+#endif
+ if (base::FeatureList::IsEnabled(features::kSyncSetupFriendlySettings)) {
+ html_source->AddLocalizedString(
+ "manageSyncedDataTitle",
+ IDS_SETTINGS_NEW_MANAGE_SYNCED_DATA_TITLE_UNIFIED_CONSENT);
+ } else {
+ html_source->AddLocalizedString(
+ "manageSyncedDataTitle",
+ IDS_SETTINGS_MANAGE_SYNCED_DATA_TITLE_UNIFIED_CONSENT);
+ }
+}
+
+} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.h b/chromium/chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.h
new file mode 100644
index 00000000000..33dc5c453d4
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.h
@@ -0,0 +1,36 @@
+// Copyright 2020 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 CHROME_BROWSER_UI_WEBUI_SETTINGS_SHARED_SETTINGS_LOCALIZED_STRINGS_PROVIDER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_SHARED_SETTINGS_LOCALIZED_STRINGS_PROVIDER_H_
+
+namespace content {
+class WebUIDataSource;
+} // namespace content
+
+namespace settings {
+
+// Adds strings used by the <settings-captions> element.
+void AddCaptionSubpageStrings(content::WebUIDataSource* html_source);
+
+// Adds strings used by the <settings-personalization-options> element.
+void AddPersonalizationOptionsStrings(content::WebUIDataSource* html_source);
+
+// Adds strings used by the <settings-sync-controls> element.
+void AddSyncControlsStrings(content::WebUIDataSource* html_source);
+
+// Adds strings used by the <settings-sync-account-control> element.
+void AddSyncAccountControlStrings(content::WebUIDataSource* html_source);
+
+#if defined(OS_CHROMEOS)
+// Adds strings used by the <settings-password-prompt-dialog> element.
+void AddPasswordPromptDialogStrings(content::WebUIDataSource* html_source);
+#endif
+
+// Adds strings used by the <settings-sync-page> element.
+void AddSyncPageStrings(content::WebUIDataSource* html_source);
+
+} // namespace settings
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_SHARED_SETTINGS_LOCALIZED_STRINGS_PROVIDER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/site_settings_handler.cc b/chromium/chrome/browser/ui/webui/settings/site_settings_handler.cc
index 95ccbe20024..b53e4f98315 100644
--- a/chromium/chrome/browser/ui/webui/settings/site_settings_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/site_settings_handler.cc
@@ -5,11 +5,13 @@
#include "chrome/browser/ui/webui/settings/site_settings_handler.h"
#include <algorithm>
+#include <set>
#include <utility>
#include <vector>
#include "base/barrier_closure.h"
#include "base/bind.h"
+#include "base/feature_list.h"
#include "base/i18n/number_formatting.h"
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
@@ -17,22 +19,22 @@
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
+#include "chrome/browser/bluetooth/bluetooth_chooser_context.h"
+#include "chrome/browser/bluetooth/bluetooth_chooser_context_factory.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
-#include "chrome/browser/content_settings/web_site_settings_uma_util.h"
#include "chrome/browser/engagement/site_engagement_service.h"
+#include "chrome/browser/hid/hid_chooser_context.h"
+#include "chrome/browser/hid/hid_chooser_context_factory.h"
#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/browser/media/unified_autoplay_config.h"
-#include "chrome/browser/permissions/chooser_context_base.h"
-#include "chrome/browser/permissions/permission_decision_auto_blocker.h"
-#include "chrome/browser/permissions/permission_manager.h"
-#include "chrome/browser/permissions/permission_uma_util.h"
-#include "chrome/browser/permissions/permission_util.h"
+#include "chrome/browser/permissions/permission_decision_auto_blocker_factory.h"
#include "chrome/browser/serial/serial_chooser_context.h"
#include "chrome/browser/serial/serial_chooser_context_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/page_info/page_info_infobar_delegate.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/browser/ui/webui/recent_site_settings_helper.h"
#include "chrome/browser/ui/webui/site_settings_helper.h"
#include "chrome/browser/usb/usb_chooser_context.h"
#include "chrome/browser/usb/usb_chooser_context_factory.h"
@@ -41,15 +43,24 @@
#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chrome/common/pref_names.h"
#include "chrome/grit/generated_resources.h"
+#include "components/content_settings/core/browser/cookie_settings.h"
+#include "components/content_settings/core/browser/uma_util.h"
#include "components/content_settings/core/browser/website_settings_registry.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "components/content_settings/core/common/content_settings_utils.h"
+#include "components/content_settings/core/common/features.h"
+#include "components/content_settings/core/common/pref_names.h"
#include "components/crx_file/id_util.h"
+#include "components/permissions/chooser_context_base.h"
+#include "components/permissions/permission_decision_auto_blocker.h"
+#include "components/permissions/permission_uma_util.h"
+#include "components/permissions/permission_util.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
+#include "content/public/common/content_features.h"
#include "content/public/common/origin_util.h"
#include "content/public/common/url_constants.h"
#include "extensions/browser/extension_registry.h"
@@ -92,6 +103,17 @@ enum class AllSitesAction {
kMaxValue = kEnterSiteDetails,
};
+enum class AllSitesAction2 {
+ kLoadPage = 0,
+ kResetSiteGroupPermissions = 1,
+ kResetOriginPermissions = 2,
+ kClearAllData = 3,
+ kClearSiteGroupData = 4,
+ kClearOriginData = 5,
+ kEnterSiteDetails = 6,
+ kMaxValue = kEnterSiteDetails,
+};
+
// Return an appropriate API Permission ID for the given string name.
extensions::APIPermission::APIPermission::ID APIPermissionFromGroupName(
std::string type) {
@@ -142,32 +164,13 @@ void AddExceptionsGrantedByHostedApps(
}
}
-base::flat_set<web_app::AppId> GetInstalledApps(
+base::flat_set<std::string> GetInstalledAppOrigins(
Profile* profile,
- web_app::AppRegistrar& registrar) {
- auto apps = registrar.GetAppIds();
- base::flat_set<std::string> installed;
- for (auto app : apps) {
- base::Optional<GURL> scope = registrar.GetAppScope(app);
- if (scope.has_value())
- installed.insert(scope.value().GetOrigin().spec());
- }
- return installed;
-}
-
-// Whether |pattern| applies to a single origin.
-bool PatternAppliesToSingleOrigin(const ContentSettingPatternSource& pattern) {
- const GURL url(pattern.primary_pattern.ToString());
- // Default settings and other patterns apply to multiple origins.
- if (url::Origin::Create(url).opaque())
- return false;
- // Embedded content settings only when |url| is embedded in another origin, so
- // ignore non-wildcard secondary patterns that are different to the primary.
- if (pattern.primary_pattern != pattern.secondary_pattern &&
- pattern.secondary_pattern != ContentSettingsPattern::Wildcard()) {
- return false;
- }
- return true;
+ const web_app::AppRegistrar& registrar) {
+ base::flat_set<std::string> origins;
+ for (const web_app::AppId& app : registrar.GetAppIds())
+ origins.insert(registrar.GetAppScope(app).GetOrigin().spec());
+ return origins;
}
// Groups |url| into sets of eTLD+1s in |site_group_map|, assuming |url| is an
@@ -236,11 +239,11 @@ void ConvertSiteGroupMapToListValue(
const std::set<std::string>& origin_permission_set,
base::Value* list_value,
Profile* profile,
- web_app::AppRegistrar& registrar) {
+ const web_app::AppRegistrar& registrar) {
DCHECK_EQ(base::Value::Type::LIST, list_value->type());
DCHECK(profile);
- base::flat_set<web_app::AppId> installed_apps =
- GetInstalledApps(profile, registrar);
+ base::flat_set<std::string> installed_origins =
+ GetInstalledAppOrigins(profile, registrar);
SiteEngagementService* engagement_service =
SiteEngagementService::Get(profile);
for (const auto& entry : site_group_map) {
@@ -267,7 +270,7 @@ void ConvertSiteGroupMapToListValue(
origin_object.SetKey("usage", base::Value(0));
origin_object.SetKey(kNumCookies, base::Value(0));
- bool is_installed = installed_apps.contains(origin);
+ bool is_installed = installed_origins.contains(origin);
if (is_installed)
has_installed_pwa = true;
origin_object.SetKey(kIsInstalled, base::Value(is_installed));
@@ -327,8 +330,58 @@ void UpdateDataFromCookiesTree(
CreateOrAppendSiteGroupEntry(all_sites_map, origin);
}
-void LogAllSitesAction(AllSitesAction action) {
- UMA_HISTOGRAM_ENUMERATION("WebsiteSettings.AllSitesAction", action);
+void LogAllSitesAction(AllSitesAction2 action) {
+ UMA_HISTOGRAM_ENUMERATION("WebsiteSettings.AllSitesAction2", action);
+}
+
+int GetNumCookieExceptionsOfTypes(HostContentSettingsMap* map,
+ const std::set<ContentSetting> types) {
+ ContentSettingsForOneType output;
+ map->GetSettingsForOneType(ContentSettingsType::COOKIES, std::string(),
+ &output);
+ return std::count_if(
+ output.begin(), output.end(),
+ [types](const ContentSettingPatternSource setting) {
+ return types.count(
+ content_settings::ValueToContentSetting(&setting.setting_value));
+ });
+}
+
+std::string GetCookieSettingDescription(Profile* profile) {
+ HostContentSettingsMap* map =
+ HostContentSettingsMapFactory::GetForProfile(profile);
+ auto content_setting =
+ map->GetDefaultContentSetting(ContentSettingsType::COOKIES, nullptr);
+
+ bool block_third_party =
+ profile->GetPrefs()->GetBoolean(prefs::kBlockThirdPartyCookies);
+ auto control_mode = static_cast<content_settings::CookieControlsMode>(
+ profile->GetPrefs()->GetInteger(prefs::kCookieControlsMode));
+
+ // Determine what the effective cookie setting is. These conditions are not
+ // mutually exclusive and rely on ordering.
+ if (content_setting == ContentSetting::CONTENT_SETTING_BLOCK) {
+ return l10n_util::GetPluralStringFUTF8(
+ IDS_SETTINGS_SITE_SETTINGS_COOKIES_BLOCK,
+ GetNumCookieExceptionsOfTypes(
+ map, {ContentSetting::CONTENT_SETTING_ALLOW,
+ ContentSetting::CONTENT_SETTING_SESSION_ONLY}));
+ } else if (block_third_party) {
+ return l10n_util::GetStringUTF8(
+ IDS_SETTINGS_SITE_SETTINGS_COOKIES_BLOCK_THIRD_PARTY);
+ } else if (base::FeatureList::IsEnabled(
+ content_settings::kImprovedCookieControls) &&
+ control_mode ==
+ content_settings::CookieControlsMode::kIncognitoOnly) {
+ return l10n_util::GetStringUTF8(
+ IDS_SETTINGS_SITE_SETTINGS_COOKIES_BLOCK_THIRD_PARTY_INCOGNITO);
+ } else {
+ // We do not make a distinction between allow and clear on exit.
+ return l10n_util::GetPluralStringFUTF8(
+ IDS_SETTINGS_SITE_SETTINGS_COOKIES_ALLOW,
+ GetNumCookieExceptionsOfTypes(map,
+ {ContentSetting::CONTENT_SETTING_BLOCK}));
+ }
}
} // namespace
@@ -365,6 +418,20 @@ void SiteSettingsHandler::RegisterMessages() {
base::BindRepeating(&SiteSettingsHandler::HandleGetAllSites,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
+ "getCookieControlsManagedState",
+ base::BindRepeating(
+ &SiteSettingsHandler::HandleGetCookieControlsManagedState,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "getCookieSettingDescription",
+ base::BindRepeating(
+ &SiteSettingsHandler::HandleGetCookieSettingDescription,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "getRecentSitePermissions",
+ base::BindRepeating(&SiteSettingsHandler::HandleGetRecentSitePermissions,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
"getFormattedBytes",
base::BindRepeating(&SiteSettingsHandler::HandleGetFormattedBytes,
base::Unretained(this)));
@@ -454,8 +521,8 @@ void SiteSettingsHandler::OnJavascriptAllowed() {
host_zoom_map_subscription_ =
content::HostZoomMap::GetDefaultForBrowserContext(profile_)
->AddZoomLevelChangedCallback(
- base::Bind(&SiteSettingsHandler::OnZoomLevelChanged,
- base::Unretained(this)));
+ base::BindRepeating(&SiteSettingsHandler::OnZoomLevelChanged,
+ base::Unretained(this)));
pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>();
pref_change_registrar_->Init(profile_->GetPrefs());
@@ -466,6 +533,16 @@ void SiteSettingsHandler::OnJavascriptAllowed() {
base::Bind(&SiteSettingsHandler::SendBlockAutoplayStatus,
base::Unretained(this)));
+ // Listen for prefs that impact the effective cookie setting
+ pref_change_registrar_->Add(
+ prefs::kBlockThirdPartyCookies,
+ base::Bind(&SiteSettingsHandler::SendCookieSettingDescription,
+ base::Unretained(this)));
+ pref_change_registrar_->Add(
+ prefs::kCookieControlsMode,
+ base::Bind(&SiteSettingsHandler::SendCookieSettingDescription,
+ base::Unretained(this)));
+
#if defined(OS_CHROMEOS)
pref_change_registrar_->Add(
prefs::kEnableDRM,
@@ -479,6 +556,8 @@ void SiteSettingsHandler::OnJavascriptDisallowed() {
chooser_observer_.RemoveAll();
host_zoom_map_subscription_.reset();
pref_change_registrar_->Remove(prefs::kBlockAutoplayEnabled);
+ pref_change_registrar_->Remove(prefs::kBlockThirdPartyCookies);
+ pref_change_registrar_->Remove(prefs::kCookieControlsMode);
#if defined(OS_CHROMEOS)
pref_change_registrar_->Remove(prefs::kEnableDRM);
#endif
@@ -505,9 +584,8 @@ void SiteSettingsHandler::OnGetUsageInfo() {
}
break;
}
- CallJavascriptFunction("settings.WebsiteUsagePrivateApi.returnUsageTotal",
- base::Value(usage_host_), base::Value(usage_string),
- base::Value(cookie_string));
+ FireWebUIListener("usage-total-changed", base::Value(usage_host_),
+ base::Value(usage_string), base::Value(cookie_string));
}
#if defined(OS_CHROMEOS)
@@ -546,6 +624,12 @@ void SiteSettingsHandler::OnContentSettingChanged(
content_type == ContentSettingsType::SOUND) {
SendBlockAutoplayStatus();
}
+
+ // If the default cookie setting changed we should update the effective
+ // setting description.
+ if (content_type == ContentSettingsType::COOKIES) {
+ SendCookieSettingDescription();
+ }
}
void SiteSettingsHandler::OnOffTheRecordProfileCreated(
@@ -671,22 +755,14 @@ void SiteSettingsHandler::HandleGetDefaultValueForContentType(
void SiteSettingsHandler::HandleGetAllSites(const base::ListValue* args) {
AllowJavascript();
- CHECK_EQ(2U, args->GetSize());
- const base::Value* callback_id;
- CHECK(args->Get(0, &callback_id));
- const base::ListValue* types;
- CHECK(args->GetList(1, &types));
+ CHECK_EQ(2U, args->GetList().size());
+ std::string callback_id = args->GetList()[0].GetString();
+ auto types = args->GetList()[1].GetList();
all_sites_map_.clear();
origin_permission_set_.clear();
- // Convert |types| to a list of ContentSettingsTypes.
- std::vector<ContentSettingsType> content_types;
- for (size_t i = 0; i < types->GetSize(); ++i) {
- std::string type;
- types->GetString(i, &type);
- content_types.push_back(
- site_settings::ContentSettingsTypeFromGroupName(type));
- }
+
+ auto content_types = site_settings::ContentSettingsTypesFromGroupNames(types);
// Incognito contains incognito content settings plus non-incognito content
// settings. Thus if it exists, just get exceptions for the incognito profile.
@@ -701,38 +777,22 @@ void SiteSettingsHandler::HandleGetAllSites(const base::ListValue* args) {
// Retrieve a list of embargoed settings to check separately. This ensures
// that only settings included in |content_types| will be listed in all sites.
- ContentSettingsForOneType embargo_settings;
- map->GetSettingsForOneType(ContentSettingsType::PERMISSION_AUTOBLOCKER_DATA,
- std::string(), &embargo_settings);
- PermissionManager* permission_manager = PermissionManager::Get(profile);
- for (const ContentSettingPatternSource& e : embargo_settings) {
- for (ContentSettingsType content_type : content_types) {
- if (PermissionUtil::IsPermission(content_type)) {
- const GURL url(e.primary_pattern.ToString());
- // Add |url| to the set if there are any embargo settings.
- PermissionResult result =
- permission_manager->GetPermissionStatus(content_type, url, url);
- if (result.source == PermissionStatusSource::MULTIPLE_DISMISSALS ||
- result.source == PermissionStatusSource::MULTIPLE_IGNORES) {
- CreateOrAppendSiteGroupEntry(&all_sites_map_, url);
- origin_permission_set_.insert(url.spec());
- break;
- }
- }
- }
+ auto* autoblocker =
+ PermissionDecisionAutoBlockerFactory::GetForProfile(profile_);
+ for (auto& url : autoblocker->GetEmbargoedOrigins(content_types)) {
+ // Add |url| to the set if there are any embargo settings.
+ CreateOrAppendSiteGroupEntry(&all_sites_map_, url);
+ origin_permission_set_.insert(url.spec());
}
- // Convert |types| to a list of ContentSettingsTypes.
- for (ContentSettingsType content_type : content_types) {
- ContentSettingsForOneType entries;
- map->GetSettingsForOneType(content_type, std::string(), &entries);
- for (const ContentSettingPatternSource& e : entries) {
- if (PatternAppliesToSingleOrigin(e)) {
- CreateOrAppendSiteGroupEntry(&all_sites_map_,
- GURL(e.primary_pattern.ToString()));
- origin_permission_set_.insert(
- GURL(e.primary_pattern.ToString()).spec());
- }
+ // Get permission exceptions which apply to a single site
+ for (auto content_type : content_types) {
+ auto exceptions =
+ site_settings::GetSiteExceptionsForContentType(map, content_type);
+ for (const auto& e : exceptions) {
+ GURL url = GURL(e.primary_pattern.ToString());
+ CreateOrAppendSiteGroupEntry(&all_sites_map_, url);
+ origin_permission_set_.insert(url.spec());
}
}
@@ -750,11 +810,95 @@ void SiteSettingsHandler::HandleGetAllSites(const base::ListValue* args) {
ConvertSiteGroupMapToListValue(all_sites_map_, origin_permission_set_,
&result, profile, app_registrar_);
- LogAllSitesAction(AllSitesAction::kLoadPage);
+ LogAllSitesAction(AllSitesAction2::kLoadPage);
send_sites_list_ = true;
- ResolveJavascriptCallback(*callback_id, result);
+ ResolveJavascriptCallback(base::Value(callback_id), result);
+}
+
+void SiteSettingsHandler::HandleGetCookieControlsManagedState(
+ const base::ListValue* args) {
+ AllowJavascript();
+ CHECK_EQ(1U, args->GetList().size());
+ std::string callback_id = args->GetList()[0].GetString();
+
+ auto managed_states = site_settings::GetCookieControlsManagedState(profile_);
+
+ base::Value result(base::Value::Type::DICTIONARY);
+ result.SetKey(
+ site_settings::kAllowAll,
+ site_settings::GetValueForManagedState(managed_states.allow_all));
+ result.SetKey(site_settings::kBlockThirdPartyIncognito,
+ site_settings::GetValueForManagedState(
+ managed_states.block_third_party_incognito));
+ result.SetKey(
+ site_settings::kBlockThirdParty,
+ site_settings::GetValueForManagedState(managed_states.block_third_party));
+ result.SetKey(
+ site_settings::kBlockAll,
+ site_settings::GetValueForManagedState(managed_states.block_all));
+ result.SetKey(
+ site_settings::kSessionOnly,
+ site_settings::GetValueForManagedState(managed_states.session_only));
+
+ ResolveJavascriptCallback(base::Value(callback_id), result);
+}
+
+void SiteSettingsHandler::HandleGetCookieSettingDescription(
+ const base::ListValue* args) {
+ AllowJavascript();
+ CHECK_EQ(1U, args->GetList().size());
+ std::string callback_id = args->GetList()[0].GetString();
+ ResolveJavascriptCallback(base::Value(callback_id),
+ base::Value(GetCookieSettingDescription(profile_)));
+}
+
+void SiteSettingsHandler::HandleGetRecentSitePermissions(
+ const base::ListValue* args) {
+ AllowJavascript();
+
+ CHECK_EQ(3U, args->GetList().size());
+ std::string callback_id = args->GetList()[0].GetString();
+ auto types = args->GetList()[1].GetList();
+ size_t max_sources = base::checked_cast<size_t>(args->GetList()[2].GetInt());
+
+ auto content_types = site_settings::ContentSettingsTypesFromGroupNames(types);
+ auto recent_site_permissions = site_settings::GetRecentSitePermissions(
+ profile_, content_types, max_sources);
+
+ // Convert groups of TimestampedPermissions for consumption by JS
+ base::Value result(base::Value::Type::LIST);
+ for (const auto& site_permissions : recent_site_permissions) {
+ DCHECK(!site_permissions.settings.empty());
+ base::Value recent_site(base::Value::Type::DICTIONARY);
+ recent_site.SetKey(site_settings::kOrigin,
+ base::Value(site_permissions.origin.spec()));
+ recent_site.SetKey(site_settings::kIncognito,
+ base::Value(site_permissions.incognito));
+
+ base::Value permissions_list(base::Value::Type::LIST);
+ for (const auto& p : site_permissions.settings) {
+ base::Value recent_permission(base::Value::Type::DICTIONARY);
+ recent_permission.SetKey(
+ site_settings::kType,
+ base::Value(
+ site_settings::ContentSettingsTypeToGroupName(p.content_type)));
+ recent_permission.SetKey(
+ site_settings::kSetting,
+ base::Value(
+ content_settings::ContentSettingToString(p.content_setting)));
+ recent_permission.SetKey(
+ site_settings::kSource,
+ base::Value(
+ site_settings::SiteSettingSourceToString(p.setting_source)));
+ permissions_list.Append(std::move(recent_permission));
+ }
+ recent_site.SetKey(site_settings::kRecentPermissions,
+ std::move(permissions_list));
+ result.Append(std::move(recent_site));
+ }
+ ResolveJavascriptCallback(base::Value(callback_id), result);
}
base::Value SiteSettingsHandler::PopulateCookiesAndUsageData(Profile* profile) {
@@ -783,14 +927,16 @@ base::Value SiteSettingsHandler::PopulateCookiesAndUsageData(Profile* profile) {
const std::string& origin = origin_info.FindKey("origin")->GetString();
const auto& size_info_it = origin_size_map.find(origin);
if (size_info_it != origin_size_map.end())
- origin_info.SetKey("usage", base::Value(double(size_info_it->second)));
+ origin_info.SetKey(
+ "usage", base::Value(static_cast<double>(size_info_it->second)));
+ GURL origin_url(origin);
const auto& origin_cookie_num_it =
- origin_cookie_map.find(GURL(origin).host());
+ origin_cookie_map.find(origin_url.host());
if (origin_cookie_num_it != origin_cookie_map.end()) {
origin_info.SetKey(kNumCookies,
base::Value(origin_cookie_num_it->second));
// Add cookies numbers for origins that isn't an eTLD+1.
- if (GURL(origin).host() != etld_plus1)
+ if (origin_url.host() != etld_plus1)
cookie_num += origin_cookie_num_it->second;
}
}
@@ -946,13 +1092,14 @@ void SiteSettingsHandler::HandleSetOriginPermissions(
HostContentSettingsMap* map =
HostContentSettingsMapFactory::GetForProfile(profile_);
- PermissionUtil::ScopedRevocationReporter scoped_revocation_reporter(
- profile_, origin, origin, content_type,
- PermissionSourceUI::SITE_SETTINGS);
+ permissions::PermissionUmaUtil::ScopedRevocationReporter
+ scoped_revocation_reporter(
+ profile_, origin, origin, content_type,
+ permissions::PermissionSourceUI::SITE_SETTINGS);
// Clear any existing embargo status if the new setting isn't block.
if (setting != CONTENT_SETTING_BLOCK) {
- PermissionDecisionAutoBlocker::GetForProfile(profile_)
+ PermissionDecisionAutoBlockerFactory::GetForProfile(profile_)
->RemoveEmbargoByUrl(origin, content_type);
}
map->SetContentSettingDefaultScope(origin, origin, content_type,
@@ -971,7 +1118,7 @@ void SiteSettingsHandler::HandleSetOriginPermissions(
"SoundContentSetting.UnmuteBy.SiteSettings"));
}
}
- WebSiteSettingsUmaUtil::LogPermissionChange(content_type, setting);
+ content_settings::LogWebSiteSettingsPermissionChange(content_type, setting);
}
// Show an infobar reminding the user to reload tabs where their site
@@ -1036,9 +1183,10 @@ void SiteSettingsHandler::HandleResetCategoryPermissionForPattern(
secondary_pattern_string.empty()
? ContentSettingsPattern::Wildcard()
: ContentSettingsPattern::FromString(secondary_pattern_string);
- PermissionUtil::ScopedRevocationReporter scoped_revocation_reporter(
- profile, primary_pattern, secondary_pattern, content_type,
- PermissionSourceUI::SITE_SETTINGS);
+ permissions::PermissionUmaUtil::ScopedRevocationReporter
+ scoped_revocation_reporter(
+ profile, primary_pattern, secondary_pattern, content_type,
+ permissions::PermissionSourceUI::SITE_SETTINGS);
map->SetContentSettingCustomScope(primary_pattern, secondary_pattern,
content_type, "", CONTENT_SETTING_DEFAULT);
@@ -1054,7 +1202,7 @@ void SiteSettingsHandler::HandleResetCategoryPermissionForPattern(
"SoundContentSetting.UnmuteBy.PatternException"));
}
}
- WebSiteSettingsUmaUtil::LogPermissionChange(
+ content_settings::LogWebSiteSettingsPermissionChange(
content_type, ContentSetting::CONTENT_SETTING_DEFAULT);
}
@@ -1096,9 +1244,10 @@ void SiteSettingsHandler::HandleSetCategoryPermissionForPattern(
? ContentSettingsPattern::Wildcard()
: ContentSettingsPattern::FromString(secondary_pattern_string);
- PermissionUtil::ScopedRevocationReporter scoped_revocation_reporter(
- profile, primary_pattern, secondary_pattern, content_type,
- PermissionSourceUI::SITE_SETTINGS);
+ permissions::PermissionUmaUtil::ScopedRevocationReporter
+ scoped_revocation_reporter(
+ profile, primary_pattern, secondary_pattern, content_type,
+ permissions::PermissionSourceUI::SITE_SETTINGS);
map->SetContentSettingCustomScope(primary_pattern, secondary_pattern,
content_type, "", setting);
@@ -1117,7 +1266,7 @@ void SiteSettingsHandler::HandleSetCategoryPermissionForPattern(
"SoundContentSetting.UnmuteBy.PatternException"));
}
}
- WebSiteSettingsUmaUtil::LogPermissionChange(content_type, setting);
+ content_settings::LogWebSiteSettingsPermissionChange(content_type, setting);
}
void SiteSettingsHandler::HandleResetChooserExceptionForSite(
@@ -1140,7 +1289,8 @@ void SiteSettingsHandler::HandleResetChooserExceptionForSite(
GURL embedding_origin(embedding_origin_str);
CHECK(embedding_origin.is_valid());
- ChooserContextBase* chooser_context = chooser_type->get_context(profile_);
+ permissions::ChooserContextBase* chooser_context =
+ chooser_type->get_context(profile_);
chooser_context->RevokeObjectPermission(
url::Origin::Create(requesting_origin),
url::Origin::Create(embedding_origin), args->GetList()[3]);
@@ -1352,6 +1502,18 @@ void SiteSettingsHandler::ObserveSourcesForProfile(Profile* profile) {
if (!chooser_observer_.IsObserving(serial_context))
chooser_observer_.Add(serial_context);
+ auto* hid_context = HidChooserContextFactory::GetForProfile(profile);
+ if (!chooser_observer_.IsObserving(hid_context))
+ chooser_observer_.Add(hid_context);
+
+ if (base::FeatureList::IsEnabled(
+ features::kWebBluetoothNewPermissionsBackend)) {
+ auto* bluetooth_context =
+ BluetoothChooserContextFactory::GetForProfile(profile);
+ if (!chooser_observer_.IsObserving(bluetooth_context))
+ chooser_observer_.Add(bluetooth_context);
+ }
+
observed_profiles_.Add(profile);
}
@@ -1368,6 +1530,18 @@ void SiteSettingsHandler::StopObservingSourcesForProfile(Profile* profile) {
if (chooser_observer_.IsObserving(serial_context))
chooser_observer_.Remove(serial_context);
+ auto* hid_context = HidChooserContextFactory::GetForProfile(profile);
+ if (chooser_observer_.IsObserving(hid_context))
+ chooser_observer_.Remove(hid_context);
+
+ if (base::FeatureList::IsEnabled(
+ features::kWebBluetoothNewPermissionsBackend)) {
+ auto* bluetooth_context =
+ BluetoothChooserContextFactory::GetForProfile(profile);
+ if (chooser_observer_.IsObserving(bluetooth_context))
+ chooser_observer_.Remove(bluetooth_context);
+ }
+
observed_profiles_.Remove(profile);
}
@@ -1444,18 +1618,16 @@ void SiteSettingsHandler::HandleClearEtldPlus1DataAndCookies(
}
for (auto* node : nodes_to_delete)
cookies_tree_model_->DeleteCookieNode(node);
-
- LogAllSitesAction(AllSitesAction::kClearData);
}
void SiteSettingsHandler::HandleRecordAction(const base::ListValue* args) {
CHECK_EQ(1U, args->GetSize());
int action;
CHECK(args->GetInteger(0, &action));
- DCHECK_LE(action, static_cast<int>(AllSitesAction::kMaxValue));
- DCHECK_GE(action, static_cast<int>(AllSitesAction::kLoadPage));
+ DCHECK_LE(action, static_cast<int>(AllSitesAction2::kMaxValue));
+ DCHECK_GE(action, static_cast<int>(AllSitesAction2::kLoadPage));
- LogAllSitesAction(static_cast<AllSitesAction>(action));
+ LogAllSitesAction(static_cast<AllSitesAction2>(action));
}
void SiteSettingsHandler::SetCookiesTreeModelForTesting(
@@ -1466,4 +1638,10 @@ void SiteSettingsHandler::SetCookiesTreeModelForTesting(
void SiteSettingsHandler::ClearAllSitesMapForTesting() {
all_sites_map_.clear();
}
+
+void SiteSettingsHandler::SendCookieSettingDescription() {
+ FireWebUIListener("cookieSettingDescriptionChanged",
+ base::Value(GetCookieSettingDescription(profile_)));
+}
+
} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/site_settings_handler.h b/chromium/chrome/browser/ui/webui/settings/site_settings_handler.h
index b60de36fcc2..575661dc87e 100644
--- a/chromium/chrome/browser/ui/webui/settings/site_settings_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/site_settings_handler.h
@@ -13,7 +13,6 @@
#include "base/containers/flat_set.h"
#include "base/scoped_observer.h"
#include "chrome/browser/browsing_data/cookies_tree_model.h"
-#include "chrome/browser/permissions/chooser_context_base.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_observer.h"
#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
@@ -21,6 +20,8 @@
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "components/content_settings/core/browser/content_settings_observer.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
+#include "components/permissions/chooser_context_base.h"
+#include "components/prefs/pref_store.h"
#include "content/public/browser/host_zoom_map.h"
#include "ppapi/buildflags/buildflags.h"
@@ -33,11 +34,12 @@ class ListValue;
namespace settings {
// Chrome "ContentSettings" settings page UI handler.
-class SiteSettingsHandler : public SettingsPageUIHandler,
- public content_settings::Observer,
- public ProfileObserver,
- public ChooserContextBase::PermissionObserver,
- public CookiesTreeModel::Observer {
+class SiteSettingsHandler
+ : public SettingsPageUIHandler,
+ public content_settings::Observer,
+ public ProfileObserver,
+ public permissions::ChooserContextBase::PermissionObserver,
+ public CookiesTreeModel::Observer {
public:
explicit SiteSettingsHandler(Profile* profile,
web_app::AppRegistrar& web_app_registrar);
@@ -110,6 +112,7 @@ class SiteSettingsHandler : public SettingsPageUIHandler,
FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, ExceptionHelpers);
FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, ExtensionDisplayName);
FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, GetAllSites);
+ FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, GetRecentSitePermissions);
FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, OnStorageFetched);
FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, GetAndSetDefault);
FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, GetAndSetForInvalidURLs);
@@ -122,6 +125,8 @@ class SiteSettingsHandler : public SettingsPageUIHandler,
FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, ZoomLevels);
FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest,
HandleClearEtldPlus1DataAndCookies);
+ FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, CookieControlsManagedState);
+ FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, CookieSettingDescription);
FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, HandleGetFormattedBytes);
FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest,
NotificationPermissionRevokeUkm);
@@ -163,6 +168,20 @@ class SiteSettingsHandler : public SettingsPageUIHandler,
// the front end when fetching finished.
void HandleGetAllSites(const base::ListValue* args);
+ // Returns whether each of the cookie controls is managed and if so what
+ // the source of that management is.
+ void HandleGetCookieControlsManagedState(const base::ListValue* args);
+
+ // Returns a string for display describing the current cookie settings.
+ void HandleGetCookieSettingDescription(const base::ListValue* args);
+
+ // Returns a list containing the most recent permission changes for the
+ // provided content types grouped by origin/profile (incognito, regular)
+ // combinations, limited to N origin/profile pairings. This includes
+ // permission changes made by embargo, but does not include permissions
+ // enforced via policy.
+ void HandleGetRecentSitePermissions(const base::ListValue* args);
+
// Called when the list of origins using storage has been fetched, and sends
// this list back to the front end.
void OnStorageFetched();
@@ -240,6 +259,10 @@ class SiteSettingsHandler : public SettingsPageUIHandler,
void ClearAllSitesMapForTesting();
+ // Notifies the JS side the effective cookies setting has changed and
+ // provides the updated description label for display.
+ void SendCookieSettingDescription();
+
Profile* profile_;
web_app::AppRegistrar& app_registrar_;
@@ -260,7 +283,8 @@ class SiteSettingsHandler : public SettingsPageUIHandler,
this};
// Change observer for chooser permissions.
- ScopedObserver<ChooserContextBase, ChooserContextBase::PermissionObserver>
+ ScopedObserver<permissions::ChooserContextBase,
+ permissions::ChooserContextBase::PermissionObserver>
chooser_observer_{this};
// Change observer for prefs.
diff --git a/chromium/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc
index 42c7a310795..0fd6541604d 100644
--- a/chromium/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc
@@ -15,6 +15,7 @@
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/metrics/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_clock.h"
#include "base/values.h"
#include "build/build_config.h"
@@ -26,10 +27,7 @@
#include "chrome/browser/extensions/test_extension_system.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/infobars/infobar_service.h"
-#include "chrome/browser/permissions/chooser_context_base.h"
-#include "chrome/browser/permissions/chooser_context_base_mock_permission_observer.h"
-#include "chrome/browser/permissions/permission_decision_auto_blocker.h"
-#include "chrome/browser/permissions/permission_uma_util.h"
+#include "chrome/browser/permissions/permission_decision_auto_blocker_factory.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/webui/site_settings_helper.h"
@@ -38,14 +36,23 @@
#include "chrome/browser/web_applications/components/web_app_helpers.h"
#include "chrome/browser/web_applications/test/test_app_registrar.h"
#include "chrome/common/pref_names.h"
+#include "chrome/grit/generated_resources.h"
#include "chrome/test/base/browser_with_test_window_test.h"
#include "chrome/test/base/testing_profile.h"
+#include "components/content_settings/core/browser/cookie_settings.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/content_settings/core/common/content_settings_types.h"
+#include "components/content_settings/core/common/features.h"
#include "components/content_settings/core/common/pref_names.h"
+#include "components/content_settings/core/test/content_settings_mock_provider.h"
+#include "components/content_settings/core/test/content_settings_test_utils.h"
#include "components/history/core/browser/history_service.h"
#include "components/infobars/core/infobar.h"
+#include "components/permissions/chooser_context_base.h"
+#include "components/permissions/permission_decision_auto_blocker.h"
+#include "components/permissions/permission_uma_util.h"
+#include "components/permissions/test/chooser_context_base_mock_permission_observer.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/public/browser/navigation_controller.h"
@@ -58,6 +65,7 @@
#include "ppapi/buildflags/buildflags.h"
#include "services/device/public/cpp/test/fake_usb_device_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/l10n/l10n_util.h"
#include "ui/base/text/bytes_formatting.h"
#if defined(OS_CHROMEOS)
@@ -190,6 +198,8 @@ class SiteSettingsHandlerTest : public testing::Test {
TestingProfile::Builder profile_builder;
profile_builder.SetPath(profile_dir_.GetPath());
profile_ = profile_builder.Build();
+ feature_list_.InitAndEnableFeature(
+ content_settings::kImprovedCookieControls);
}
void SetUp() override {
@@ -399,6 +409,16 @@ class SiteSettingsHandlerTest : public testing::Test {
}
}
+ void ValidateCookieSettingUpdate(const std::string expected_string,
+ const int expected_call_index) {
+ const content::TestWebUI::CallData& data =
+ *web_ui()->call_data()[expected_call_index];
+
+ ASSERT_EQ("cr.webUIListenerCallback", data.function_name());
+ ASSERT_EQ("cookieSettingDescriptionChanged", data.arg1()->GetString());
+ ASSERT_EQ(expected_string, data.arg2()->GetString());
+ }
+
void CreateIncognitoProfile() {
incognito_profile_ = TestingProfile::Builder().BuildIncognito(profile());
}
@@ -479,6 +499,10 @@ class SiteSettingsHandlerTest : public testing::Test {
const std::string kCookies;
const std::string kFlash;
+ // The number of listeners that are expected to fire when any content setting
+ // is changed.
+ const size_t kNumberContentSettingListeners = 2;
+
private:
// A profile directory that outlives |task_environment_| is needed because
// TestingProfile::CreateHistoryService uses the directory to host a
@@ -490,6 +514,7 @@ class SiteSettingsHandlerTest : public testing::Test {
web_app::TestAppRegistrar app_registrar_;
content::TestWebUI web_ui_;
std::unique_ptr<SiteSettingsHandler> handler_;
+ base::test::ScopedFeatureList feature_list_;
#if defined(OS_CHROMEOS)
std::unique_ptr<user_manager::ScopedUserManager> user_manager_enabler_;
#endif
@@ -611,8 +636,8 @@ TEST_F(SiteSettingsHandlerTest, MAYBE_GetAllSites) {
}
// Test embargoed settings also appear.
- PermissionDecisionAutoBlocker* auto_blocker =
- PermissionDecisionAutoBlocker::GetForProfile(profile());
+ permissions::PermissionDecisionAutoBlocker* auto_blocker =
+ PermissionDecisionAutoBlockerFactory::GetForProfile(profile());
base::SimpleTestClock clock;
clock.SetNow(base::Time::Now());
auto_blocker->SetClockForTesting(&clock);
@@ -712,12 +737,137 @@ TEST_F(SiteSettingsHandlerTest, MAYBE_GetAllSites) {
}
// Each call to HandleGetAllSites() above added a callback to the profile's
- // BrowsingDataLocalStorageHelper, so make sure these aren't stuck waiting to
- // run at the end of the test.
+ // browsing_data::LocalStorageHelper, so make sure these aren't stuck waiting
+ // to run at the end of the test.
base::RunLoop run_loop;
run_loop.RunUntilIdle();
}
+TEST_F(SiteSettingsHandlerTest, GetRecentSitePermissions) {
+ // Constants used only in this test.
+ std::string kAllowed = content_settings::ContentSettingToString(
+ ContentSetting::CONTENT_SETTING_ALLOW);
+ std::string kBlocked = content_settings::ContentSettingToString(
+ ContentSetting::CONTENT_SETTING_BLOCK);
+ std::string kEmbargo =
+ SiteSettingSourceToString(site_settings::SiteSettingSource::kEmbargo);
+ std::string kPreference =
+ SiteSettingSourceToString(site_settings::SiteSettingSource::kPreference);
+
+ base::ListValue get_recent_permissions_args;
+ get_recent_permissions_args.AppendString(kCallbackId);
+ base::Value category_list(base::Value::Type::LIST);
+ category_list.Append(kNotifications);
+ category_list.Append(kFlash);
+ get_recent_permissions_args.Append(std::move(category_list));
+ get_recent_permissions_args.Append(3);
+
+ // Configure prefs and auto blocker with a controllable clock.
+ base::SimpleTestClock clock;
+ clock.SetNow(base::Time::Now());
+ HostContentSettingsMap* map =
+ HostContentSettingsMapFactory::GetForProfile(profile());
+ map->SetClockForTesting(&clock);
+ permissions::PermissionDecisionAutoBlocker* auto_blocker =
+ PermissionDecisionAutoBlockerFactory::GetForProfile(profile());
+ auto_blocker->SetClockForTesting(&clock);
+ clock.Advance(base::TimeDelta::FromHours(1));
+
+ // Test recent permissions is empty when there are no preferences.
+ handler()->HandleGetRecentSitePermissions(&get_recent_permissions_args);
+ EXPECT_EQ(1U, web_ui()->call_data().size());
+
+ {
+ const content::TestWebUI::CallData& data = *web_ui()->call_data().back();
+ EXPECT_EQ("cr.webUIResponse", data.function_name());
+ EXPECT_EQ(kCallbackId, data.arg1()->GetString());
+ ASSERT_TRUE(data.arg2()->GetBool());
+
+ base::Value::ConstListView recent_permissions = data.arg3()->GetList();
+ EXPECT_EQ(0UL, recent_permissions.size());
+ }
+
+ // Add numerous permissions from different sources and confirm that the recent
+ // permissions are correctly transformed for usage by JS.
+ const GURL url1("https://example.com");
+ const GURL url2("http://example.com");
+ for (int i = 0; i < 3; ++i)
+ auto_blocker->RecordDismissAndEmbargo(
+ url1, ContentSettingsType::NOTIFICATIONS, false);
+
+ clock.Advance(base::TimeDelta::FromHours(2));
+ map->SetContentSettingDefaultScope(url2, url2, ContentSettingsType::PLUGINS,
+ std::string(), CONTENT_SETTING_ALLOW);
+ clock.Advance(base::TimeDelta::FromHours(1));
+ CreateIncognitoProfile();
+ HostContentSettingsMap* incognito_map =
+ HostContentSettingsMapFactory::GetForProfile(incognito_profile());
+ incognito_map->SetClockForTesting(&clock);
+ incognito_map->SetContentSettingDefaultScope(
+ url1, url1, ContentSettingsType::PLUGINS, std::string(),
+ CONTENT_SETTING_ALLOW);
+
+ clock.Advance(base::TimeDelta::FromHours(1));
+ permissions::PermissionDecisionAutoBlocker* incognito_auto_blocker =
+ PermissionDecisionAutoBlockerFactory::GetForProfile(incognito_profile());
+ incognito_auto_blocker->SetClockForTesting(&clock);
+ for (int i = 0; i < 3; ++i)
+ incognito_auto_blocker->RecordDismissAndEmbargo(
+ url1, ContentSettingsType::NOTIFICATIONS, false);
+
+ handler()->HandleGetRecentSitePermissions(&get_recent_permissions_args);
+ {
+ const content::TestWebUI::CallData& data = *web_ui()->call_data().back();
+ EXPECT_EQ("cr.webUIResponse", data.function_name());
+ EXPECT_EQ(kCallbackId, data.arg1()->GetString());
+ ASSERT_TRUE(data.arg2()->GetBool());
+
+ base::Value::ConstListView recent_permissions = data.arg3()->GetList();
+ EXPECT_EQ(3UL, recent_permissions.size());
+ EXPECT_EQ(url1.spec(),
+ recent_permissions[2].FindKey("origin")->GetString());
+ EXPECT_EQ(url2.spec(),
+ recent_permissions[1].FindKey("origin")->GetString());
+ EXPECT_EQ(url1.spec(),
+ recent_permissions[0].FindKey("origin")->GetString());
+
+ EXPECT_TRUE(recent_permissions[0].FindKey("incognito")->GetBool());
+ EXPECT_FALSE(recent_permissions[1].FindKey("incognito")->GetBool());
+ EXPECT_FALSE(recent_permissions[2].FindKey("incognito")->GetBool());
+
+ base::Value::ConstListView incognito_url1_permissions =
+ recent_permissions[0].FindKey("recentPermissions")->GetList();
+ base::Value::ConstListView url1_permissions =
+ recent_permissions[2].FindKey("recentPermissions")->GetList();
+ base::Value::ConstListView url2_permissions =
+ recent_permissions[1].FindKey("recentPermissions")->GetList();
+
+ EXPECT_EQ(2UL, incognito_url1_permissions.size());
+
+ EXPECT_EQ(kNotifications,
+ incognito_url1_permissions[0].FindKey("type")->GetString());
+ EXPECT_EQ(kBlocked,
+ incognito_url1_permissions[0].FindKey("setting")->GetString());
+ EXPECT_EQ(kEmbargo,
+ incognito_url1_permissions[0].FindKey("source")->GetString());
+
+ EXPECT_EQ(kFlash,
+ incognito_url1_permissions[1].FindKey("type")->GetString());
+ EXPECT_EQ(kAllowed,
+ incognito_url1_permissions[1].FindKey("setting")->GetString());
+ EXPECT_EQ(kPreference,
+ incognito_url1_permissions[1].FindKey("source")->GetString());
+
+ EXPECT_EQ(kNotifications, url1_permissions[0].FindKey("type")->GetString());
+ EXPECT_EQ(kBlocked, url1_permissions[0].FindKey("setting")->GetString());
+ EXPECT_EQ(kEmbargo, url1_permissions[0].FindKey("source")->GetString());
+
+ EXPECT_EQ(kFlash, url2_permissions[0].FindKey("type")->GetString());
+ EXPECT_EQ(kAllowed, url2_permissions[0].FindKey("setting")->GetString());
+ EXPECT_EQ(kPreference, url2_permissions[0].FindKey("source")->GetString());
+ }
+}
+
TEST_F(SiteSettingsHandlerTest, OnStorageFetched) {
SetUpCookiesTreeModel();
@@ -942,12 +1092,13 @@ TEST_F(SiteSettingsHandlerTest, NotificationPermissionRevokeUkm) {
auto* entry = entries.front();
ukm_recorder.ExpectEntrySourceHasUrl(entry, GURL(google));
- EXPECT_EQ(*ukm_recorder.GetEntryMetric(entry, "Source"),
- static_cast<int64_t>(PermissionSourceUI::SITE_SETTINGS));
+ EXPECT_EQ(
+ *ukm_recorder.GetEntryMetric(entry, "Source"),
+ static_cast<int64_t>(permissions::PermissionSourceUI::SITE_SETTINGS));
EXPECT_EQ(*ukm_recorder.GetEntryMetric(entry, "PermissionType"),
static_cast<int64_t>(ContentSettingsType::NOTIFICATIONS));
EXPECT_EQ(*ukm_recorder.GetEntryMetric(entry, "Action"),
- static_cast<int64_t>(PermissionAction::REVOKED));
+ static_cast<int64_t>(permissions::PermissionAction::REVOKED));
}
TEST_F(SiteSettingsHandlerTest, DefaultSettingSource) {
@@ -956,6 +1107,8 @@ TEST_F(SiteSettingsHandlerTest, DefaultSettingSource) {
// Use a non-default port to verify the display name does not strip this off.
const std::string google("https://www.google.com:183");
+ const std::string expected_display_name("www.google.com:183");
+
ContentSettingSourceSetter source_setter(profile(),
ContentSettingsType::NOTIFICATIONS);
@@ -968,7 +1121,7 @@ TEST_F(SiteSettingsHandlerTest, DefaultSettingSource) {
// Test Chrome built-in defaults are marked as default.
handler()->HandleGetOriginPermissions(&get_origin_permissions_args);
- ValidateOrigin(google, google, google, CONTENT_SETTING_ASK,
+ ValidateOrigin(google, google, expected_display_name, CONTENT_SETTING_ASK,
site_settings::SiteSettingSource::kDefault, 1U);
base::ListValue default_value_args;
@@ -978,7 +1131,7 @@ TEST_F(SiteSettingsHandlerTest, DefaultSettingSource) {
handler()->HandleSetDefaultValueForContentType(&default_value_args);
// A user-set global default should also show up as default.
handler()->HandleGetOriginPermissions(&get_origin_permissions_args);
- ValidateOrigin(google, google, google, CONTENT_SETTING_BLOCK,
+ ValidateOrigin(google, google, expected_display_name, CONTENT_SETTING_BLOCK,
site_settings::SiteSettingSource::kDefault, 3U);
base::ListValue set_notification_pattern_args;
@@ -992,7 +1145,7 @@ TEST_F(SiteSettingsHandlerTest, DefaultSettingSource) {
&set_notification_pattern_args);
// A user-set pattern should not show up as default.
handler()->HandleGetOriginPermissions(&get_origin_permissions_args);
- ValidateOrigin(google, google, google, CONTENT_SETTING_ALLOW,
+ ValidateOrigin(google, google, expected_display_name, CONTENT_SETTING_ALLOW,
site_settings::SiteSettingSource::kPreference, 5U);
base::ListValue set_notification_origin_args;
@@ -1006,20 +1159,20 @@ TEST_F(SiteSettingsHandlerTest, DefaultSettingSource) {
&set_notification_origin_args);
// A user-set per-origin permission should not show up as default.
handler()->HandleGetOriginPermissions(&get_origin_permissions_args);
- ValidateOrigin(google, google, google, CONTENT_SETTING_BLOCK,
+ ValidateOrigin(google, google, expected_display_name, CONTENT_SETTING_BLOCK,
site_settings::SiteSettingSource::kPreference, 7U);
// Enterprise-policy set defaults should not show up as default.
source_setter.SetPolicyDefault(CONTENT_SETTING_ALLOW);
handler()->HandleGetOriginPermissions(&get_origin_permissions_args);
- ValidateOrigin(google, google, google, CONTENT_SETTING_ALLOW,
+ ValidateOrigin(google, google, expected_display_name, CONTENT_SETTING_ALLOW,
site_settings::SiteSettingSource::kPolicy, 8U);
}
TEST_F(SiteSettingsHandlerTest, GetAndSetOriginPermissions) {
const std::string origin_with_port("https://www.example.com:443");
// The display name won't show the port if it's default for that scheme.
- const std::string origin("https://www.example.com");
+ const std::string origin("www.example.com");
base::ListValue get_args;
get_args.AppendString(kCallbackId);
get_args.AppendString(origin_with_port);
@@ -1511,7 +1664,8 @@ TEST_F(SiteSettingsHandlerTest, SessionOnlyException) {
set_args.AppendBoolean(false); // Incognito.
base::HistogramTester histograms;
handler()->HandleSetCategoryPermissionForPattern(&set_args);
- EXPECT_EQ(1U, web_ui()->call_data().size());
+
+ EXPECT_EQ(kNumberContentSettingListeners, web_ui()->call_data().size());
histograms.ExpectTotalCount(uma_base, 1);
histograms.ExpectTotalCount(uma_base + ".SessionOnly", 1);
}
@@ -1564,10 +1718,6 @@ TEST_F(SiteSettingsHandlerTest, BlockAutoplay_Update) {
namespace {
-const GURL kAndroidUrl("https://android.com");
-const GURL kChromiumUrl("https://chromium.org");
-const GURL kGoogleUrl("https://google.com");
-
constexpr char kUsbPolicySetting[] = R"(
[
{
@@ -1585,6 +1735,18 @@ constexpr char kUsbPolicySetting[] = R"(
}
])";
+// TODO(https://crbug.com/1042727): Fix test GURL scoping and remove this getter
+// function.
+GURL AndroidUrl() {
+ return GURL("https://android.com");
+}
+GURL ChromiumUrl() {
+ return GURL("https://chromium.org");
+}
+GURL GoogleUrl() {
+ return GURL("https://google.com");
+}
+
} // namespace
class SiteSettingsHandlerChooserExceptionTest : public SiteSettingsHandlerTest {
@@ -1601,7 +1763,8 @@ class SiteSettingsHandlerChooserExceptionTest : public SiteSettingsHandlerTest {
void TearDown() override {
auto* chooser_context = UsbChooserContextFactory::GetForProfile(profile());
- chooser_context->ChooserContextBase::RemoveObserver(&observer_);
+ chooser_context->permissions::ChooserContextBase::RemoveObserver(
+ &observer_);
}
// Sets up the UsbChooserContext with two devices and permissions for these
@@ -1627,9 +1790,9 @@ class SiteSettingsHandlerChooserExceptionTest : public SiteSettingsHandlerTest {
base::DoNothing::Once<std::vector<device::mojom::UsbDeviceInfoPtr>>());
base::RunLoop().RunUntilIdle();
- const auto kAndroidOrigin = url::Origin::Create(kAndroidUrl);
- const auto kChromiumOrigin = url::Origin::Create(kChromiumUrl);
- const auto kGoogleOrigin = url::Origin::Create(kGoogleUrl);
+ const auto kAndroidOrigin = url::Origin::Create(AndroidUrl());
+ const auto kChromiumOrigin = url::Origin::Create(ChromiumUrl());
+ const auto kGoogleOrigin = url::Origin::Create(GoogleUrl());
// Add the user granted permissions for testing.
// These two persistent device permissions should be lumped together with
@@ -1652,7 +1815,7 @@ class SiteSettingsHandlerChooserExceptionTest : public SiteSettingsHandlerTest {
*policy_value);
// Add the observer for permission changes.
- chooser_context->ChooserContextBase::AddObserver(&observer_);
+ chooser_context->permissions::ChooserContextBase::AddObserver(&observer_);
}
void SetUpOffTheRecordUsbChooserContext() {
@@ -1670,19 +1833,20 @@ class SiteSettingsHandlerChooserExceptionTest : public SiteSettingsHandlerTest {
base::DoNothing::Once<std::vector<device::mojom::UsbDeviceInfoPtr>>());
base::RunLoop().RunUntilIdle();
- const auto kAndroidOrigin = url::Origin::Create(kAndroidUrl);
- const auto kChromiumOrigin = url::Origin::Create(kChromiumUrl);
+ const auto kAndroidOrigin = url::Origin::Create(AndroidUrl());
+ const auto kChromiumOrigin = url::Origin::Create(ChromiumUrl());
chooser_context->GrantDevicePermission(kChromiumOrigin, kAndroidOrigin,
*off_the_record_device_);
// Add the observer for permission changes.
- chooser_context->ChooserContextBase::AddObserver(&observer_);
+ chooser_context->permissions::ChooserContextBase::AddObserver(&observer_);
}
void DestroyIncognitoProfile() override {
auto* chooser_context =
UsbChooserContextFactory::GetForProfile(incognito_profile());
- chooser_context->ChooserContextBase::RemoveObserver(&observer_);
+ chooser_context->permissions::ChooserContextBase::RemoveObserver(
+ &observer_);
SiteSettingsHandlerTest::DestroyIncognitoProfile();
}
@@ -1778,7 +1942,7 @@ class SiteSettingsHandlerChooserExceptionTest : public SiteSettingsHandlerTest {
device::mojom::UsbDeviceInfoPtr persistent_device_info_;
device::mojom::UsbDeviceInfoPtr user_granted_device_info_;
- MockPermissionObserver observer_;
+ permissions::MockPermissionObserver observer_;
private:
device::FakeUsbDeviceManager device_manager_;
@@ -1836,10 +2000,10 @@ TEST_F(SiteSettingsHandlerChooserExceptionTest,
const std::string kUsbChooserGroupName =
site_settings::ContentSettingsTypeToGroupName(
ContentSettingsType::USB_CHOOSER_DATA);
- const auto kAndroidOrigin = url::Origin::Create(kAndroidUrl);
- const auto kChromiumOrigin = url::Origin::Create(kChromiumUrl);
- const std::string kAndroidOriginStr = kAndroidUrl.GetOrigin().spec();
- const std::string kChromiumOriginStr = kChromiumUrl.GetOrigin().spec();
+ const auto kAndroidOrigin = url::Origin::Create(AndroidUrl());
+ const auto kChromiumOrigin = url::Origin::Create(ChromiumUrl());
+ const std::string kAndroidOriginStr = AndroidUrl().GetOrigin().spec();
+ const std::string kChromiumOriginStr = ChromiumUrl().GetOrigin().spec();
{
const base::Value& exceptions = GetChooserExceptionListFromWebUiCallData(
@@ -2013,6 +2177,158 @@ TEST_F(SiteSettingsHandlerTest, HandleClearEtldPlus1DataAndCookies) {
EXPECT_EQ(0U, storage_and_cookie_list->GetSize());
}
+TEST_F(SiteSettingsHandlerTest, CookieControlsManagedState) {
+ // Test that the handler correctly wraps the helper result. Helper with
+ // extensive logic is tested in site_settings_helper_unittest.cc.
+ const std::string kNone = "none";
+ const std::string kDevicePolicy = "devicePolicy";
+ const std::vector<std::string> kControlNames = {
+ "allowAll", "blockAll", "blockThirdParty", "blockThirdPartyIncognito",
+ "sessionOnly"};
+
+ // Check that the default cookie control state is handled correctly.
+ base::ListValue get_args;
+ get_args.AppendString(kCallbackId);
+ handler()->HandleGetCookieControlsManagedState(&get_args);
+ {
+ const content::TestWebUI::CallData& data = *web_ui()->call_data().back();
+ EXPECT_EQ("cr.webUIResponse", data.function_name());
+ EXPECT_EQ(kCallbackId, data.arg1()->GetString());
+ ASSERT_TRUE(data.arg2()->GetBool());
+ for (const auto& control_name : kControlNames) {
+ auto* control_state = data.arg3()->FindPath(control_name);
+ ASSERT_FALSE(control_state->FindKey("disabled")->GetBool());
+ ASSERT_EQ(kNone, control_state->FindKey("indicator")->GetString());
+ }
+ }
+
+ // Check that a fully managed cookie state is handled correctly.
+ HostContentSettingsMap* map =
+ HostContentSettingsMapFactory::GetForProfile(profile());
+ auto provider = std::make_unique<content_settings::MockProvider>();
+ provider->SetWebsiteSetting(
+ ContentSettingsPattern::Wildcard(), ContentSettingsPattern::Wildcard(),
+ ContentSettingsType::COOKIES, std::string(),
+ std::make_unique<base::Value>(CONTENT_SETTING_ALLOW));
+ content_settings::TestUtils::OverrideProvider(
+ map, std::move(provider), HostContentSettingsMap::POLICY_PROVIDER);
+ sync_preferences::TestingPrefServiceSyncable* pref_service =
+ profile()->GetTestingPrefService();
+ pref_service->SetManagedPref(prefs::kBlockThirdPartyCookies,
+ std::make_unique<base::Value>(true));
+
+ handler()->HandleGetCookieControlsManagedState(&get_args);
+ {
+ const content::TestWebUI::CallData& data = *web_ui()->call_data().back();
+ EXPECT_EQ("cr.webUIResponse", data.function_name());
+ EXPECT_EQ(kCallbackId, data.arg1()->GetString());
+ ASSERT_TRUE(data.arg2()->GetBool());
+ for (const auto& control_name : kControlNames) {
+ auto* control_state = data.arg3()->FindPath(control_name);
+ ASSERT_TRUE(control_state->FindKey("disabled")->GetBool());
+ ASSERT_EQ(kDevicePolicy,
+ control_state->FindKey("indicator")->GetString());
+ }
+ }
+}
+
+TEST_F(SiteSettingsHandlerTest, CookieSettingDescription) {
+ const auto kBlocked = [](int num) {
+ return l10n_util::GetPluralStringFUTF8(
+ IDS_SETTINGS_SITE_SETTINGS_COOKIES_BLOCK, num);
+ };
+ const auto kAllowed = [](int num) {
+ return l10n_util::GetPluralStringFUTF8(
+ IDS_SETTINGS_SITE_SETTINGS_COOKIES_ALLOW, num);
+ };
+ const std::string kBlockThirdParty = l10n_util::GetStringUTF8(
+ IDS_SETTINGS_SITE_SETTINGS_COOKIES_BLOCK_THIRD_PARTY);
+ const std::string kBlockThirdPartyIncognito = l10n_util::GetStringUTF8(
+ IDS_SETTINGS_SITE_SETTINGS_COOKIES_BLOCK_THIRD_PARTY_INCOGNITO);
+
+ // Enforce expected default profile setting.
+ profile()->GetPrefs()->SetBoolean(prefs::kBlockThirdPartyCookies, false);
+ profile()->GetPrefs()->SetInteger(
+ prefs::kCookieControlsMode,
+ static_cast<int>(content_settings::CookieControlsMode::kIncognitoOnly));
+ auto* content_settings =
+ HostContentSettingsMapFactory::GetForProfile(profile());
+ content_settings->SetDefaultContentSetting(
+ ContentSettingsType::COOKIES, ContentSetting::CONTENT_SETTING_ALLOW);
+ web_ui()->ClearTrackedCalls();
+
+ // Validate get method works.
+ base::ListValue get_args;
+ get_args.AppendString(kCallbackId);
+ handler()->HandleGetCookieSettingDescription(&get_args);
+ const content::TestWebUI::CallData& data = *web_ui()->call_data().back();
+
+ EXPECT_EQ("cr.webUIResponse", data.function_name());
+ EXPECT_EQ(kCallbackId, data.arg1()->GetString());
+ ASSERT_TRUE(data.arg2()->GetBool());
+ EXPECT_EQ(kBlockThirdPartyIncognito, data.arg3()->GetString());
+
+ // Multiple listeners will be called when prefs and content settings are
+ // changed in this test. Increment our expected call_data index accordingly.
+ int expected_call_index = 0;
+ const int kPrefListenerIndex = 1;
+ const int kContentSettingListenerIndex = 2;
+
+ // Check updates are working,
+ profile()->GetPrefs()->SetBoolean(prefs::kBlockThirdPartyCookies, true);
+ expected_call_index += kPrefListenerIndex;
+ ValidateCookieSettingUpdate(kBlockThirdParty, expected_call_index);
+
+ content_settings->SetDefaultContentSetting(
+ ContentSettingsType::COOKIES, ContentSetting::CONTENT_SETTING_BLOCK);
+ expected_call_index += kContentSettingListenerIndex;
+ ValidateCookieSettingUpdate(kBlocked(0), expected_call_index);
+
+ // Check changes which do not affect the effective cookie setting.
+ profile()->GetPrefs()->SetBoolean(prefs::kBlockThirdPartyCookies, false);
+ expected_call_index += kPrefListenerIndex;
+ ValidateCookieSettingUpdate(kBlocked(0), expected_call_index);
+
+ profile()->GetPrefs()->SetInteger(
+ prefs::kCookieControlsMode,
+ static_cast<int>(content_settings::CookieControlsMode::kOff));
+ expected_call_index += kPrefListenerIndex;
+ ValidateCookieSettingUpdate(kBlocked(0), expected_call_index);
+
+ // Set to allow and check previous changes are respected.
+ content_settings->SetDefaultContentSetting(
+ ContentSettingsType::COOKIES, ContentSetting::CONTENT_SETTING_ALLOW);
+ expected_call_index += kContentSettingListenerIndex;
+ ValidateCookieSettingUpdate(kAllowed(0), expected_call_index);
+
+ // Confirm exceptions are counted correctly.
+ GURL url1("https://example.com");
+ GURL url2("http://example.com");
+ GURL url3("http://another.example.com");
+ content_settings->SetContentSettingDefaultScope(
+ url1, url1, ContentSettingsType::COOKIES, std::string(),
+ ContentSetting::CONTENT_SETTING_BLOCK);
+ expected_call_index += kContentSettingListenerIndex;
+ ValidateCookieSettingUpdate(kAllowed(1), expected_call_index);
+
+ content_settings->SetContentSettingDefaultScope(
+ url2, url2, ContentSettingsType::COOKIES, std::string(),
+ ContentSetting::CONTENT_SETTING_ALLOW);
+ expected_call_index += kContentSettingListenerIndex;
+ ValidateCookieSettingUpdate(kAllowed(1), expected_call_index);
+
+ content_settings->SetContentSettingDefaultScope(
+ url3, url3, ContentSettingsType::COOKIES, std::string(),
+ ContentSetting::CONTENT_SETTING_SESSION_ONLY);
+ expected_call_index += kContentSettingListenerIndex;
+ ValidateCookieSettingUpdate(kAllowed(1), expected_call_index);
+
+ content_settings->SetDefaultContentSetting(
+ ContentSettingsType::COOKIES, ContentSetting::CONTENT_SETTING_BLOCK);
+ expected_call_index += kContentSettingListenerIndex;
+ ValidateCookieSettingUpdate(kBlocked(2), expected_call_index);
+}
+
TEST_F(SiteSettingsHandlerTest, HandleGetFormattedBytes) {
const double size = 120000000000;
base::ListValue get_args;