summaryrefslogtreecommitdiff
path: root/chromium/chrome/browser/ui/webui/settings
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/chrome/browser/ui/webui/settings')
-rw-r--r--chromium/chrome/browser/ui/webui/settings/about_handler.cc15
-rw-r--r--chromium/chrome/browser/ui/webui/settings/about_handler.h1
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/about_section.cc149
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/about_section.h19
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc176
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_section.h5
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc14
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.cc191
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.h40
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/apps_section.cc98
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/apps_section.h5
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.cc187
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.h11
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.cc27
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.h28
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator_test_api.h19
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/constants/constants_util.cc2
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom29
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/constants/routes_util.cc7
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom34
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc90
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.h20
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/crostini_section.cc158
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/crostini_section.h6
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc11
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler_unittest.cc27
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/date_time_handler.cc11
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/date_time_section.cc54
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/date_time_section.h5
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_dlc_handler.cc46
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_dlc_handler.h26
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_dlc_handler_unittest.cc51
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_section.cc340
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_section.h19
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc15
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h1
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler_unittest.cc52
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/fake_hierarchy.cc53
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/fake_hierarchy.h50
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_section.cc52
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_section.h56
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_sections.cc24
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_sections.h26
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/files_section.cc29
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/files_section.h5
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/google_assistant_handler.cc4
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/hierarchy.cc318
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/hierarchy.h171
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/internet_section.cc422
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/internet_section.h24
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/languages_section.cc166
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/languages_section.h7
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/main_section.cc37
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/main_section.h5
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_section.cc192
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_section.h10
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_identifier.h24
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.cc8
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.h6
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_factory.cc13
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_unittest.cc52
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_section.cc39
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_section.h94
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.cc15
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.h9
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc4
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/parental_controls_handler.cc6
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/people_section.cc271
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/people_section.h5
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/personalization_section.cc72
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/personalization_section.h5
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.cc54
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.h10
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/printing_section.cc45
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/printing_section.h5
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc41
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/privacy_section.h5
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/reset_section.cc23
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/reset_section.h5
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/search.mojom64
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/search_concept.h3
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc277
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.h70
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc238
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/search_result_icon.mojom1
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.cc188
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h78
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry_unittest.cc69
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search_section.cc166
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search_section.h8
-rw-r--r--chromium/chrome/browser/ui/webui/settings/custom_home_pages_table_model.cc5
-rw-r--r--chromium/chrome/browser/ui/webui/settings/recent_site_settings_helper_unittest.cc6
-rw-r--r--chromium/chrome/browser/ui/webui/settings/safety_check_handler.cc7
-rw-r--r--chromium/chrome/browser/ui/webui/settings/safety_check_handler.h12
-rw-r--r--chromium/chrome/browser/ui/webui/settings/safety_check_handler_unittest.cc19
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc4
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler_browsertest.cc14
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc105
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc1
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc107
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler.h19
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler_browsertest.cc201
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_ui.cc10
-rw-r--r--chromium/chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.cc12
-rw-r--r--chromium/chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.h3
-rw-r--r--chromium/chrome/browser/ui/webui/settings/site_settings_handler.cc41
-rw-r--r--chromium/chrome/browser/ui/webui/settings/site_settings_handler.h8
-rw-r--r--chromium/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc203
-rw-r--r--chromium/chrome/browser/ui/webui/settings/site_settings_helper.cc263
-rw-r--r--chromium/chrome/browser/ui/webui/settings/site_settings_helper.h24
-rw-r--r--chromium/chrome/browser/ui/webui/settings/site_settings_helper_unittest.cc340
-rw-r--r--chromium/chrome/browser/ui/webui/settings/tts_handler.cc10
-rw-r--r--chromium/chrome/browser/ui/webui/settings/tts_handler.h1
113 files changed, 5454 insertions, 1574 deletions
diff --git a/chromium/chrome/browser/ui/webui/settings/about_handler.cc b/chromium/chrome/browser/ui/webui/settings/about_handler.cc
index 9f615ac73cb..a1bb190d093 100644
--- a/chromium/chrome/browser/ui/webui/settings/about_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/about_handler.cc
@@ -101,15 +101,12 @@ struct RegulatoryLabel {
// Returns message that informs user that for update it's better to
// connect to a network of one of the allowed types.
base::string16 GetAllowedConnectionTypesMessage() {
- const chromeos::NetworkState* network = chromeos::NetworkHandler::Get()
- ->network_state_handler()
- ->DefaultNetwork();
- const bool mobile_data =
- network && network->IsConnectedState() && network->IsUsingMobileData();
-
if (help_utils_chromeos::IsUpdateOverCellularAllowed(
- true /* interactive */)) {
- return mobile_data
+ /*interactive=*/true)) {
+ const bool metered = chromeos::NetworkHandler::Get()
+ ->network_state_handler()
+ ->default_network_is_metered();
+ return metered
? l10n_util::GetStringUTF16(
IDS_UPGRADE_NETWORK_LIST_CELLULAR_ALLOWED_NOT_AUTOMATIC)
: l10n_util::GetStringUTF16(
@@ -652,6 +649,7 @@ void AboutHandler::RequestUpdate() {
void AboutHandler::SetUpdateStatus(VersionUpdater::Status status,
int progress,
bool rollback,
+ bool powerwash,
const std::string& version,
int64_t size,
const base::string16& message) {
@@ -663,6 +661,7 @@ void AboutHandler::SetUpdateStatus(VersionUpdater::Status status,
event->SetString("message", message);
event->SetInteger("progress", progress);
event->SetBoolean("rollback", rollback);
+ event->SetBoolean("powerwash", powerwash);
event->SetString("version", version);
// DictionaryValue does not support int64_t, so convert to string.
event->SetString("size", base::NumberToString(size));
diff --git a/chromium/chrome/browser/ui/webui/settings/about_handler.h b/chromium/chrome/browser/ui/webui/settings/about_handler.h
index 4b8bf98b5a3..bc71e2da278 100644
--- a/chromium/chrome/browser/ui/webui/settings/about_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/about_handler.h
@@ -135,6 +135,7 @@ class AboutHandler : public settings::SettingsPageUIHandler,
void SetUpdateStatus(VersionUpdater::Status status,
int progress,
bool rollback,
+ bool powerwash,
const std::string& version,
int64_t size,
const base::string16& fail_message);
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/about_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/about_section.cc
index ea9dc60efd8..a90a99bfebb 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/about_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/about_section.cc
@@ -4,11 +4,11 @@
#include "chrome/browser/ui/webui/settings/chromeos/about_section.h"
+#include "base/feature_list.h"
#include "base/i18n/message_formatter.h"
#include "base/no_destructor.h"
#include "base/strings/utf_string_conversions.h"
#include "base/system/sys_info.h"
-#include "build/branding_buildflags.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browser_process_platform_part.h"
#include "chrome/browser/chromeos/arc/arc_util.h"
@@ -19,10 +19,13 @@
#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h"
#include "chrome/browser/ui/webui/webui_util.h"
#include "chrome/common/channel_info.h"
+#include "chrome/common/pref_names.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 "chromeos/dbus/constants/dbus_switches.h"
+#include "components/prefs/pref_service.h"
#include "components/strings/grit/components_chromium_strings.h"
#include "components/strings/grit/components_strings.h"
#include "components/user_manager/user_manager.h"
@@ -44,16 +47,14 @@ const std::vector<SearchConcept>& GetAboutSearchConcepts() {
mojom::SearchResultIcon::kChrome,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
- {.subpage = mojom::Subpage::kDetailedBuildInfo},
- {IDS_OS_SETTINGS_TAG_ABOUT_CHROME_OS_DETAILED_BUILD_ALT1,
- SearchConcept::kAltTagEnd}},
- {IDS_OS_SETTINGS_TAG_ABOUT_CHROME_OS,
+ {.subpage = mojom::Subpage::kDetailedBuildInfo}},
+ {IDS_SETTINGS_ABOUT_OS,
mojom::kAboutChromeOsDetailsSubpagePath,
mojom::SearchResultIcon::kChrome,
- mojom::SearchResultDefaultRank::kHigh,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
{.subpage = mojom::Subpage::kAboutChromeOsDetails}},
- {IDS_OS_SETTINGS_TAG_ABOUT_CHROME_OS_VERSION,
+ {IDS_OS_SETTINGS_TAG_OS_VERSION,
mojom::kAboutChromeOsDetailsSubpagePath,
mojom::SearchResultIcon::kChrome,
mojom::SearchResultDefaultRank::kMedium,
@@ -62,13 +63,67 @@ const std::vector<SearchConcept>& GetAboutSearchConcepts() {
{IDS_OS_SETTINGS_TAG_ABOUT_CHROME_OS_CHANNEL,
mojom::kDetailedBuildInfoSubpagePath,
mojom::SearchResultIcon::kChrome,
- mojom::SearchResultDefaultRank::kHigh,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kChangeChromeChannel}},
+ {IDS_OS_SETTINGS_TAG_ABOUT_OS_UPDATE,
+ mojom::kAboutChromeOsDetailsSubpagePath,
+ mojom::SearchResultIcon::kChrome,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kCheckForOsUpdate}},
+ {IDS_OS_SETTINGS_TAG_ABOUT_HELP,
+ mojom::kAboutChromeOsDetailsSubpagePath,
+ mojom::SearchResultIcon::kChrome,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kGetHelpWithChromeOs}},
+ });
+ return *tags;
+}
+
+const std::vector<SearchConcept>& GetAboutReleaseNotesSearchConcepts() {
+ static const base::NoDestructor<std::vector<SearchConcept>> tags({
+ {IDS_OS_SETTINGS_TAG_ABOUT_RELEASE_NOTES,
+ mojom::kAboutChromeOsDetailsSubpagePath,
+ mojom::SearchResultIcon::kChrome,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kSeeWhatsNew},
+ {IDS_OS_SETTINGS_TAG_ABOUT_RELEASE_NOTES_ALT1,
+ SearchConcept::kAltTagEnd}},
+ });
+ return *tags;
+}
+
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
+const std::vector<SearchConcept>& GetAboutTermsOfServiceSearchConcepts() {
+ static const base::NoDestructor<std::vector<SearchConcept>> tags({
+ {IDS_OS_SETTINGS_TAG_ABOUT_TERMS_OF_SERVICE,
+ mojom::kAboutChromeOsDetailsSubpagePath,
+ mojom::SearchResultIcon::kChrome,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kTermsOfService}},
});
return *tags;
}
+const std::vector<SearchConcept>& GetAboutReportIssueSearchConcepts() {
+ static const base::NoDestructor<std::vector<SearchConcept>> tags({
+ {IDS_OS_SETTINGS_TAG_ABOUT_REPORT_ISSUE,
+ mojom::kAboutChromeOsDetailsSubpagePath,
+ mojom::SearchResultIcon::kChrome,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kReportAnIssue},
+ {IDS_OS_SETTINGS_TAG_ABOUT_REPORT_ISSUE_ALT1,
+ SearchConcept::kAltTagEnd}},
+ });
+ return *tags;
+}
+#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
+
// Returns the link to the safety info for the device (if it exists).
std::string GetSafetyInfoLink() {
const std::vector<std::string> board =
@@ -99,10 +154,33 @@ bool IsDeviceManaged() {
} // namespace
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
+AboutSection::AboutSection(Profile* profile,
+ SearchTagRegistry* search_tag_registry,
+ PrefService* pref_service)
+ : AboutSection(profile, search_tag_registry) {
+ pref_service_ = pref_service;
+
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+ updater.AddSearchTags(GetAboutTermsOfServiceSearchConcepts());
+
+ pref_change_registrar_.Init(pref_service_);
+ pref_change_registrar_.Add(
+ prefs::kUserFeedbackAllowed,
+ base::BindRepeating(&AboutSection::UpdateReportIssueSearchTags,
+ base::Unretained(this)));
+ UpdateReportIssueSearchTags();
+}
+#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
+
AboutSection::AboutSection(Profile* profile,
SearchTagRegistry* search_tag_registry)
: OsSettingsSection(profile, search_tag_registry) {
- registry()->AddSearchTags(GetAboutSearchConcepts());
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+ updater.AddSearchTags(GetAboutSearchConcepts());
+
+ if (base::FeatureList::IsEnabled(features::kReleaseNotes))
+ updater.AddSearchTags(GetAboutReleaseNotesSearchConcepts());
}
AboutSection::~AboutSection() = default;
@@ -270,5 +348,58 @@ void AboutSection::AddHandlers(content::WebUI* web_ui) {
web_ui->AddMessageHandler(std::make_unique<::settings::AboutHandler>());
}
+int AboutSection::GetSectionNameMessageId() const {
+ return IDS_SETTINGS_ABOUT_OS;
+}
+
+mojom::Section AboutSection::GetSection() const {
+ return mojom::Section::kAboutChromeOs;
+}
+
+mojom::SearchResultIcon AboutSection::GetSectionIcon() const {
+ return mojom::SearchResultIcon::kChrome;
+}
+
+std::string AboutSection::GetSectionPath() const {
+ return mojom::kAboutChromeOsSectionPath;
+}
+
+void AboutSection::RegisterHierarchy(HierarchyGenerator* generator) const {
+ // About Chrome OS.
+ generator->RegisterTopLevelSubpage(
+ IDS_SETTINGS_ABOUT_OS, mojom::Subpage::kAboutChromeOsDetails,
+ mojom::SearchResultIcon::kChrome, mojom::SearchResultDefaultRank::kMedium,
+ mojom::kAboutChromeOsDetailsSubpagePath);
+ static constexpr mojom::Setting kAboutChromeOsDetailsSettings[] = {
+ mojom::Setting::kCheckForOsUpdate, mojom::Setting::kSeeWhatsNew,
+ mojom::Setting::kGetHelpWithChromeOs, mojom::Setting::kReportAnIssue,
+ mojom::Setting::kTermsOfService};
+ RegisterNestedSettingBulk(mojom::Subpage::kAboutChromeOsDetails,
+ kAboutChromeOsDetailsSettings, generator);
+
+ // Detailed build info.
+ generator->RegisterNestedSubpage(
+ IDS_SETTINGS_ABOUT_PAGE_DETAILED_BUILD_INFO,
+ mojom::Subpage::kDetailedBuildInfo, mojom::Subpage::kAboutChromeOsDetails,
+ mojom::SearchResultIcon::kChrome, mojom::SearchResultDefaultRank::kMedium,
+ mojom::kDetailedBuildInfoSubpagePath);
+ static constexpr mojom::Setting kDetailedBuildInfoSettings[] = {
+ mojom::Setting::kChangeChromeChannel,
+ mojom::Setting::kCopyDetailedBuildInfo};
+ RegisterNestedSettingBulk(mojom::Subpage::kDetailedBuildInfo,
+ kDetailedBuildInfoSettings, generator);
+}
+
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
+void AboutSection::UpdateReportIssueSearchTags() {
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+
+ if (pref_service_->GetBoolean(prefs::kUserFeedbackAllowed))
+ updater.AddSearchTags(GetAboutReportIssueSearchConcepts());
+ else
+ updater.RemoveSearchTags(GetAboutReportIssueSearchConcepts());
+}
+#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
+
} // namespace settings
} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/about_section.h b/chromium/chrome/browser/ui/webui/settings/chromeos/about_section.h
index 0e619e80d91..506f0b67d56 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/about_section.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/about_section.h
@@ -5,7 +5,9 @@
#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_ABOUT_SECTION_H_
#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_ABOUT_SECTION_H_
+#include "build/branding_buildflags.h"
#include "chrome/browser/ui/webui/settings/chromeos/os_settings_section.h"
+#include "components/prefs/pref_change_registrar.h"
namespace content {
class WebUIDataSource;
@@ -19,6 +21,11 @@ class SearchTagRegistry;
// Provides UI strings and search tags for the settings "About Chrome OS" page.
class AboutSection : public OsSettingsSection {
public:
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
+ AboutSection(Profile* profile,
+ SearchTagRegistry* search_tag_registry,
+ PrefService* pref_service);
+#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
AboutSection(Profile* profile, SearchTagRegistry* search_tag_registry);
~AboutSection() override;
@@ -26,6 +33,18 @@ class AboutSection : public OsSettingsSection {
// OsSettingsSection:
void AddLoadTimeData(content::WebUIDataSource* html_source) override;
void AddHandlers(content::WebUI* web_ui) override;
+ int GetSectionNameMessageId() const override;
+ mojom::Section GetSection() const override;
+ mojom::SearchResultIcon GetSectionIcon() const override;
+ std::string GetSectionPath() const override;
+ void RegisterHierarchy(HierarchyGenerator* generator) const override;
+
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
+ void UpdateReportIssueSearchTags();
+
+ PrefService* pref_service_;
+ PrefChangeRegistrar pref_change_registrar_;
+#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
};
} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc
index 1e7b9bf8b08..a38be955b4e 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc
@@ -23,6 +23,7 @@
#include "content/public/browser/web_ui_data_source.h"
#include "content/public/common/content_features.h"
#include "media/base/media_switches.h"
+#include "ui/accessibility/accessibility_features.h"
#include "ui/accessibility/accessibility_switches.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/webui/web_ui_util.h"
@@ -82,16 +83,18 @@ const std::vector<SearchConcept>& GetA11ySearchConcepts() {
{IDS_OS_SETTINGS_TAG_A11Y_MONO_AUDIO,
mojom::kManageAccessibilitySubpagePath,
mojom::SearchResultIcon::kA11y,
- mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultDefaultRank::kLow,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kMonoAudio},
{IDS_OS_SETTINGS_TAG_A11Y_MONO_AUDIO_ALT1, SearchConcept::kAltTagEnd}},
{IDS_OS_SETTINGS_TAG_A11Y_TEXT_TO_SPEECH,
- mojom::kManageAccessibilitySubpagePath,
+ mojom::kTextToSpeechSubpagePath,
mojom::SearchResultIcon::kA11y,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
- {.subpage = mojom::Subpage::kManageAccessibility}},
+ {.subpage = mojom::Subpage::kTextToSpeech},
+ {IDS_OS_SETTINGS_TAG_A11Y_TEXT_TO_SPEECH_ALT1,
+ SearchConcept::kAltTagEnd}},
{IDS_OS_SETTINGS_TAG_A11Y_CAPTIONS,
mojom::kCaptionsSubpagePath,
mojom::SearchResultIcon::kA11y,
@@ -262,11 +265,43 @@ const std::vector<SearchConcept>& GetA11yLabelsSearchConcepts() {
return *tags;
}
+const std::vector<SearchConcept>& GetA11yLiveCaptionSearchConcepts() {
+ static const base::NoDestructor<std::vector<SearchConcept>> tags({
+ {IDS_OS_SETTINGS_TAG_A11Y_LIVE_CAPTIONS,
+ mojom::kManageAccessibilitySubpagePath,
+ mojom::SearchResultIcon::kA11y,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kLiveCaptions}},
+ });
+ return *tags;
+}
+
+const std::vector<SearchConcept>& GetA11yCursorColorSearchConcepts() {
+ static const base::NoDestructor<std::vector<SearchConcept>> tags({
+ {IDS_OS_SETTINGS_TAG_A11Y_CURSOR_COLOR,
+ mojom::kManageAccessibilitySubpagePath,
+ mojom::SearchResultIcon::kA11y,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kEnableCursorColor}},
+ });
+ return *tags;
+}
+
bool AreExperimentalA11yLabelsAllowed() {
return base::FeatureList::IsEnabled(
::features::kExperimentalAccessibilityLabels);
}
+bool AreLiveCaptionsAllowed() {
+ return base::FeatureList::IsEnabled(media::kLiveCaption);
+}
+
+bool IsCursorColorAllowed() {
+ return features::IsAccessibilityCursorColorEnabled();
+}
+
bool IsSwitchAccessAllowed() {
return base::CommandLine::ForCurrentProcess()->HasSwitch(
::switches::kEnableExperimentalAccessibilitySwitchAccess);
@@ -285,7 +320,8 @@ AccessibilitySection::AccessibilitySection(
PrefService* pref_service)
: OsSettingsSection(profile, search_tag_registry),
pref_service_(pref_service) {
- registry()->AddSearchTags(GetA11ySearchConcepts());
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+ updater.AddSearchTags(GetA11ySearchConcepts());
pref_change_registrar_.Init(pref_service_);
pref_change_registrar_.Add(
@@ -323,6 +359,13 @@ void AccessibilitySection::AddLoadTimeData(
IDS_SETTINGS_LARGE_MOUSE_CURSOR_SIZE_DEFAULT_LABEL},
{"largeMouseCursorSizeLargeLabel",
IDS_SETTINGS_LARGE_MOUSE_CURSOR_SIZE_LARGE_LABEL},
+ {"cursorColorEnabledLabel", IDS_SETTINGS_CURSOR_COLOR_ENABLED_LABEL},
+ {"cursorColorOptionsLabel", IDS_SETTINGS_CURSOR_COLOR_OPTIONS_LABEL},
+ {"cursorColorRed", IDS_SETTINGS_CURSOR_COLOR_RED},
+ {"cursorColorOrange", IDS_SETTINGS_CURSOR_COLOR_ORANGE},
+ {"cursorColorGreen", IDS_SETTINGS_CURSOR_COLOR_GREEN},
+ {"cursorColorBlue", IDS_SETTINGS_CURSOR_COLOR_BLUE},
+ {"cursorColorPurple", IDS_SETTINGS_CURSOR_COLOR_PURPLE},
{"highContrastLabel", IDS_SETTINGS_HIGH_CONTRAST_LABEL},
{"stickyKeysLabel", IDS_SETTINGS_STICKY_KEYS_LABEL},
{"chromeVoxLabel", IDS_SETTINGS_CHROMEVOX_LABEL},
@@ -473,6 +516,10 @@ void AccessibilitySection::AddLoadTimeData(
IDS_SETTINGS_A11Y_TABLET_MODE_SHELF_BUTTONS_LABEL},
{"tabletModeShelfNavigationButtonsSettingDescription",
IDS_SETTINGS_A11Y_TABLET_MODE_SHELF_BUTTONS_DESCRIPTION},
+ {"captionsEnableLiveCaptionTitle",
+ IDS_SETTINGS_CAPTIONS_ENABLE_LIVE_CAPTION_TITLE},
+ {"captionsEnableLiveCaptionSubtitle",
+ IDS_SETTINGS_CAPTIONS_ENABLE_LIVE_CAPTION_SUBTITLE},
};
AddLocalizedStringsBulk(html_source, kLocalizedStrings);
@@ -495,8 +542,10 @@ void AccessibilitySection::AddLoadTimeData(
html_source->AddString("tabletModeShelfNavigationButtonsLearnMoreUrl",
chrome::kTabletModeGesturesLearnMoreURL);
- html_source->AddBoolean("enableLiveCaption",
- base::FeatureList::IsEnabled(media::kLiveCaption));
+ html_source->AddBoolean("enableLiveCaption", AreLiveCaptionsAllowed());
+
+ html_source->AddBoolean("showExperimentalAccessibilityCursorColor",
+ IsCursorColorAllowed());
::settings::AddCaptionSubpageStrings(html_source);
}
@@ -510,33 +559,132 @@ void AccessibilitySection::AddHandlers(content::WebUI* web_ui) {
std::make_unique<::settings::FontHandler>(profile()));
}
+int AccessibilitySection::GetSectionNameMessageId() const {
+ return IDS_SETTINGS_ACCESSIBILITY;
+}
+
+mojom::Section AccessibilitySection::GetSection() const {
+ return mojom::Section::kAccessibility;
+}
+
+mojom::SearchResultIcon AccessibilitySection::GetSectionIcon() const {
+ return mojom::SearchResultIcon::kA11y;
+}
+
+std::string AccessibilitySection::GetSectionPath() const {
+ return mojom::kAccessibilitySectionPath;
+}
+
+void AccessibilitySection::RegisterHierarchy(
+ HierarchyGenerator* generator) const {
+ generator->RegisterTopLevelSetting(mojom::Setting::kA11yQuickSettings);
+
+ // Manage accessibility.
+ generator->RegisterTopLevelSubpage(
+ IDS_SETTINGS_ACCESSIBILITY_MANAGE_ACCESSIBILITY_FEATURES,
+ mojom::Subpage::kManageAccessibility, mojom::SearchResultIcon::kA11y,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::kManageAccessibilitySubpagePath);
+ static constexpr mojom::Setting kManageAccessibilitySettings[] = {
+ mojom::Setting::kChromeVox,
+ mojom::Setting::kSelectToSpeak,
+ mojom::Setting::kHighContrastMode,
+ mojom::Setting::kFullscreenMagnifier,
+ mojom::Setting::kDockedMagnifier,
+ mojom::Setting::kStickyKeys,
+ mojom::Setting::kOnScreenKeyboard,
+ mojom::Setting::kDictation,
+ mojom::Setting::kSpeakToType,
+ mojom::Setting::kEnableSwitchAccess,
+ mojom::Setting::kHighlightTextCaret,
+ mojom::Setting::kAutoClickWhenCursorStops,
+ mojom::Setting::kLargeCursor,
+ mojom::Setting::kHighlightCursorWhileMoving,
+ mojom::Setting::kTabletNavigationButtons,
+ mojom::Setting::kMonoAudio,
+ mojom::Setting::kStartupSound,
+ mojom::Setting::kGetImageDescriptionsFromGoogle,
+ mojom::Setting::kLiveCaptions,
+ mojom::Setting::kEnableCursorColor,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kManageAccessibility,
+ kManageAccessibilitySettings, generator);
+
+ // Text-to-Speech.
+ generator->RegisterTopLevelSubpage(
+ IDS_SETTINGS_MANAGE_TTS_SETTINGS, mojom::Subpage::kTextToSpeech,
+ mojom::SearchResultIcon::kA11y, mojom::SearchResultDefaultRank::kMedium,
+ mojom::kTextToSpeechSubpagePath);
+ static constexpr mojom::Setting kTextToSpeechSettings[] = {
+ mojom::Setting::kTextToSpeechRate, mojom::Setting::kTextToSpeechPitch,
+ mojom::Setting::kTextToSpeechVolume, mojom::Setting::kTextToSpeechVoice,
+ mojom::Setting::kTextToSpeechEngines,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kTextToSpeech,
+ kTextToSpeechSettings, generator);
+
+ // Switch access.
+ generator->RegisterTopLevelSubpage(IDS_SETTINGS_MANAGE_SWITCH_ACCESS_SETTINGS,
+ mojom::Subpage::kSwitchAccessOptions,
+ mojom::SearchResultIcon::kA11y,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::kSwitchAccessOptionsSubpagePath);
+ static constexpr mojom::Setting kSwitchAccessSettings[] = {
+ mojom::Setting::kSwitchActionAssignment,
+ mojom::Setting::kSwitchActionAutoScan,
+ mojom::Setting::kSwitchActionAutoScanKeyboard,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kSwitchAccessOptions,
+ kSwitchAccessSettings, generator);
+
+ // Captions.
+ generator->RegisterTopLevelSubpage(
+ IDS_SETTINGS_CAPTIONS, mojom::Subpage::kCaptions,
+ mojom::SearchResultIcon::kA11y, mojom::SearchResultDefaultRank::kMedium,
+ mojom::kCaptionsSubpagePath);
+}
+
void AccessibilitySection::UpdateSearchTags() {
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+
if (accessibility_state_utils::IsScreenReaderEnabled() &&
AreExperimentalA11yLabelsAllowed()) {
- registry()->AddSearchTags(GetA11yLabelsSearchConcepts());
+ updater.AddSearchTags(GetA11yLabelsSearchConcepts());
} else {
- registry()->RemoveSearchTags(GetA11yLabelsSearchConcepts());
+ updater.RemoveSearchTags(GetA11yLabelsSearchConcepts());
}
- registry()->RemoveSearchTags(GetA11ySwitchAccessSearchConcepts());
- registry()->RemoveSearchTags(GetA11ySwitchAccessOnSearchConcepts());
- registry()->RemoveSearchTags(GetA11ySwitchAccessKeyboardSearchConcepts());
+ updater.RemoveSearchTags(GetA11ySwitchAccessSearchConcepts());
+ updater.RemoveSearchTags(GetA11ySwitchAccessOnSearchConcepts());
+ updater.RemoveSearchTags(GetA11ySwitchAccessKeyboardSearchConcepts());
+
+ if (AreLiveCaptionsAllowed()) {
+ updater.AddSearchTags(GetA11yLiveCaptionSearchConcepts());
+ } else {
+ updater.RemoveSearchTags(GetA11yLiveCaptionSearchConcepts());
+ }
+
+ if (IsCursorColorAllowed()) {
+ updater.AddSearchTags(GetA11yCursorColorSearchConcepts());
+ } else {
+ updater.RemoveSearchTags(GetA11yCursorColorSearchConcepts());
+ }
if (!IsSwitchAccessAllowed())
return;
- registry()->AddSearchTags(GetA11ySwitchAccessSearchConcepts());
+ updater.AddSearchTags(GetA11ySwitchAccessSearchConcepts());
if (!pref_service_->GetBoolean(
ash::prefs::kAccessibilitySwitchAccessEnabled)) {
return;
}
- registry()->AddSearchTags(GetA11ySwitchAccessOnSearchConcepts());
+ updater.AddSearchTags(GetA11ySwitchAccessOnSearchConcepts());
if (pref_service_->GetBoolean(
ash::prefs::kAccessibilitySwitchAccessAutoScanEnabled)) {
- registry()->AddSearchTags(GetA11ySwitchAccessKeyboardSearchConcepts());
+ updater.AddSearchTags(GetA11ySwitchAccessKeyboardSearchConcepts());
}
}
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_section.h b/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_section.h
index 546454007b1..77f82db40d3 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_section.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_section.h
@@ -31,6 +31,11 @@ class AccessibilitySection : public OsSettingsSection {
// OsSettingsSection:
void AddLoadTimeData(content::WebUIDataSource* html_source) override;
void AddHandlers(content::WebUI* web_ui) override;
+ int GetSectionNameMessageId() const override;
+ mojom::Section GetSection() const override;
+ mojom::SearchResultIcon GetSectionIcon() const override;
+ std::string GetSectionPath() const override;
+ void RegisterHierarchy(HierarchyGenerator* generator) const override;
void UpdateSearchTags();
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 0d6b946d6c3..69266feb260 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
@@ -17,10 +17,10 @@
#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/ui/webui/chromeos/account_manager_welcome_dialog.h"
-#include "chrome/browser/ui/webui/chromeos/account_migration_welcome_dialog.h"
+#include "chrome/browser/ui/webui/chromeos/account_manager/account_manager_welcome_dialog.h"
+#include "chrome/browser/ui/webui/chromeos/account_manager/account_migration_welcome_dialog.h"
#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
-#include "chrome/browser/ui/webui/signin/inline_login_handler_dialog_chromeos.h"
+#include "chrome/browser/ui/webui/signin/inline_login_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"
@@ -343,8 +343,8 @@ base::ListValue AccountManagerUIHandler::GetSecondaryGaiaAccounts(
void AccountManagerUIHandler::HandleAddAccount(const base::ListValue* args) {
AllowJavascript();
- InlineLoginHandlerDialogChromeOS::Show(
- InlineLoginHandlerDialogChromeOS::Source::kSettingsAddAccountButton);
+ InlineLoginDialogChromeOS::Show(
+ InlineLoginDialogChromeOS::Source::kSettingsAddAccountButton);
}
void AccountManagerUIHandler::HandleReauthenticateAccount(
@@ -354,9 +354,9 @@ void AccountManagerUIHandler::HandleReauthenticateAccount(
CHECK(!args->GetList().empty());
const std::string& account_email = args->GetList()[0].GetString();
- InlineLoginHandlerDialogChromeOS::Show(
+ InlineLoginDialogChromeOS::Show(
account_email,
- InlineLoginHandlerDialogChromeOS::Source::kSettingsReauthAccountButton);
+ InlineLoginDialogChromeOS::Source::kSettingsReauthAccountButton);
}
void AccountManagerUIHandler::HandleMigrateAccount(
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
index 276327a54c8..fd4f14a6d09 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.cc
@@ -4,13 +4,34 @@
#include "chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.h"
+#include "ash/public/cpp/ambient/ambient_backend_controller.h"
+#include "ash/public/cpp/ambient/common/ambient_settings.h"
#include "base/bind.h"
+#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/values.h"
namespace chromeos {
namespace settings {
+namespace {
+
+// Width and height of the preview image for personal album.
+constexpr int kBannerWidth = 512;
+constexpr int kBannderHeight = 512;
+
+ash::AmbientModeTopicSource ExtractTopicSource(const base::ListValue* args) {
+ CHECK_EQ(args->GetSize(), 1U);
+ ash::AmbientModeTopicSource topic_source =
+ static_cast<ash::AmbientModeTopicSource>(args->GetList()[0].GetInt());
+ // Check the |topic_source| has valid value.
+ CHECK_GE(topic_source, ash::AmbientModeTopicSource::kMinValue);
+ CHECK_LE(topic_source, ash::AmbientModeTopicSource::kMaxValue);
+ return topic_source;
+}
+
+} // namespace
+
AmbientModeHandler::AmbientModeHandler() = default;
AmbientModeHandler::~AmbientModeHandler() = default;
@@ -22,36 +43,94 @@ void AmbientModeHandler::RegisterMessages() {
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
- "onTopicSourceSelectedChanged",
- base::BindRepeating(&AmbientModeHandler::HandleTopicSourceSelectedChanged,
+ "setSelectedTopicSource",
+ base::BindRepeating(&AmbientModeHandler::HandleSetSelectedTopicSource,
+ base::Unretained(this)));
+
+ web_ui()->RegisterMessageCallback(
+ "requestPhotosContainers",
+ base::BindRepeating(&AmbientModeHandler::RequestPhotosContainers,
base::Unretained(this)));
+
+ web_ui()->RegisterMessageCallback(
+ "setSelectedPhotosContainers",
+ base::BindRepeating(
+ &AmbientModeHandler::HandleSetSelectedPhotosContainers,
+ base::Unretained(this)));
}
void AmbientModeHandler::OnJavascriptAllowed() {
- if (topic_source_.has_value())
- SendTopicSource();
+ GetSettings();
+
+ // Prefetch albums.
+ FetchPersonalAlbums();
+}
+
+void AmbientModeHandler::OnJavascriptDisallowed() {
+ weak_factory_.InvalidateWeakPtrs();
}
void AmbientModeHandler::HandleInitialized(const base::ListValue* args) {
CHECK(args);
CHECK(args->empty());
+ init_from_ambient_mode_page_ = true;
AllowJavascript();
- GetSettings();
}
-void AmbientModeHandler::HandleTopicSourceSelectedChanged(
+void AmbientModeHandler::RequestPhotosContainers(const base::ListValue* args) {
+ // TODO(b/159747583): Handle deep linking to ambientMode/photos page.
+ // For now it will not load the page contents if visited directly.
+ if (!init_from_ambient_mode_page_)
+ return;
+
+ ash::AmbientModeTopicSource topic_source = ExtractTopicSource(args);
+ DCHECK_EQ(topic_source, settings_->topic_source);
+
+ if (topic_source == ash::AmbientModeTopicSource::kGooglePhotos) {
+ FetchPersonalAlbums();
+ }
+ SendPhotosContainers();
+}
+
+void AmbientModeHandler::HandleSetSelectedTopicSource(
const base::ListValue* args) {
- CHECK_EQ(args->GetSize(), 1U);
- int topic_source;
- CHECK(base::StringToInt(args->GetList()[0].GetString(), &topic_source));
- // Check the |topic_source| has valid value.
- CHECK_GE(topic_source,
- static_cast<int>(ash::AmbientModeTopicSource::kMinValue));
- CHECK_LE(topic_source,
- static_cast<int>(ash::AmbientModeTopicSource::kMaxValue));
+ ash::AmbientModeTopicSource topic_source = ExtractTopicSource(args);
+ settings_->topic_source = topic_source;
+ UpdateSettings();
+}
- UpdateSettings(static_cast<ash::AmbientModeTopicSource>(topic_source));
+void AmbientModeHandler::HandleSetSelectedPhotosContainers(
+ const base::ListValue* args) {
+ switch (settings_->topic_source) {
+ case ash::AmbientModeTopicSource::kGooglePhotos:
+ // For Google Photos, we will populate the |selected_album_ids| with IDs
+ // of selected albums.
+ settings_->selected_album_ids.clear();
+ for (const auto& value : args->GetList()) {
+ std::string name = value.GetString();
+ auto it = std::find_if(
+ personal_albums_.albums.begin(), personal_albums_.albums.end(),
+ [name](const auto& album) { return album.album_name == name; });
+ CHECK(it != personal_albums_.albums.end());
+ settings_->selected_album_ids.emplace_back(it->album_id);
+ }
+ break;
+ case ash::AmbientModeTopicSource::kArtGallery:
+ // For Art gallery, we set the corresponding setting to be enabled or not
+ // based on the selections.
+ for (auto& art_setting : settings_->art_settings) {
+ std::string title = art_setting.title;
+ auto it = std::find_if(
+ args->GetList().begin(), args->GetList().end(),
+ [title](const auto& value) { return value.GetString() == title; });
+ const bool checked = it != args->GetList().end();
+ art_setting.enabled = checked;
+ }
+ break;
+ }
+
+ UpdateSettings();
}
void AmbientModeHandler::GetSettings() {
@@ -60,37 +139,63 @@ void AmbientModeHandler::GetSettings() {
}
void AmbientModeHandler::OnGetSettings(
- base::Optional<ash::AmbientModeTopicSource> topic_source) {
- if (!topic_source.has_value()) {
+ const base::Optional<ash::AmbientSettings>& settings) {
+ if (!settings) {
// TODO(b/152921891): Retry a small fixed number of times, then only retry
// when user confirms in the error message dialog.
return;
}
- topic_source_ = topic_source;
- if (!IsJavascriptAllowed())
- return;
-
+ settings_ = settings;
SendTopicSource();
}
void AmbientModeHandler::SendTopicSource() {
+ DCHECK(settings_);
FireWebUIListener("topic-source-changed",
- base::Value(
+ base::Value(static_cast<int>(settings_->topic_source)));
+}
- static_cast<int>(topic_source_.value())));
+void AmbientModeHandler::SendPhotosContainers() {
+ DCHECK(settings_);
+
+ base::Value dictionary(base::Value::Type::DICTIONARY);
+ base::Value containers(base::Value::Type::LIST);
+ switch (settings_->topic_source) {
+ case ash::AmbientModeTopicSource::kGooglePhotos:
+ for (const auto& album : personal_albums_.albums) {
+ base::Value value(base::Value::Type::DICTIONARY);
+ value.SetKey("title", base::Value(album.album_name));
+ value.SetKey("checked",
+ base::Value(base::Contains(settings_->selected_album_ids,
+ album.album_id)));
+ containers.Append(std::move(value));
+ }
+ break;
+ case ash::AmbientModeTopicSource::kArtGallery:
+ for (const auto& setting : settings_->art_settings) {
+ base::Value value(base::Value::Type::DICTIONARY);
+ value.SetKey("title", base::Value(setting.title));
+ value.SetKey("checked", base::Value(setting.enabled));
+ containers.Append(std::move(value));
+ }
+ break;
+ }
+
+ dictionary.SetKey("topicSource",
+ base::Value(static_cast<int>(settings_->topic_source)));
+ dictionary.SetKey("topicContainers", std::move(containers));
+ FireWebUIListener("photos-containers-changed", std::move(dictionary));
}
-void AmbientModeHandler::UpdateSettings(
- ash::AmbientModeTopicSource topic_source) {
+void AmbientModeHandler::UpdateSettings() {
+ DCHECK(settings_);
ash::AmbientBackendController::Get()->UpdateSettings(
- topic_source, base::BindOnce(&AmbientModeHandler::OnUpdateSettings,
- weak_factory_.GetWeakPtr(), topic_source));
+ *settings_, base::BindOnce(&AmbientModeHandler::OnUpdateSettings,
+ weak_factory_.GetWeakPtr()));
}
-void AmbientModeHandler::OnUpdateSettings(
- ash::AmbientModeTopicSource topic_source,
- bool success) {
+void AmbientModeHandler::OnUpdateSettings(bool success) {
if (success)
return;
@@ -98,5 +203,31 @@ void AmbientModeHandler::OnUpdateSettings(
// when user confirms in the error message dialog.
}
+void AmbientModeHandler::FetchPersonalAlbums() {
+ // TODO: Add a helper function to get all the albums.
+ ash::AmbientBackendController::Get()->FetchPersonalAlbums(
+ kBannerWidth, kBannderHeight, /*num_albums=*/100, /*resume_token=*/"",
+ base::BindOnce(&AmbientModeHandler::OnPersonalAlbumsFetched,
+ weak_factory_.GetWeakPtr()));
+}
+
+void AmbientModeHandler::OnPersonalAlbumsFetched(
+ ash::PersonalAlbums personal_albums) {
+ personal_albums_ = std::move(personal_albums);
+
+ // If the |topic_source| is not |kGooglePhotos|, no need to refresh the
+ // photos subpage.
+ // |settings_| could be null because we call GetSettings() and
+ // FetchPersonalAlbums() in OnJavascriptAllowed(). |settings_| is populated by
+ // OnGetSettings(), which could be called later. The purpose to call
+ // FetchPersonalAlbums() is to prefetch albums, which takes several seconds,
+ // This improves the experience when we click into the ambientMode/photos page
+ // to show the albums list faster.
+ if (settings_ &&
+ settings_->topic_source == ash::AmbientModeTopicSource::kGooglePhotos) {
+ SendPhotosContainers();
+ }
+}
+
} // 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
index 8e26f721b60..ac0c6441433 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.h
@@ -12,6 +12,10 @@
#include "base/optional.h"
#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+namespace ash {
+struct AmbientSettings;
+} // namespace ash
+
namespace base {
class ListValue;
} // namespace base
@@ -31,34 +35,52 @@ class AmbientModeHandler : public ::settings::SettingsPageUIHandler {
// settings::SettingsPageUIHandler:
void RegisterMessages() override;
void OnJavascriptAllowed() override;
- void OnJavascriptDisallowed() override {}
+ void OnJavascriptDisallowed() override;
private:
// WebUI call to signal js side is ready.
void HandleInitialized(const base::ListValue* args);
+ // WebUI call to request photos containers, e.g. personal albums or art
+ // categories.
+ void RequestPhotosContainers(const base::ListValue* args);
+
// WebUI call to sync topic source with server.
- void HandleTopicSourceSelectedChanged(const base::ListValue* args);
+ void HandleSetSelectedTopicSource(const base::ListValue* args);
+
+ // WebUI call to sync photos containers with server.
+ void HandleSetSelectedPhotosContainers(const base::ListValue* args);
// Retrieve the initial settings from server.
void GetSettings();
// Called when the initial settings is retrieved.
- void OnGetSettings(base::Optional<ash::AmbientModeTopicSource> topic_source);
+ void OnGetSettings(const base::Optional<ash::AmbientSettings>& settings);
// Send the "topic-source-changed" WebUIListener event when the initial
// settings is retrieved.
void SendTopicSource();
- // Update the selected topic source to server.
- void UpdateSettings(ash::AmbientModeTopicSource topic_source);
+ // Send the "photos-containers-changed" WebUIListener event when the personal
+ // albums are retrieved.
+ void SendPhotosContainers();
+
+ // Update the local |settings_| to server.
+ void UpdateSettings();
// Called when the settings is updated.
- // |topic_source| is the value to retry if the update was failed.
- void OnUpdateSettings(ash::AmbientModeTopicSource topic_source, bool success);
+ void OnUpdateSettings(bool success);
+
+ void FetchPersonalAlbums();
+
+ void OnPersonalAlbumsFetched(ash::PersonalAlbums personal_albums);
+
+ // Whether the Javascript is inited from the ambientMode page.
+ bool init_from_ambient_mode_page_ = false;
+
+ base::Optional<ash::AmbientSettings> settings_;
- // The topic source, i.e. from which category the photos will be displayed.
- base::Optional<ash::AmbientModeTopicSource> topic_source_;
+ ash::PersonalAlbums personal_albums_;
base::WeakPtrFactory<AmbientModeHandler> weak_factory_{this};
};
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/apps_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/apps_section.cc
index 7ae2a6a8724..6d8ebbc5421 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/apps_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/apps_section.cc
@@ -4,6 +4,7 @@
#include "chrome/browser/ui/webui/settings/chromeos/apps_section.h"
+#include "base/feature_list.h"
#include "base/no_destructor.h"
#include "chrome/browser/chromeos/arc/arc_util.h"
#include "chrome/browser/chromeos/plugin_vm/plugin_vm_pref_names.h"
@@ -17,6 +18,7 @@
#include "chrome/common/url_constants.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/grit/os_settings_resources.h"
+#include "chromeos/constants/chromeos_features.h"
#include "components/arc/arc_prefs.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/web_ui_data_source.h"
@@ -39,7 +41,7 @@ const std::vector<SearchConcept>& GetAppsSearchConcepts() {
{IDS_OS_SETTINGS_TAG_APPS_MANAGEMENT,
mojom::kAppManagementSubpagePath,
mojom::SearchResultIcon::kAppsGrid,
- mojom::SearchResultDefaultRank::kHigh,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
{.subpage = mojom::Subpage::kAppManagement},
{IDS_OS_SETTINGS_TAG_APPS_MANAGEMENT_ALT1, SearchConcept::kAltTagEnd}},
@@ -143,7 +145,8 @@ AppsSection::AppsSection(Profile* profile,
: OsSettingsSection(profile, search_tag_registry),
pref_service_(pref_service),
arc_app_list_prefs_(arc_app_list_prefs) {
- registry()->AddSearchTags(GetAppsSearchConcepts());
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+ updater.AddSearchTags(GetAppsSearchConcepts());
if (arc::IsArcAllowedForProfile(profile)) {
pref_change_registrar_.Init(pref_service_);
@@ -179,17 +182,11 @@ void AppsSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
"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);
// We have 2 variants of Android apps settings. Default case, when the Play
// Store app exists we show expandable section that allows as to
@@ -220,6 +217,57 @@ void AppsSection::AddHandlers(content::WebUI* web_ui) {
}
}
+int AppsSection::GetSectionNameMessageId() const {
+ return IDS_SETTINGS_APPS_TITLE;
+}
+
+mojom::Section AppsSection::GetSection() const {
+ return mojom::Section::kApps;
+}
+
+mojom::SearchResultIcon AppsSection::GetSectionIcon() const {
+ return mojom::SearchResultIcon::kAppsGrid;
+}
+
+std::string AppsSection::GetSectionPath() const {
+ return mojom::kAppsSectionPath;
+}
+
+void AppsSection::RegisterHierarchy(HierarchyGenerator* generator) const {
+ // Manage apps.
+ generator->RegisterTopLevelSubpage(IDS_SETTINGS_APPS_LINK_TEXT,
+ mojom::Subpage::kAppManagement,
+ mojom::SearchResultIcon::kAppsGrid,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::kAppManagementSubpagePath);
+ // Note: The subpage name in the UI is updated dynamically based on the app
+ // being shown, but we use a generic "App details" string here.
+ generator->RegisterNestedSubpage(
+ IDS_SETTINGS_APP_DETAILS_TITLE, mojom::Subpage::kAppDetails,
+ mojom::Subpage::kAppManagement, mojom::SearchResultIcon::kAppsGrid,
+ mojom::SearchResultDefaultRank::kMedium, mojom::kAppDetailsSubpagePath);
+ generator->RegisterNestedSubpage(IDS_SETTINGS_APPS_PLUGIN_VM_SHARED_PATHS,
+ mojom::Subpage::kPluginVmSharedPaths,
+ mojom::Subpage::kAppManagement,
+ mojom::SearchResultIcon::kAppsGrid,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::kPluginVmSharedPathsSubpagePath);
+
+ // Google Play Store.
+ generator->RegisterTopLevelSubpage(IDS_SETTINGS_ANDROID_APPS_LABEL,
+ mojom::Subpage::kGooglePlayStore,
+ mojom::SearchResultIcon::kGooglePlay,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::kGooglePlayStoreSubpagePath);
+ static constexpr mojom::Setting kGooglePlayStoreSettings[] = {
+ mojom::Setting::kManageAndroidPreferences,
+ mojom::Setting::kRemovePlayStore,
+ mojom::Setting::kTurnOnPlayStore,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kGooglePlayStore,
+ kGooglePlayStoreSettings, generator);
+}
+
void AppsSection::OnAppRegistered(const std::string& app_id,
const ArcAppListPrefs::AppInfo& app_info) {
UpdateAndroidSearchTags();
@@ -264,34 +312,52 @@ void AppsSection::AddPluginVmLoadTimeData(
IDS_SETTINGS_APPS_PLUGIN_VM_SHARED_PATHS_INSTRUCTIONS_REMOVE},
{"pluginVmSharedPathsRemoveSharing",
IDS_SETTINGS_APPS_PLUGIN_VM_SHARED_PATHS_REMOVE_SHARING},
+ {"pluginVmSharedPathsListEmptyMessage",
+ IDS_SETTINGS_APPS_PLUGIN_VM_SHARED_PATHS_LIST_EMPTY_MESSAGE},
+ {"pluginVmPermissionDialogCameraLabel",
+ IDS_SETTINGS_APPS_PLUGIN_VM_PERMISSION_DIALOG_CAMERA_LABEL},
+ {"pluginVmPermissionDialogMicrophoneLabel",
+ IDS_SETTINGS_APPS_PLUGIN_VM_PERMISSION_DIALOG_MICROPHONE_LABEL},
+ {"pluginVmPermissionDialogRelaunchButton",
+ IDS_SETTINGS_APPS_PLUGIN_VM_PERMISSION_DIALOG_RELAUNCH_BUTTON},
};
AddLocalizedStringsBulk(html_source, kLocalizedStrings);
html_source->AddBoolean("showPluginVm",
ShowPluginVm(profile(), *pref_service_));
+ html_source->AddBoolean(
+ "showPluginVmCameraPermissions",
+ base::FeatureList::IsEnabled(
+ chromeos::features::kPluginVmShowCameraPermissions));
+ html_source->AddBoolean(
+ "showPluginVmMicrophonePermissions",
+ base::FeatureList::IsEnabled(
+ chromeos::features::kPluginVmShowMicrophonePermissions));
}
void AppsSection::UpdateAndroidSearchTags() {
- registry()->RemoveSearchTags(GetAndroidNoPlayStoreSearchConcepts());
- registry()->RemoveSearchTags(GetAndroidPlayStoreDisabledSearchConcepts());
- registry()->RemoveSearchTags(GetAndroidPlayStoreSearchConcepts());
- registry()->RemoveSearchTags(GetAndroidSettingsSearchConcepts());
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+
+ updater.RemoveSearchTags(GetAndroidNoPlayStoreSearchConcepts());
+ updater.RemoveSearchTags(GetAndroidPlayStoreDisabledSearchConcepts());
+ updater.RemoveSearchTags(GetAndroidPlayStoreSearchConcepts());
+ updater.RemoveSearchTags(GetAndroidSettingsSearchConcepts());
if (!arc::IsPlayStoreAvailable()) {
- registry()->AddSearchTags(GetAndroidNoPlayStoreSearchConcepts());
+ updater.AddSearchTags(GetAndroidNoPlayStoreSearchConcepts());
return;
}
if (!arc::IsArcPlayStoreEnabledForProfile(profile())) {
- registry()->AddSearchTags(GetAndroidPlayStoreDisabledSearchConcepts());
+ updater.AddSearchTags(GetAndroidPlayStoreDisabledSearchConcepts());
return;
}
- registry()->AddSearchTags(GetAndroidPlayStoreSearchConcepts());
+ updater.AddSearchTags(GetAndroidPlayStoreSearchConcepts());
if (arc_app_list_prefs_ &&
arc_app_list_prefs_->IsRegistered(arc::kSettingsAppId)) {
- registry()->AddSearchTags(GetAndroidSettingsSearchConcepts());
+ updater.AddSearchTags(GetAndroidSettingsSearchConcepts());
}
}
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/apps_section.h b/chromium/chrome/browser/ui/webui/settings/chromeos/apps_section.h
index ba926ba1652..d5217f6c693 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/apps_section.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/apps_section.h
@@ -33,6 +33,11 @@ class AppsSection : public OsSettingsSection, public ArcAppListPrefs::Observer {
// OsSettingsSection:
void AddLoadTimeData(content::WebUIDataSource* html_source) override;
void AddHandlers(content::WebUI* web_ui) override;
+ int GetSectionNameMessageId() const override;
+ mojom::Section GetSection() const override;
+ mojom::SearchResultIcon GetSectionIcon() const override;
+ std::string GetSectionPath() const override;
+ void RegisterHierarchy(HierarchyGenerator* generator) const override;
// ArcAppListPrefs::Observer:
void OnAppRegistered(const std::string& app_id,
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.cc
index 9b6fad55c74..2de04401ca6 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.cc
@@ -17,6 +17,8 @@
#include "chrome/grit/generated_resources.h"
#include "content/public/browser/web_ui_data_source.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
+#include "device/bluetooth/bluetooth_device.h"
+#include "device/bluetooth/chromeos/bluetooth_utils.h"
#include "device/bluetooth/dbus/bluez_dbus_manager.h"
#include "device/bluetooth/strings/grit/bluetooth_strings.h"
#include "ui/base/l10n/l10n_util.h"
@@ -28,37 +30,12 @@ namespace {
const std::vector<SearchConcept>& GetBluetoothSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
- {IDS_OS_SETTINGS_TAG_BLUETOOTH_PAIR,
- mojom::kBluetoothDevicesSubpagePath,
- mojom::SearchResultIcon::kBluetooth,
- mojom::SearchResultDefaultRank::kHigh,
- mojom::SearchResultType::kSetting,
- {.setting = mojom::Setting::kBluetoothPairDevice}},
- {IDS_OS_SETTINGS_TAG_BLUETOOTH_CONNECT,
- mojom::kBluetoothDevicesSubpagePath,
- mojom::SearchResultIcon::kBluetooth,
- mojom::SearchResultDefaultRank::kHigh,
- mojom::SearchResultType::kSetting,
- {.setting = mojom::Setting::kBluetoothConnectToDevice}},
{IDS_OS_SETTINGS_TAG_BLUETOOTH,
mojom::kBluetoothDevicesSubpagePath,
mojom::SearchResultIcon::kBluetooth,
- mojom::SearchResultDefaultRank::kHigh,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
{.subpage = mojom::Subpage::kBluetoothDevices}},
- {IDS_OS_SETTINGS_TAG_BLUETOOTH_DISCONNECT,
- mojom::kBluetoothDevicesSubpagePath,
- mojom::SearchResultIcon::kBluetooth,
- mojom::SearchResultDefaultRank::kHigh,
- mojom::SearchResultType::kSetting,
- {.setting = mojom::Setting::kBluetoothDisconnectFromDevice}},
- {IDS_OS_SETTINGS_TAG_BLUETOOTH_UNPAIR,
- mojom::kBluetoothDevicesSubpagePath,
- mojom::SearchResultIcon::kBluetooth,
- mojom::SearchResultDefaultRank::kHigh,
- mojom::SearchResultType::kSetting,
- {.setting = mojom::Setting::kBluetoothUnpairDevice},
- {IDS_OS_SETTINGS_TAG_BLUETOOTH_UNPAIR_ALT1, SearchConcept::kAltTagEnd}},
});
return *tags;
}
@@ -68,7 +45,7 @@ const std::vector<SearchConcept>& GetBluetoothOnSearchConcepts() {
{IDS_OS_SETTINGS_TAG_BLUETOOTH_TURN_OFF,
mojom::kBluetoothDevicesSubpagePath,
mojom::SearchResultIcon::kBluetooth,
- mojom::SearchResultDefaultRank::kHigh,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kBluetoothOnOff},
{IDS_OS_SETTINGS_TAG_BLUETOOTH_TURN_OFF_ALT1,
@@ -82,7 +59,7 @@ const std::vector<SearchConcept>& GetBluetoothOffSearchConcepts() {
{IDS_OS_SETTINGS_TAG_BLUETOOTH_TURN_ON,
mojom::kBluetoothDevicesSubpagePath,
mojom::SearchResultIcon::kBluetooth,
- mojom::SearchResultDefaultRank::kHigh,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kBluetoothOnOff},
{IDS_OS_SETTINGS_TAG_BLUETOOTH_TURN_ON_ALT1, SearchConcept::kAltTagEnd}},
@@ -90,6 +67,55 @@ const std::vector<SearchConcept>& GetBluetoothOffSearchConcepts() {
return *tags;
}
+const std::vector<SearchConcept>& GetBluetoothConnectableSearchConcepts() {
+ static const base::NoDestructor<std::vector<SearchConcept>> tags({
+ {IDS_OS_SETTINGS_TAG_BLUETOOTH_CONNECT,
+ mojom::kBluetoothDevicesSubpagePath,
+ mojom::SearchResultIcon::kBluetooth,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kBluetoothConnectToDevice}},
+ });
+ return *tags;
+}
+
+const std::vector<SearchConcept>& GetBluetoothConnectedSearchConcepts() {
+ static const base::NoDestructor<std::vector<SearchConcept>> tags({
+ {IDS_OS_SETTINGS_TAG_BLUETOOTH_DISCONNECT,
+ mojom::kBluetoothDevicesSubpagePath,
+ mojom::SearchResultIcon::kBluetooth,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kBluetoothDisconnectFromDevice}},
+ });
+ return *tags;
+}
+
+const std::vector<SearchConcept>& GetBluetoothPairableSearchConcepts() {
+ static const base::NoDestructor<std::vector<SearchConcept>> tags({
+ {IDS_OS_SETTINGS_TAG_BLUETOOTH_PAIR,
+ mojom::kBluetoothDevicesSubpagePath,
+ mojom::SearchResultIcon::kBluetooth,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kBluetoothPairDevice}},
+ });
+ return *tags;
+}
+
+const std::vector<SearchConcept>& GetBluetoothPairedSearchConcepts() {
+ static const base::NoDestructor<std::vector<SearchConcept>> tags({
+ {IDS_OS_SETTINGS_TAG_BLUETOOTH_UNPAIR,
+ mojom::kBluetoothDevicesSubpagePath,
+ mojom::SearchResultIcon::kBluetooth,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kBluetoothUnpairDevice},
+ {IDS_OS_SETTINGS_TAG_BLUETOOTH_UNPAIR_ALT1, SearchConcept::kAltTagEnd}},
+ });
+ return *tags;
+}
+
} // namespace
BluetoothSection::BluetoothSection(Profile* profile,
@@ -165,6 +191,40 @@ void BluetoothSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
chromeos::bluetooth_dialog::AddLocalizedStrings(html_source);
}
+int BluetoothSection::GetSectionNameMessageId() const {
+ return IDS_SETTINGS_BLUETOOTH;
+}
+
+mojom::Section BluetoothSection::GetSection() const {
+ return mojom::Section::kBluetooth;
+}
+
+mojom::SearchResultIcon BluetoothSection::GetSectionIcon() const {
+ return mojom::SearchResultIcon::kBluetooth;
+}
+
+std::string BluetoothSection::GetSectionPath() const {
+ return mojom::kBluetoothSectionPath;
+}
+
+void BluetoothSection::RegisterHierarchy(HierarchyGenerator* generator) const {
+ generator->RegisterTopLevelSubpage(IDS_SETTINGS_BLUETOOTH,
+ mojom::Subpage::kBluetoothDevices,
+ mojom::SearchResultIcon::kBluetooth,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::kBluetoothDevicesSubpagePath);
+ static constexpr mojom::Setting kBluetoothDevicesSettings[] = {
+ mojom::Setting::kBluetoothOnOff,
+ mojom::Setting::kBluetoothConnectToDevice,
+ mojom::Setting::kBluetoothDisconnectFromDevice,
+ mojom::Setting::kBluetoothPairDevice,
+ mojom::Setting::kBluetoothUnpairDevice,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kBluetoothDevices,
+ kBluetoothDevicesSettings, generator);
+ generator->RegisterTopLevelAltSetting(mojom::Setting::kBluetoothOnOff);
+}
+
void BluetoothSection::AdapterPresentChanged(device::BluetoothAdapter* adapter,
bool present) {
UpdateSearchTags();
@@ -175,6 +235,21 @@ void BluetoothSection::AdapterPoweredChanged(device::BluetoothAdapter* adapter,
UpdateSearchTags();
}
+void BluetoothSection::DeviceAdded(device::BluetoothAdapter* adapter,
+ device::BluetoothDevice* device) {
+ UpdateSearchTags();
+}
+
+void BluetoothSection::DeviceChanged(device::BluetoothAdapter* adapter,
+ device::BluetoothDevice* device) {
+ UpdateSearchTags();
+}
+
+void BluetoothSection::DeviceRemoved(device::BluetoothAdapter* adapter,
+ device::BluetoothDevice* device) {
+ UpdateSearchTags();
+}
+
void BluetoothSection::OnFetchBluetoothAdapter(
scoped_refptr<device::BluetoothAdapter> bluetooth_adapter) {
bluetooth_adapter_ = bluetooth_adapter;
@@ -183,20 +258,60 @@ void BluetoothSection::OnFetchBluetoothAdapter(
}
void BluetoothSection::UpdateSearchTags() {
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+
// Start with no search tags, then add them below if appropriate.
- registry()->RemoveSearchTags(GetBluetoothSearchConcepts());
- registry()->RemoveSearchTags(GetBluetoothOnSearchConcepts());
- registry()->RemoveSearchTags(GetBluetoothOffSearchConcepts());
+ updater.RemoveSearchTags(GetBluetoothSearchConcepts());
+ updater.RemoveSearchTags(GetBluetoothOnSearchConcepts());
+ updater.RemoveSearchTags(GetBluetoothOffSearchConcepts());
+ updater.RemoveSearchTags(GetBluetoothConnectableSearchConcepts());
+ updater.RemoveSearchTags(GetBluetoothConnectedSearchConcepts());
+ updater.RemoveSearchTags(GetBluetoothPairableSearchConcepts());
+ updater.RemoveSearchTags(GetBluetoothPairedSearchConcepts());
if (!bluetooth_adapter_->IsPresent())
return;
- registry()->AddSearchTags(GetBluetoothSearchConcepts());
+ updater.AddSearchTags(GetBluetoothSearchConcepts());
+
+ if (!bluetooth_adapter_->IsPowered()) {
+ updater.AddSearchTags(GetBluetoothOffSearchConcepts());
+ return;
+ }
+
+ updater.AddSearchTags(GetBluetoothOnSearchConcepts());
+
+ // Filter devices so that only those shown in the UI are returned. Note that
+ // passing |max_devices| of 0 indicates that there is no maximum.
+ device::BluetoothAdapter::DeviceList devices =
+ device::FilterBluetoothDeviceList(bluetooth_adapter_->GetDevices(),
+ device::BluetoothFilterType::KNOWN,
+ /*max_devices=*/0);
+
+ bool connectable_device_exists = false;
+ bool connected_device_exists = false;
+ bool pairable_device_exists = false;
+ bool paired_device_exists = false;
+ for (const device::BluetoothDevice* device : devices) {
+ // Note: Device must be paired to be connectable.
+ if (device->IsPaired() && device->IsConnectable() && !device->IsConnected())
+ connectable_device_exists = true;
+ if (device->IsConnected())
+ connected_device_exists = true;
+ if (device->IsPairable() && !device->IsPaired())
+ pairable_device_exists = true;
+ if (device->IsPaired())
+ paired_device_exists = true;
+ }
- if (bluetooth_adapter_->IsPowered())
- registry()->AddSearchTags(GetBluetoothOnSearchConcepts());
- else
- registry()->AddSearchTags(GetBluetoothOffSearchConcepts());
+ if (connectable_device_exists)
+ updater.AddSearchTags(GetBluetoothConnectableSearchConcepts());
+ if (connected_device_exists)
+ updater.AddSearchTags(GetBluetoothConnectedSearchConcepts());
+ if (pairable_device_exists)
+ updater.AddSearchTags(GetBluetoothPairableSearchConcepts());
+ if (paired_device_exists)
+ updater.AddSearchTags(GetBluetoothPairedSearchConcepts());
}
} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.h b/chromium/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.h
index 0586828bb1f..e187a244e2b 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/bluetooth_section.h
@@ -31,12 +31,23 @@ class BluetoothSection : public OsSettingsSection,
private:
// OsSettingsSection:
void AddLoadTimeData(content::WebUIDataSource* html_source) override;
+ int GetSectionNameMessageId() const override;
+ mojom::Section GetSection() const override;
+ mojom::SearchResultIcon GetSectionIcon() const override;
+ std::string GetSectionPath() const override;
+ void RegisterHierarchy(HierarchyGenerator* generator) const override;
// device::BluetoothAdapter::Observer:
void AdapterPresentChanged(device::BluetoothAdapter* adapter,
bool present) override;
void AdapterPoweredChanged(device::BluetoothAdapter* adapter,
bool powered) override;
+ void DeviceAdded(device::BluetoothAdapter* adapter,
+ device::BluetoothDevice* device) override;
+ void DeviceChanged(device::BluetoothAdapter* adapter,
+ device::BluetoothDevice* device) override;
+ void DeviceRemoved(device::BluetoothAdapter* adapter,
+ device::BluetoothDevice* device) override;
void OnFetchBluetoothAdapter(
scoped_refptr<device::BluetoothAdapter> bluetooth_adapter);
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
index 7c8d870bb91..5fd2a36e803 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.cc
@@ -17,6 +17,7 @@
#include "chrome/browser/profiles/profile.h"
#include "chromeos/cryptohome/cryptohome_util.h"
#include "chromeos/dbus/cryptohome/cryptohome_client.h"
+#include "chromeos/dbus/dlcservice/dlcservice_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"
@@ -392,6 +393,32 @@ void OtherUsersSizeCalculator::OnGetOtherUserSize(
NotifySizeCalculated(other_users_total_bytes);
}
+DlcsSizeCalculator::DlcsSizeCalculator()
+ : SizeCalculator(CalculationType::kDlcs) {}
+
+DlcsSizeCalculator::~DlcsSizeCalculator() = default;
+
+void DlcsSizeCalculator::PerformCalculation() {
+ DlcserviceClient::Get()->GetExistingDlcs(base::BindOnce(
+ &DlcsSizeCalculator::OnGetExistingDlcs, weak_ptr_factory_.GetWeakPtr()));
+}
+
+void DlcsSizeCalculator::OnGetExistingDlcs(
+ const std::string& err,
+ const dlcservice::DlcsWithContent& dlcs_with_content) {
+ if (err != dlcservice::kErrorNone) {
+ NotifySizeCalculated(0);
+ return;
+ }
+ base::ListValue dlc_metadata_list;
+ int64_t dlc_total_size_in_bytes = 0;
+ for (int i = 0; i < dlcs_with_content.dlc_infos_size(); i++) {
+ const auto& dlc_info = dlcs_with_content.dlc_infos(i);
+ dlc_total_size_in_bytes += dlc_info.used_bytes_on_disk();
+ }
+ NotifySizeCalculated(dlc_total_size_in_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
index 8f483f50b95..23fc718f6f6 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.h
@@ -25,6 +25,10 @@
class Profile;
+namespace dlcservice {
+class DlcsWithContent;
+} // namespace dlcservice
+
namespace chromeos {
namespace settings {
namespace calculator {
@@ -42,7 +46,8 @@ class SizeCalculator {
kAppsExtensions,
kCrostini,
kOtherUsers,
- kLast = kOtherUsers,
+ kDlcs,
+ kLast = kDlcs,
kSystem,
};
@@ -289,6 +294,27 @@ class OtherUsersSizeCalculator : public SizeCalculator {
base::WeakPtrFactory<OtherUsersSizeCalculator> weak_ptr_factory_{this};
};
+// Class handling the calculation of all DLC size.
+class DlcsSizeCalculator : public SizeCalculator {
+ public:
+ DlcsSizeCalculator();
+ ~DlcsSizeCalculator() override;
+
+ DlcsSizeCalculator(const DlcsSizeCalculator&) = delete;
+ DlcsSizeCalculator& operator=(const DlcsSizeCalculator&) = delete;
+
+ private:
+ friend class DlcsSizeTestAPI;
+
+ void PerformCalculation() override;
+
+ // Callback to update the total size of existing DLCs.
+ void OnGetExistingDlcs(const std::string& err,
+ const dlcservice::DlcsWithContent& dlcs_with_content);
+
+ base::WeakPtrFactory<DlcsSizeCalculator> weak_ptr_factory_{this};
+};
+
} // namespace calculator
} // namespace settings
} // namespace chromeos
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
index 2e0850df244..4a15d946c26 100644
--- 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
@@ -149,6 +149,25 @@ class OtherUsersSizeTestAPI {
OtherUsersSizeCalculator* other_users_size_calculator_;
};
+class DlcsSizeTestAPI {
+ public:
+ explicit DlcsSizeTestAPI(StorageHandler* handler,
+ DlcsSizeCalculator* dlcs_size_calculator) {
+ dlcs_size_calculator_ = dlcs_size_calculator;
+ dlcs_size_calculator_->AddObserver(handler);
+ }
+
+ void StartCalculation() { dlcs_size_calculator_->StartCalculation(); }
+
+ void SimulateOnGetExistingDlcs(
+ const std::string& err,
+ const dlcservice::DlcsWithContent& dlcs_with_content) {
+ dlcs_size_calculator_->OnGetExistingDlcs(err, dlcs_with_content);
+ }
+
+ private:
+ DlcsSizeCalculator* dlcs_size_calculator_;
+};
} // namespace calculator
} // namespace settings
} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/constants/constants_util.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/constants/constants_util.cc
index d5bdaf20d53..263d760b558 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/constants/constants_util.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/constants/constants_util.cc
@@ -17,7 +17,7 @@ std::vector<T> All() {
int32_t max_value = static_cast<int32_t>(T::kMaxValue);
std::vector<T> all;
- for (int32_t i = min_value; i < max_value; ++i) {
+ for (int32_t i = min_value; i <= max_value; ++i) {
T current = static_cast<T>(i);
// Not every value between the min and max values is valid:
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom b/chromium/chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom
index b1837490f1c..ecb574c87e6 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom
@@ -49,6 +49,7 @@ enum Subpage {
// MultiDevice section.
kMultiDeviceFeatures = 200,
kSmartLock = 201,
+ kNearbyShare = 202,
// People section.
kMyAccounts = 300,
@@ -61,19 +62,19 @@ enum Subpage {
kKerberos = 307,
// Device section.
- kDevice = 400,
- kPointers = 401,
- kKeyboard = 402,
- kStylus = 403,
- kDisplay = 404,
- kStorage = 405,
- kExternalStorage = 406,
- kDlc = 407,
- kPower = 408,
+ kPointers = 400,
+ kKeyboard = 401,
+ kStylus = 402,
+ kDisplay = 403,
+ kStorage = 404,
+ kExternalStorage = 405,
+ kDlc = 406,
+ kPower = 407,
// Personalization section.
kChangePicture = 500,
kAmbientMode = 501,
+ kAmbientModePhotos= 502,
// Search and Assistant section.
kAssistant = 600,
@@ -91,7 +92,6 @@ enum Subpage {
kCrostiniBackupAndRestore = 803,
kCrostiniDevelopAndroidApps = 804,
kCrostiniPortForwarding = 805,
- kCrostiniDiskResize = 806,
// Note: Deprecated Plugin VM section has no subpages.
@@ -104,6 +104,7 @@ enum Subpage {
kLanguagesAndInputDetails = 1200,
kManageInputMethods = 1201,
kSmartInputs = 1202,
+ kInputMethodOptions = 1203,
// Files section.
kNetworkFileShares = 1300,
@@ -143,6 +144,7 @@ const string kBluetoothDevicesSubpagePath = "bluetoothDevices";
const string kMultiDeviceSectionPath = "multidevice";
const string kMultiDeviceFeaturesSubpagePath = "multidevice/features";
const string kSmartLockSubpagePath = "multidevice/features/smartLock";
+const string kNearbyShareSubpagePath = "multidevice/nearbyshare";
// People section.
const string kPeopleSectionPath = "osPeople";
@@ -151,7 +153,7 @@ const string kSyncSubpagePath = "osSync";
const string kSyncDeprecatedSubpagePath = "syncSetup";
const string kSyncDeprecatedAdvancedSubpagePath = "syncSetup/advanced";
const string kSecurityAndSignInSubpagePath = "lockScreen";
-const string kFingerprintSubpathPath = "lockScreen/fingerprint";
+const string kFingerprintSubpagePath = "lockScreen/fingerprint";
const string kManageOtherPeopleSubpagePath = "accounts";
const string kKerberosSubpagePath = "kerberosAccounts";
@@ -170,6 +172,7 @@ const string kPowerSubpagePath = "power";
const string kPersonalizationSectionPath = "personalization";
const string kChangePictureSubpagePath = "changePicture";
const string kAmbientModeSubpagePath = "ambientMode";
+const string kAmbientModePhotosSubpagePath = "ambientMode/photos";
// Search and Assistant section.
const string kSearchAndAssistantSectionPath = "osSearch";
@@ -191,7 +194,6 @@ const string kCrostiniUsbPreferencesSubpagePath = "crostini/sharedUsbDevices";
const string kCrostiniBackupAndRestoreSubpagePath = "crostini/exportImport";
const string kCrostiniDevelopAndroidAppsSubpagePath = "crostini/androidAdb";
const string kCrostiniPortForwardingSubpagePath = "crostini/portForwarding";
-const string kCrostiniDiskResizeSubpagePath = "crostini/diskResize";
// Date and Time section.
const string kDateAndTimeSectionPath = "dateTime";
@@ -204,7 +206,8 @@ const string kPrivacyAndSecuritySectionPath = "osPrivacy";
const string kLanguagesAndInputSectionPath = "osLanguages";
const string kLanguagesAndInputDetailsSubpagePath = "osLanguages/details";
const string kManageInputMethodsSubpagePath = "osLanguages/inputMethods";
-const string kSmartInputsSubagePath = "osLanguages/smartInputs";
+const string kSmartInputsSubpagePath = "osLanguages/smartInputs";
+const string kInputMethodOptionsSubpagePath = "osLanguages/inputMethodOptions";
// Files section.
const string kFilesSectionPath = "files";
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/constants/routes_util.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/constants/routes_util.cc
index 957b28fd7cc..d2fa7499076 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/constants/routes_util.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/constants/routes_util.cc
@@ -37,13 +37,14 @@ bool IsOSSettingsSubPage(const std::string& sub_page) {
chromeos::settings::mojom::kMultiDeviceSectionPath,
chromeos::settings::mojom::kMultiDeviceFeaturesSubpagePath,
chromeos::settings::mojom::kSmartLockSubpagePath,
+ chromeos::settings::mojom::kNearbyShareSubpagePath,
// People section.
chromeos::settings::mojom::kPeopleSectionPath,
chromeos::settings::mojom::kMyAccountsSubpagePath,
chromeos::settings::mojom::kSyncSubpagePath,
chromeos::settings::mojom::kSecurityAndSignInSubpagePath,
- chromeos::settings::mojom::kFingerprintSubpathPath,
+ chromeos::settings::mojom::kFingerprintSubpagePath,
chromeos::settings::mojom::kManageOtherPeopleSubpagePath,
chromeos::settings::mojom::kKerberosSubpagePath,
@@ -82,7 +83,6 @@ bool IsOSSettingsSubPage(const std::string& sub_page) {
chromeos::settings::mojom::kCrostiniBackupAndRestoreSubpagePath,
chromeos::settings::mojom::kCrostiniDevelopAndroidAppsSubpagePath,
chromeos::settings::mojom::kCrostiniPortForwardingSubpagePath,
- chromeos::settings::mojom::kCrostiniDiskResizeSubpagePath,
// Date and Time section.
chromeos::settings::mojom::kDateAndTimeSectionPath,
@@ -95,7 +95,8 @@ bool IsOSSettingsSubPage(const std::string& sub_page) {
chromeos::settings::mojom::kLanguagesAndInputSectionPath,
chromeos::settings::mojom::kLanguagesAndInputDetailsSubpagePath,
chromeos::settings::mojom::kManageInputMethodsSubpagePath,
- chromeos::settings::mojom::kSmartInputsSubagePath,
+ chromeos::settings::mojom::kSmartInputsSubpagePath,
+ chromeos::settings::mojom::kInputMethodOptionsSubpagePath,
// Files section.
chromeos::settings::mojom::kFilesSectionPath,
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom b/chromium/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom
index 634b625b075..19339269f3b 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom
@@ -16,7 +16,7 @@ enum Setting {
kDisconnectWifiNetwork = 5,
kPreferWifiNetwork = 6,
kForgetWifiNetwork = 7,
- kConfigureWifi = 8,
+ kWifiAddNetwork = 8,
kWifiAutoConfigureIp = 9,
kWifiDns = 10,
kWifiProxy = 11,
@@ -31,7 +31,9 @@ enum Setting {
kCellularProxy = 20,
kCellularAutoConnectToNetwork = 21,
kInstantTetheringOnOff = 22,
- kDisconnectTetherNetwork = 22,
+ kDisconnectTetherNetwork = 23,
+ kWifiMetered = 24,
+ kCellularMetered = 25,
// Bluetooth section.
kBluetoothOnOff = 100,
@@ -49,11 +51,12 @@ enum Setting {
kMessagesSetUp = 205,
kMessagesOnOff = 206,
kForgetPhone = 207,
+ kNearbyShareOnOff = 208,
// People section.
kAddAccount = 300,
kRemoveAccount = 301,
- kSyncOnOff = 302,
+ kSplitSyncOnOff = 302,
kLockScreen = 303,
kChangeAuthPin = 304,
kGuestBrowsing = 305,
@@ -67,6 +70,10 @@ enum Setting {
kAddFingerprint = 313,
kRemoveFingerprint = 314,
kSetUpParentalControls = 315,
+ kNonSplitSyncEncryptionOptions = 316,
+ kAutocompleteSearchesAndUrls = 317,
+ kMakeSearchesAndBrowsingBetter = 318,
+ kGoogleDriveSearchSuggestions = 319,
// Device section.
kTouchpadTapToClick = 400,
@@ -91,16 +98,26 @@ enum Setting {
kStylusLatestNoteOnLockScreen = 419,
kDisplayOrientation = 420,
kDisplayArrangement = 421,
- kPowerIdleBehavior = 422,
+ kPowerIdleBehaviorWhileCharging = 422,
kPowerSource = 423,
kSleepWhenLaptopLidClosed = 424,
kDisplayResolution = 425,
kDisplayRefreshRate = 426,
+ kRemoveDlc = 427,
+ kDisplayMirroring = 428,
+ kAllowWindowsToSpanDisplays = 429,
+ kAmbientColors = 430,
+ kTouchscreenCalibration = 431,
+ kNightLightColorTemperature = 432,
+ kPowerIdleBehaviorWhileOnBattery = 433,
+ kDisplayOverscan = 434,
// Personalization section.
kOpenWallpaper = 500,
kAmbientModeOnOff = 501,
kAmbientModeSource = 502,
+ kChangeDeviceAccountImage = 503,
+ kAmbientModeUpdatePhotosContainers = 504,
// Search and Assistant section.
kPreferredSearchEngine = 600,
@@ -110,6 +127,7 @@ enum Setting {
kAssistantOkGoogle = 604,
kAssistantNotifications = 605,
kAssistantVoiceInput = 606,
+ kTrainAssistantVoiceModel = 607,
// Apps section.
kManageAndroidPreferences = 700,
@@ -141,6 +159,7 @@ enum Setting {
kAddLanguage = 1200,
kShowInputOptionsInShelf = 1201,
kShowPersonalInformationSuggestions = 1202,
+ kShowEmojiSuggestions = 1203,
// Files section.
kGoogleDriveConnection = 1300,
@@ -178,6 +197,8 @@ enum Setting {
kSwitchActionAutoScan = 1524,
kSwitchActionAutoScanKeyboard = 1525,
kGetImageDescriptionsFromGoogle = 1526,
+ kLiveCaptions = 1527,
+ kEnableCursorColor = 1528,
// Reset section.
kPowerwash = 1600,
@@ -185,4 +206,9 @@ enum Setting {
// About Chrome OS section.
kChangeChromeChannel = 1700,
kCopyDetailedBuildInfo = 1701,
+ kCheckForOsUpdate = 1702,
+ kSeeWhatsNew = 1703,
+ kGetHelpWithChromeOs = 1704,
+ kReportAnIssue = 1705,
+ kTermsOfService = 1706,
};
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 bf1d6db4c78..5c934d15a17 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc
@@ -104,6 +104,11 @@ void CrostiniHandler::RegisterMessages() {
base::BindRepeating(&CrostiniHandler::HandleQueryArcAdbRequest,
weak_ptr_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
+ "getCanChangeArcAdbSideloading",
+ base::BindRepeating(
+ &CrostiniHandler::HandleCanChangeArcAdbSideloadingRequest,
+ weak_ptr_factory_.GetWeakPtr()));
+ web_ui()->RegisterMessageCallback(
"enableArcAdbSideload",
base::BindRepeating(&CrostiniHandler::HandleEnableArcAdbRequest,
weak_ptr_factory_.GetWeakPtr()));
@@ -191,6 +196,20 @@ void CrostiniHandler::OnJavascriptAllowed() {
}
crostini::CrostiniExportImport::GetForProfile(profile_)->AddObserver(this);
crostini::CrostiniPortForwarder::GetForProfile(profile_)->AddObserver(this);
+
+ // Observe ADB sideloading device policy and react to its changes
+ adb_sideloading_device_policy_subscription_ =
+ chromeos::CrosSettings::Get()->AddSettingsObserver(
+ chromeos::kDeviceCrostiniArcAdbSideloadingAllowed,
+ base::BindRepeating(&CrostiniHandler::FetchCanChangeAdbSideloading,
+ weak_ptr_factory_.GetWeakPtr()));
+
+ // Observe ADB sideloading user policy and react to its changes
+ pref_change_registrar_.Init(profile_->GetPrefs());
+ pref_change_registrar_.Add(
+ crostini::prefs::kCrostiniArcAdbSideloadingUserPref,
+ base::BindRepeating(&CrostiniHandler::FetchCanChangeAdbSideloading,
+ weak_ptr_factory_.GetWeakPtr()));
}
void CrostiniHandler::OnJavascriptDisallowed() {
@@ -206,6 +225,9 @@ void CrostiniHandler::OnJavascriptDisallowed() {
crostini::CrostiniExportImport::GetForProfile(profile_)->RemoveObserver(this);
crostini::CrostiniPortForwarder::GetForProfile(profile_)->RemoveObserver(
this);
+
+ adb_sideloading_device_policy_subscription_.reset();
+ pref_change_registrar_.RemoveAll();
}
void CrostiniHandler::HandleRequestCrostiniInstallerView(
@@ -437,7 +459,15 @@ void CrostiniHandler::OnQueryAdbSideload(
void CrostiniHandler::HandleEnableArcAdbRequest(const base::ListValue* args) {
CHECK_EQ(0U, args->GetList().size());
- if (!CheckEligibilityToChangeArcAdbSideloading())
+
+ crostini::CrostiniFeatures::Get()->CanChangeAdbSideloading(
+ profile_, base::BindOnce(&CrostiniHandler::OnCanEnableArcAdbSideloading,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void CrostiniHandler::OnCanEnableArcAdbSideloading(
+ bool can_change_adb_sideloading) {
+ if (!can_change_adb_sideloading)
return;
LogEvent(CrostiniSettingsEvent::kEnableAdbSideloading);
@@ -451,7 +481,15 @@ void CrostiniHandler::HandleEnableArcAdbRequest(const base::ListValue* args) {
void CrostiniHandler::HandleDisableArcAdbRequest(const base::ListValue* args) {
CHECK_EQ(0U, args->GetList().size());
- if (!CheckEligibilityToChangeArcAdbSideloading())
+
+ crostini::CrostiniFeatures::Get()->CanChangeAdbSideloading(
+ profile_, base::BindOnce(&CrostiniHandler::OnCanDisableArcAdbSideloading,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void CrostiniHandler::OnCanDisableArcAdbSideloading(
+ bool can_change_adb_sideloading) {
+ if (!can_change_adb_sideloading)
return;
LogEvent(CrostiniSettingsEvent::kDisableAdbSideloading);
@@ -464,10 +502,6 @@ void CrostiniHandler::HandleDisableArcAdbRequest(const base::ListValue* args) {
power_manager::REQUEST_RESTART_FOR_USER, "disable adb sideloading");
}
-bool CrostiniHandler::CheckEligibilityToChangeArcAdbSideloading() const {
- return crostini::CrostiniFeatures::Get()->CanChangeAdbSideloading(profile_);
-}
-
void CrostiniHandler::LaunchTerminal() {
crostini::LaunchCrostiniApp(
profile_, crostini::GetTerminalId(),
@@ -502,6 +536,26 @@ void CrostiniHandler::HandleQueryArcAdbRequest(const base::ListValue* args) {
weak_ptr_factory_.GetWeakPtr()));
}
+void CrostiniHandler::HandleCanChangeArcAdbSideloadingRequest(
+ const base::ListValue* args) {
+ AllowJavascript();
+ CHECK_EQ(0U, args->GetList().size());
+
+ FetchCanChangeAdbSideloading();
+}
+
+void CrostiniHandler::FetchCanChangeAdbSideloading() {
+ crostini::CrostiniFeatures::Get()->CanChangeAdbSideloading(
+ profile_, base::BindOnce(&CrostiniHandler::OnCanChangeArcAdbSideloading,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void CrostiniHandler::OnCanChangeArcAdbSideloading(
+ bool can_change_arc_adb_sideloading) {
+ FireWebUIListener("crostini-can-change-arc-adb-sideload-changed",
+ base::Value(can_change_arc_adb_sideloading));
+}
+
void CrostiniHandler::HandleCrostiniUpgraderDialogStatusRequest(
const base::ListValue* args) {
AllowJavascript();
@@ -536,6 +590,11 @@ void CrostiniHandler::HandleAddCrostiniPortForward(
int protocol_type = args->GetList()[4].GetInt();
std::string label = args->GetList()[5].GetString();
+ if (!crostini::CrostiniFeatures::Get()->IsPortForwardingAllowed(profile_)) {
+ OnPortForwardComplete(callback_id, false);
+ return;
+ }
+
crostini::CrostiniPortForwarder::GetForProfile(profile_)->AddPort(
crostini::ContainerId(std::move(vm_name), std::move(container_name)),
port_number,
@@ -559,6 +618,11 @@ void CrostiniHandler::HandleRemoveCrostiniPortForward(
int protocol_type;
CHECK(args->GetInteger(4, &protocol_type));
+ if (!crostini::CrostiniFeatures::Get()->IsPortForwardingAllowed(profile_)) {
+ OnPortForwardComplete(callback_id, false);
+ return;
+ }
+
crostini::CrostiniPortForwarder::GetForProfile(profile_)->RemovePort(
crostini::ContainerId(std::move(vm_name), std::move(container_name)),
port_number,
@@ -574,6 +638,10 @@ void CrostiniHandler::HandleRemoveAllCrostiniPortForwards(
std::string vm_name = args_list[0].GetString();
std::string container_name = args_list[1].GetString();
+ if (!crostini::CrostiniFeatures::Get()->IsPortForwardingAllowed(profile_)) {
+ return;
+ }
+
crostini::CrostiniPortForwarder::GetForProfile(profile_)->RemoveAllPorts(
crostini::ContainerId(std::move(vm_name), std::move(container_name)));
}
@@ -593,6 +661,11 @@ void CrostiniHandler::HandleActivateCrostiniPortForward(
int protocol_type;
CHECK(args->GetInteger(4, &protocol_type));
+ if (!crostini::CrostiniFeatures::Get()->IsPortForwardingAllowed(profile_)) {
+ OnPortForwardComplete(callback_id, false);
+ return;
+ }
+
crostini::CrostiniPortForwarder::GetForProfile(profile_)->ActivatePort(
crostini::ContainerId(std::move(vm_name), std::move(container_name)),
port_number,
@@ -616,6 +689,11 @@ void CrostiniHandler::HandleDeactivateCrostiniPortForward(
int protocol_type;
CHECK(args->GetInteger(4, &protocol_type));
+ if (!crostini::CrostiniFeatures::Get()->IsPortForwardingAllowed(profile_)) {
+ OnPortForwardComplete(callback_id, false);
+ return;
+ }
+
crostini::CrostiniPortForwarder::GetForProfile(profile_)->DeactivatePort(
crostini::ContainerId(std::move(vm_name), std::move(container_name)),
port_number,
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 b1f5b8162bc..5867245850c 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.h
@@ -11,9 +11,11 @@
#include "chrome/browser/chromeos/crostini/crostini_export_import.h"
#include "chrome/browser/chromeos/crostini/crostini_manager.h"
#include "chrome/browser/chromeos/crostini/crostini_port_forwarder.h"
+#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/chromeos/usb/cros_usb_detector.h"
#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
#include "chromeos/dbus/session_manager/session_manager_client.h"
+#include "components/prefs/pref_change_registrar.h"
class Profile;
@@ -83,8 +85,14 @@ class CrostiniHandler : public ::settings::SettingsPageUIHandler,
void HandleQueryArcAdbRequest(const base::ListValue* args);
// Handle a request for enabling adb sideloading in ARC.
void HandleEnableArcAdbRequest(const base::ListValue* args);
+ // Called after establishing whether enabling adb sideloading is allowed for
+ // the user and device
+ void OnCanEnableArcAdbSideloading(bool can_change_adb_sideloading);
// Handle a request for disabling adb sideloading in ARC.
void HandleDisableArcAdbRequest(const base::ListValue* args);
+ // Called after establishing whether disabling adb sideloading is allowed for
+ // the user and device
+ void OnCanDisableArcAdbSideloading(bool can_change_adb_sideloading);
// Launch the Crostini terminal.
void LaunchTerminal();
// Handle a request for showing the container upgrade view.
@@ -93,9 +101,6 @@ class CrostiniHandler : public ::settings::SettingsPageUIHandler,
void OnQueryAdbSideload(
SessionManagerClient::AdbSideloadResponseCode response_code,
bool enabled);
- // 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.
@@ -142,8 +147,17 @@ class CrostiniHandler : public ::settings::SettingsPageUIHandler,
void HandleSetCrostiniMicSharingEnabled(const base::ListValue* args);
// Handles a request for getting the permissions for Crostini Mic access.
void HandleGetCrostiniMicSharingEnabled(const base::ListValue* args);
+ // Handle a request for checking permission for changing ARC adb sideloading.
+ void HandleCanChangeArcAdbSideloadingRequest(const base::ListValue* args);
+ // Get permission of changing ARC adb sideloading
+ void FetchCanChangeAdbSideloading();
+ // Callback of FetchCanChangeAdbSideloading.
+ void OnCanChangeArcAdbSideloading(bool can_change_arc_adb_sideloading);
Profile* profile_;
+ std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
+ adb_sideloading_device_policy_subscription_;
+ PrefChangeRegistrar pref_change_registrar_;
// weak_ptr_factory_ should always be last member.
base::WeakPtrFactory<CrostiniHandler> weak_ptr_factory_{this};
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_section.cc
index f25ce803272..546c2ff9270 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_section.cc
@@ -36,21 +36,15 @@ namespace chromeos {
namespace settings {
namespace {
-const std::vector<SearchConcept>& GetCrostiniSearchConcepts() {
+const std::vector<SearchConcept>& GetCrostiniOptedInSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
{IDS_OS_SETTINGS_TAG_CROSTINI,
mojom::kCrostiniDetailsSubpagePath,
mojom::SearchResultIcon::kPenguin,
- mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultDefaultRank::kHigh,
mojom::SearchResultType::kSubpage,
{.subpage = mojom::Subpage::kCrostiniDetails},
{IDS_OS_SETTINGS_TAG_CROSTINI_ALT1, SearchConcept::kAltTagEnd}},
- });
- return *tags;
-}
-
-const std::vector<SearchConcept>& GetCrostiniOptedInSearchConcepts() {
- static const base::NoDestructor<std::vector<SearchConcept>> tags({
{IDS_OS_SETTINGS_TAG_CROSTINI_USB_PREFERENCES,
mojom::kCrostiniUsbPreferencesSubpagePath,
mojom::SearchResultIcon::kPenguin,
@@ -88,6 +82,13 @@ const std::vector<SearchConcept>& GetCrostiniOptedInSearchConcepts() {
const std::vector<SearchConcept>& GetCrostiniOptedOutSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
+ {IDS_OS_SETTINGS_TAG_CROSTINI,
+ mojom::kCrostiniSectionPath,
+ mojom::SearchResultIcon::kPenguin,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSection,
+ {.section = mojom::Section::kCrostini},
+ {IDS_OS_SETTINGS_TAG_CROSTINI_ALT1, SearchConcept::kAltTagEnd}},
{IDS_OS_SETTINGS_TAG_CROSTINI_SETUP,
mojom::kCrostiniSectionPath,
mojom::SearchResultIcon::kPenguin,
@@ -205,10 +206,6 @@ bool IsAdbSideloadingAllowed() {
return base::FeatureList::IsEnabled(features::kArcAdbSideloadingFeature);
}
-bool IsPortForwardingAllowed() {
- return base::FeatureList::IsEnabled(features::kCrostiniPortForwarding);
-}
-
bool IsDiskResizingAllowed() {
return base::FeatureList::IsEnabled(features::kCrostiniDiskResizing);
}
@@ -320,16 +317,22 @@ void CrostiniSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
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},
+ {"crostiniPortForwardingAddPortDialogPortNumberLabel",
+ IDS_SETTINGS_CROSTINI_PORT_FORWARDING_ADD_PORT_DIALOG_PORT_NUMBER_LABEL},
+ {"crostiniPortForwardingAddPortDialogLabelLabel",
+ IDS_SETTINGS_CROSTINI_PORT_FORWARDING_ADD_PORT_DIALOG_LABEL_LABEL},
{"crostiniPortForwardingTCP", IDS_SETTINGS_CROSTINI_PORT_FORWARDING_TCP},
{"crostiniPortForwardingUDP", IDS_SETTINGS_CROSTINI_PORT_FORWARDING_UDP},
{"crostiniPortForwardingAddError",
IDS_SETTINGS_CROSTINI_PORT_FORWARDING_ADD_ERROR},
+ {"crostiniPortForwardingAddExisting",
+ IDS_SETTINGS_CROSTINI_PORT_FORWARDING_ADD_EXISTING},
{"crostiniPortForwardingRemoveAllPorts",
IDS_SETTINGS_CROSTINI_PORT_FORWARDING_REMOVE_ALL_PORTS},
{"crostiniPortForwardingRemovePort",
IDS_SETTINGS_CROSTINI_PORT_FORWARDING_REMOVE_PORT},
+ {"crostiniPortForwardingActivatePortError",
+ IDS_SETTINGS_CROSTINI_PORT_FORWARDING_ACTIVATE_PORT_ERROR},
{"crostiniPortForwardingToggleAriaLabel",
IDS_SETTINGS_CROSTINI_PORT_FORWARDING_TOGGLE_PORT_ARIA_LABEL},
{"crostiniPortForwardingRemoveAllPortsAriaLabel",
@@ -432,9 +435,6 @@ void CrostiniSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
chromeos::ProfileHelper::IsOwnerProfile(profile()));
html_source->AddBoolean("isEnterpriseManaged",
IsDeviceManaged() || IsProfileManaged(profile()));
- html_source->AddBoolean(
- "canChangeAdbSideloading",
- crostini::CrostiniFeatures::Get()->CanChangeAdbSideloading(profile()));
html_source->AddBoolean("showCrostiniContainerUpgrade",
IsContainerUpgradeAllowed());
html_source->AddBoolean("showCrostiniDiskResize", IsDiskResizingAllowed());
@@ -448,6 +448,89 @@ void CrostiniSection::AddHandlers(content::WebUI* web_ui) {
}
}
+int CrostiniSection::GetSectionNameMessageId() const {
+ return IDS_SETTINGS_CROSTINI_TITLE;
+}
+
+mojom::Section CrostiniSection::GetSection() const {
+ return mojom::Section::kCrostini;
+}
+
+mojom::SearchResultIcon CrostiniSection::GetSectionIcon() const {
+ return mojom::SearchResultIcon::kPenguin;
+}
+
+std::string CrostiniSection::GetSectionPath() const {
+ return mojom::kCrostiniSectionPath;
+}
+
+void CrostiniSection::RegisterHierarchy(HierarchyGenerator* generator) const {
+ generator->RegisterTopLevelSetting(mojom::Setting::kSetUpCrostini);
+
+ // Crostini details.
+ generator->RegisterTopLevelSubpage(IDS_SETTINGS_CROSTINI_LABEL,
+ mojom::Subpage::kCrostiniDetails,
+ mojom::SearchResultIcon::kPenguin,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::kCrostiniDetailsSubpagePath);
+ static constexpr mojom::Setting kCrostiniDetailsSettings[] = {
+ mojom::Setting::kCrostiniContainerUpgrade,
+ mojom::Setting::kCrostiniDiskResize,
+ mojom::Setting::kCrostiniMicAccess,
+ mojom::Setting::kUninstallCrostini,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kCrostiniDetails,
+ kCrostiniDetailsSettings, generator);
+
+ // Manage shared folders.
+ generator->RegisterNestedSubpage(
+ IDS_SETTINGS_CROSTINI_SHARED_PATHS,
+ mojom::Subpage::kCrostiniManageSharedFolders,
+ mojom::Subpage::kCrostiniDetails, mojom::SearchResultIcon::kPenguin,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::kCrostiniManageSharedFoldersSubpagePath);
+
+ // USB preferences.
+ generator->RegisterNestedSubpage(
+ IDS_SETTINGS_CROSTINI_SHARED_USB_DEVICES_LABEL,
+ mojom::Subpage::kCrostiniUsbPreferences, mojom::Subpage::kCrostiniDetails,
+ mojom::SearchResultIcon::kPenguin,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::kCrostiniUsbPreferencesSubpagePath);
+
+ // Backup and restore.
+ generator->RegisterNestedSubpage(IDS_SETTINGS_CROSTINI_EXPORT_IMPORT_TITLE,
+ mojom::Subpage::kCrostiniBackupAndRestore,
+ mojom::Subpage::kCrostiniDetails,
+ mojom::SearchResultIcon::kPenguin,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::kCrostiniBackupAndRestoreSubpagePath);
+ static constexpr mojom::Setting kCrostiniBackupAndRestoreSettings[] = {
+ mojom::Setting::kBackupLinuxAppsAndFiles,
+ mojom::Setting::kRestoreLinuxAppsAndFiles,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kCrostiniBackupAndRestore,
+ kCrostiniBackupAndRestoreSettings, generator);
+
+ // Develop Android apps.
+ generator->RegisterNestedSubpage(
+ IDS_SETTINGS_CROSTINI_ARC_ADB_TITLE,
+ mojom::Subpage::kCrostiniDevelopAndroidApps,
+ mojom::Subpage::kCrostiniDetails, mojom::SearchResultIcon::kPenguin,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::kCrostiniDevelopAndroidAppsSubpagePath);
+ generator->RegisterNestedSetting(mojom::Setting::kCrostiniAdbDebugging,
+ mojom::Subpage::kCrostiniDevelopAndroidApps);
+
+ // Port forwarding.
+ generator->RegisterNestedSubpage(IDS_SETTINGS_CROSTINI_PORT_FORWARDING,
+ mojom::Subpage::kCrostiniPortForwarding,
+ mojom::Subpage::kCrostiniDetails,
+ mojom::SearchResultIcon::kPenguin,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::kCrostiniPortForwardingSubpagePath);
+}
+
bool CrostiniSection::IsCrostiniAllowed() {
return crostini::CrostiniFeatures::Get()->IsUIAllowed(profile(),
/*check_policy=*/false);
@@ -461,48 +544,51 @@ bool CrostiniSection::IsContainerUpgradeAllowed() {
return crostini::ShouldAllowContainerUpgrade(profile());
}
+bool CrostiniSection::IsPortForwardingAllowed() {
+ return crostini::CrostiniFeatures::Get()->IsPortForwardingAllowed(profile());
+}
+
void CrostiniSection::UpdateSearchTags() {
- registry()->RemoveSearchTags(GetCrostiniSearchConcepts());
- registry()->RemoveSearchTags(GetCrostiniOptedInSearchConcepts());
- registry()->RemoveSearchTags(GetCrostiniOptedOutSearchConcepts());
- registry()->RemoveSearchTags(GetCrostiniExportImportSearchConcepts());
- registry()->RemoveSearchTags(GetCrostiniAdbSideloadingSearchConcepts());
- registry()->RemoveSearchTags(GetCrostiniPortForwardingSearchConcepts());
- registry()->RemoveSearchTags(GetCrostiniContainerUpgradeSearchConcepts());
- registry()->RemoveSearchTags(GetCrostiniDiskResizingSearchConcepts());
- registry()->RemoveSearchTags(GetCrostiniMicSearchConcepts());
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+
+ updater.RemoveSearchTags(GetCrostiniOptedInSearchConcepts());
+ updater.RemoveSearchTags(GetCrostiniOptedOutSearchConcepts());
+ updater.RemoveSearchTags(GetCrostiniExportImportSearchConcepts());
+ updater.RemoveSearchTags(GetCrostiniAdbSideloadingSearchConcepts());
+ updater.RemoveSearchTags(GetCrostiniPortForwardingSearchConcepts());
+ updater.RemoveSearchTags(GetCrostiniContainerUpgradeSearchConcepts());
+ updater.RemoveSearchTags(GetCrostiniDiskResizingSearchConcepts());
+ updater.RemoveSearchTags(GetCrostiniMicSearchConcepts());
if (!IsCrostiniAllowed())
return;
- registry()->AddSearchTags(GetCrostiniSearchConcepts());
-
if (!pref_service_->GetBoolean(crostini::prefs::kCrostiniEnabled)) {
- registry()->AddSearchTags(GetCrostiniOptedOutSearchConcepts());
+ updater.AddSearchTags(GetCrostiniOptedOutSearchConcepts());
return;
}
- registry()->AddSearchTags(GetCrostiniOptedInSearchConcepts());
+ updater.AddSearchTags(GetCrostiniOptedInSearchConcepts());
if (IsExportImportAllowed())
- registry()->AddSearchTags(GetCrostiniExportImportSearchConcepts());
+ updater.AddSearchTags(GetCrostiniExportImportSearchConcepts());
if (IsAdbSideloadingAllowed() &&
pref_service_->GetBoolean(arc::prefs::kArcEnabled)) {
- registry()->AddSearchTags(GetCrostiniAdbSideloadingSearchConcepts());
+ updater.AddSearchTags(GetCrostiniAdbSideloadingSearchConcepts());
}
if (IsPortForwardingAllowed())
- registry()->AddSearchTags(GetCrostiniPortForwardingSearchConcepts());
+ updater.AddSearchTags(GetCrostiniPortForwardingSearchConcepts());
if (IsContainerUpgradeAllowed())
- registry()->AddSearchTags(GetCrostiniContainerUpgradeSearchConcepts());
+ updater.AddSearchTags(GetCrostiniContainerUpgradeSearchConcepts());
if (IsDiskResizingAllowed())
- registry()->AddSearchTags(GetCrostiniDiskResizingSearchConcepts());
+ updater.AddSearchTags(GetCrostiniDiskResizingSearchConcepts());
if (IsMicSettingAllowed())
- registry()->AddSearchTags(GetCrostiniMicSearchConcepts());
+ updater.AddSearchTags(GetCrostiniMicSearchConcepts());
}
} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_section.h b/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_section.h
index ee51c4be36f..e7caf6a65ea 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_section.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_section.h
@@ -31,10 +31,16 @@ class CrostiniSection : public OsSettingsSection {
// OsSettingsSection:
void AddLoadTimeData(content::WebUIDataSource* html_source) override;
void AddHandlers(content::WebUI* web_ui) override;
+ int GetSectionNameMessageId() const override;
+ mojom::Section GetSection() const override;
+ mojom::SearchResultIcon GetSectionIcon() const override;
+ std::string GetSectionPath() const override;
+ void RegisterHierarchy(HierarchyGenerator* generator) const override;
bool IsCrostiniAllowed();
bool IsExportImportAllowed();
bool IsContainerUpgradeAllowed();
+ bool IsPortForwardingAllowed();
void UpdateSearchTags();
PrefService* pref_service_;
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 6031f1951fa..74b1ac7cc36 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
@@ -27,6 +27,7 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/printing/cups_printers_manager.h"
#include "chrome/browser/chromeos/printing/ppd_provider_factory.h"
+#include "chrome/browser/chromeos/printing/print_management/print_management_uma.h"
#include "chrome/browser/chromeos/printing/printer_configurer.h"
#include "chrome/browser/chromeos/printing/printer_event_tracker.h"
#include "chrome/browser/chromeos/printing/printer_event_tracker_factory.h"
@@ -241,15 +242,15 @@ Printer::PpdReference GetPpdReference(const base::Value* info) {
Printer::PpdReference ret;
- if (user_supplied_ppd_url != nullptr) {
+ if (user_supplied_ppd_url) {
ret.user_supplied_ppd_url = user_supplied_ppd_url->GetString();
}
- if (effective_make_and_model != nullptr) {
+ if (effective_make_and_model) {
ret.effective_make_and_model = effective_make_and_model->GetString();
}
- if (autoconf != nullptr) {
+ if (autoconf) {
ret.autoconf = autoconf->GetBool();
}
@@ -998,6 +999,7 @@ void CupsPrintersHandler::HandleStartDiscovery(const base::ListValue* args) {
UMA_HISTOGRAM_COUNTS_100(
"Printing.CUPS.PrintersDiscovered",
discovered_printers_.size() + automatic_printers_.size());
+ printers_manager_->RecordNearbyNetworkPrinterCounts();
// Scan completes immediately right now. Emit done.
FireWebUIListener("on-printer-discovery-done");
}
@@ -1328,7 +1330,8 @@ void CupsPrintersHandler::HandleOpenPrintManagementApp(
DCHECK(args->empty());
DCHECK(
base::FeatureList::IsEnabled(chromeos::features::kPrintJobManagementApp));
- chrome::ShowPrintManagementApp(profile_);
+ chrome::ShowPrintManagementApp(profile_,
+ PrintManagementAppEntryPoint::kSettings);
}
} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler_unittest.cc
index 36193fc66fa..00cd8e56cb4 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler_unittest.cc
@@ -10,13 +10,17 @@
#include "base/bind_helpers.h"
#include "base/files/file_path.h"
#include "base/json/json_string_value_serializer.h"
+#include "base/test/metrics/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
#include "base/values.h"
+#include "chrome/browser/chromeos/printing/print_management/print_management_uma.h"
#include "chrome/browser/chromeos/printing/printing_stubs.h"
#include "chrome/browser/download/chrome_download_manager_delegate.h"
#include "chrome/browser/download/download_core_service_factory.h"
#include "chrome/browser/download/download_core_service_impl.h"
#include "chrome/browser/ui/chrome_select_file_policy.h"
#include "chrome/test/base/testing_profile.h"
+#include "chromeos/constants/chromeos_features.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/debug_daemon/debug_daemon_client.h"
#include "content/public/test/browser_task_environment.h"
@@ -192,6 +196,8 @@ class CupsPrintersHandlerTest : public testing::Test {
~CupsPrintersHandlerTest() override = default;
void SetUp() override {
+ scoped_feature_list_.InitWithFeatures(
+ {chromeos::features::kPrintJobManagementApp}, {});
printers_handler_ = CupsPrintersHandler::CreateForTesting(
&profile_, base::MakeRefCounted<FakePpdProvider>(),
std::make_unique<StubPrinterConfigurer>(), &printers_manager_);
@@ -201,11 +207,13 @@ class CupsPrintersHandlerTest : public testing::Test {
protected:
// Must outlive |profile_|.
+ base::HistogramTester histogram_tester_;
content::BrowserTaskEnvironment task_environment_;
TestingProfile profile_;
content::TestWebUI web_ui_;
std::unique_ptr<CupsPrintersHandler> printers_handler_;
TestCupsPrintersManager printers_manager_;
+ base::test::ScopedFeatureList scoped_feature_list_;
};
TEST_F(CupsPrintersHandlerTest, RemoveCorrectPrinter) {
@@ -253,5 +261,24 @@ TEST_F(CupsPrintersHandlerTest, VerifyOnlyPpdFilesAllowed) {
web_ui_.HandleReceivedMessage("selectPPDFile",
&base::Value::AsListValue(args));
}
+
+TEST_F(CupsPrintersHandlerTest, VerifyPrintManagementAppEntryPointHistogram) {
+ base::Value args(base::Value::Type::LIST);
+ web_ui_.HandleReceivedMessage("openPrintManagementApp",
+ &base::Value::AsListValue(args));
+ histogram_tester_.ExpectBucketCount(
+ "Printing.Cups.PrintManagementAppEntryPoint",
+ PrintManagementAppEntryPoint::kSettings, 1);
+ histogram_tester_.ExpectBucketCount(
+ "Printing.Cups.PrintManagementAppEntryPoint",
+ PrintManagementAppEntryPoint::kNotification, 0);
+ histogram_tester_.ExpectBucketCount(
+ "Printing.Cups.PrintManagementAppEntryPoint",
+ PrintManagementAppEntryPoint::kLauncher, 0);
+ histogram_tester_.ExpectBucketCount(
+ "Printing.Cups.PrintManagementAppEntryPoint",
+ PrintManagementAppEntryPoint::kBrowser, 0);
+}
+
} // namespace settings.
} // namespace chromeos.
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 dac0db6e52d..0c1df37cc1e 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
@@ -58,7 +58,7 @@ bool IsTimezoneAutomaticDetectionUserEditable() {
if (IsSystemTimezoneAutomaticDetectionManaged()) {
return GetSystemTimezoneAutomaticDetectionPolicyValue() ==
- enterprise_management::SystemTimezoneProto::USERS_DECIDE;
+ enterprise_management::SystemTimezoneProto::USERS_DECIDE;
}
return true;
@@ -156,7 +156,7 @@ void DateTimeHandler::HandleShowParentAccessForTimeZone(
base::BindOnce(&DateTimeHandler::OnParentAccessValidation,
weak_ptr_factory_.GetWeakPtr()),
ash::ParentAccessRequestReason::kChangeTimezone, false /* extra_dimmer */,
- base::Time());
+ base::Time::Now());
}
void DateTimeHandler::OnParentAccessValidation(bool success) {
@@ -166,10 +166,9 @@ void DateTimeHandler::OnParentAccessValidation(bool success) {
void DateTimeHandler::NotifyTimezoneAutomaticDetectionPolicy() {
bool managed = !IsTimezoneAutomaticDetectionUserEditable();
- bool force_enabled = managed &&
- g_browser_process->platform_part()
- ->GetTimezoneResolverManager()
- ->ShouldApplyResolvedTimezone();
+ bool force_enabled = managed && g_browser_process->platform_part()
+ ->GetTimezoneResolverManager()
+ ->ShouldApplyResolvedTimezone();
FireWebUIListener("time-zone-auto-detect-policy", base::Value(managed),
base::Value(force_enabled));
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/date_time_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/date_time_section.cc
index 529689f68dc..8899d28d0e1 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/date_time_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/date_time_section.cc
@@ -19,6 +19,7 @@
#include "chromeos/settings/cros_settings_names.h"
#include "chromeos/settings/system_settings_provider.h"
#include "chromeos/settings/timezone_settings.h"
+#include "components/user_manager/user_manager.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"
@@ -71,18 +72,23 @@ const std::vector<SearchConcept>& GetNoFineGrainedTimeZoneSearchConcepts() {
return *tags;
}
+bool IsFineGrainedTimeZoneEnabled() {
+ SystemSettingsProvider provider;
+ return provider.Get(chromeos::kFineGrainedTimeZoneResolveEnabled)->GetBool();
+}
+
} // namespace
DateTimeSection::DateTimeSection(Profile* profile,
SearchTagRegistry* search_tag_registry)
: OsSettingsSection(profile, search_tag_registry) {
- registry()->AddSearchTags(GetDateTimeSearchConcepts());
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+ updater.AddSearchTags(GetDateTimeSearchConcepts());
- SystemSettingsProvider provider;
- if (provider.Get(chromeos::kFineGrainedTimeZoneResolveEnabled)->GetBool())
- registry()->AddSearchTags(GetFineGrainedTimeZoneSearchConcepts());
+ if (IsFineGrainedTimeZoneEnabled())
+ updater.AddSearchTags(GetFineGrainedTimeZoneSearchConcepts());
else
- registry()->AddSearchTags(GetNoFineGrainedTimeZoneSearchConcepts());
+ updater.AddSearchTags(GetNoFineGrainedTimeZoneSearchConcepts());
}
DateTimeSection::~DateTimeSection() = default;
@@ -127,11 +133,49 @@ void DateTimeSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
html_source->AddBoolean(
"timeActionsProtectedForChild",
base::FeatureList::IsEnabled(features::kParentAccessCodeForTimeChange));
+
+ bool is_child = user_manager::UserManager::Get()->GetActiveUser()->IsChild();
+ html_source->AddBoolean("isChild", is_child);
}
void DateTimeSection::AddHandlers(content::WebUI* web_ui) {
web_ui->AddMessageHandler(std::make_unique<DateTimeHandler>());
}
+int DateTimeSection::GetSectionNameMessageId() const {
+ return IDS_SETTINGS_DATE_TIME;
+}
+
+mojom::Section DateTimeSection::GetSection() const {
+ return mojom::Section::kDateAndTime;
+}
+
+mojom::SearchResultIcon DateTimeSection::GetSectionIcon() const {
+ return mojom::SearchResultIcon::kClock;
+}
+
+std::string DateTimeSection::GetSectionPath() const {
+ return mojom::kDateAndTimeSectionPath;
+}
+
+void DateTimeSection::RegisterHierarchy(HierarchyGenerator* generator) const {
+ generator->RegisterTopLevelSetting(mojom::Setting::k24HourClock);
+
+ generator->RegisterTopLevelSubpage(
+ IDS_SETTINGS_TIME_ZONE_SUBPAGE_TITLE, mojom::Subpage::kTimeZone,
+ mojom::SearchResultIcon::kClock, mojom::SearchResultDefaultRank::kMedium,
+ mojom::kTimeZoneSubpagePath);
+
+ // When fine-grained time zone is enabled, users change the time zone on the
+ // time zone subpage; otherwise, the setting is directly embedded in the
+ // section.
+ if (IsFineGrainedTimeZoneEnabled()) {
+ generator->RegisterNestedSetting(mojom::Setting::kChangeTimeZone,
+ mojom::Subpage::kTimeZone);
+ } else {
+ generator->RegisterTopLevelSetting(mojom::Setting::kChangeTimeZone);
+ }
+}
+
} // namespace settings
} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/date_time_section.h b/chromium/chrome/browser/ui/webui/settings/chromeos/date_time_section.h
index 2c1d8e0f5c3..7eef9df9516 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/date_time_section.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/date_time_section.h
@@ -26,6 +26,11 @@ class DateTimeSection : public OsSettingsSection {
// OsSettingsSection:
void AddLoadTimeData(content::WebUIDataSource* html_source) override;
void AddHandlers(content::WebUI* web_ui) override;
+ int GetSectionNameMessageId() const override;
+ mojom::Section GetSection() const override;
+ mojom::SearchResultIcon GetSectionIcon() const override;
+ std::string GetSectionPath() const override;
+ void RegisterHierarchy(HierarchyGenerator* generator) const override;
};
} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_dlc_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_dlc_handler.cc
index 38eb1b57fef..c90f34eff69 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_dlc_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_dlc_handler.cc
@@ -36,28 +36,32 @@ DlcHandler::~DlcHandler() = default;
void DlcHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(
- "getDlcList", base::BindRepeating(&DlcHandler::HandleGetDlcList,
- weak_ptr_factory_.GetWeakPtr()));
+ "dlcSubpageReady", base::BindRepeating(&DlcHandler::HandleDlcSubpageReady,
+ base::Unretained(this)));
web_ui()->RegisterMessageCallback(
- "purgeDlc", base::BindRepeating(&DlcHandler::HandlePurgeDlc,
- weak_ptr_factory_.GetWeakPtr()));
+ "purgeDlc",
+ base::BindRepeating(&DlcHandler::HandlePurgeDlc, base::Unretained(this)));
+}
+
+void DlcHandler::OnJavascriptAllowed() {
+ dlcservice_client_observer_.Add(DlcserviceClient::Get());
}
void DlcHandler::OnJavascriptDisallowed() {
+ dlcservice_client_observer_.RemoveAll();
+
// Ensure that pending callbacks do not complete and cause JS to be evaluated.
weak_ptr_factory_.InvalidateWeakPtrs();
}
-void DlcHandler::HandleGetDlcList(const base::ListValue* args) {
- AllowJavascript();
- CHECK_EQ(1U, args->GetSize());
- const base::Value* callback_id;
- CHECK(args->Get(0, &callback_id));
+void DlcHandler::OnDlcStateChanged(const dlcservice::DlcState& dlc_state) {
+ FetchDlcList();
+}
- DlcserviceClient::Get()->GetExistingDlcs(
- base::BindOnce(&DlcHandler::GetDlcListCallback,
- weak_ptr_factory_.GetWeakPtr(), callback_id->Clone()));
+void DlcHandler::HandleDlcSubpageReady(const base::ListValue* args) {
+ AllowJavascript();
+ FetchDlcList();
}
void DlcHandler::HandlePurgeDlc(const base::ListValue* args) {
@@ -74,16 +78,18 @@ void DlcHandler::HandlePurgeDlc(const base::ListValue* args) {
weak_ptr_factory_.GetWeakPtr(), callback_id->Clone()));
}
-void DlcHandler::GetDlcListCallback(
- const base::Value& callback_id,
+void DlcHandler::FetchDlcList() {
+ DlcserviceClient::Get()->GetExistingDlcs(
+ base::BindOnce(&DlcHandler::SendDlcList, weak_ptr_factory_.GetWeakPtr()));
+}
+
+void DlcHandler::SendDlcList(
const std::string& err,
const dlcservice::DlcsWithContent& dlcs_with_content) {
- if (err == dlcservice::kErrorNone) {
- ResolveJavascriptCallback(callback_id,
- DlcsWithContentToListValue(dlcs_with_content));
- return;
- }
- ResolveJavascriptCallback(callback_id, base::ListValue());
+ FireWebUIListener("dlc-list-changed",
+ err == dlcservice::kErrorNone
+ ? DlcsWithContentToListValue(dlcs_with_content)
+ : base::ListValue());
}
void DlcHandler::PurgeDlcCallback(const base::Value& callback_id,
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_dlc_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/device_dlc_handler.h
index 27afcaf2de6..cbd3f798c74 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_dlc_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_dlc_handler.h
@@ -6,6 +6,7 @@
#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_DLC_HANDLER_H_
#include "base/memory/weak_ptr.h"
+#include "base/scoped_observer.h"
#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
#include "chromeos/dbus/dlcservice/dlcservice_client.h"
@@ -17,7 +18,8 @@ namespace chromeos {
namespace settings {
// Chrome OS Downloaded Content settings page UI handler.
-class DlcHandler : public ::settings::SettingsPageUIHandler {
+class DlcHandler : public ::settings::SettingsPageUIHandler,
+ public DlcserviceClient::Observer {
public:
DlcHandler();
DlcHandler(const DlcHandler&) = delete;
@@ -26,22 +28,32 @@ class DlcHandler : public ::settings::SettingsPageUIHandler {
// SettingsPageUIHandler:
void RegisterMessages() override;
- void OnJavascriptAllowed() override {}
+ void OnJavascriptAllowed() override;
void OnJavascriptDisallowed() override;
+ // DlcserviceClient::Observer:
+ void OnDlcStateChanged(const dlcservice::DlcState& dlc_state) override;
+
private:
- // Handler to get the latest list of DLCs.
- void HandleGetDlcList(const base::ListValue* args);
+ // Handler called when DLC subpage is attached.
+ void HandleDlcSubpageReady(const base::ListValue* args);
// Handler to purge a DLC.
void HandlePurgeDlc(const base::ListValue* args);
- void GetDlcListCallback(const base::Value& callback_id,
- const std::string& err,
- const dlcservice::DlcsWithContent& dlcs_with_content);
+ // Fetches the latest DLC list from DlcserviceClient, passing SendDlcList() as
+ // the callback.
+ void FetchDlcList();
+
+ // Sends DLC list to web UIs listening in on 'dlc-list-changed' events.
+ void SendDlcList(const std::string& err,
+ const dlcservice::DlcsWithContent& dlcs_with_content);
void PurgeDlcCallback(const base::Value& callback_id, const std::string& err);
+ ScopedObserver<DlcserviceClient, DlcserviceClient::Observer>
+ dlcservice_client_observer_{this};
+
base::WeakPtrFactory<DlcHandler> weak_ptr_factory_{this};
};
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_dlc_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_dlc_handler_unittest.cc
index cb4dbc5dde8..b99ed70fcde 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_dlc_handler_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_dlc_handler_unittest.cc
@@ -42,14 +42,14 @@ class DlcHandlerTest : public testing::Test {
void SetUp() override {
test_web_ui_ = std::make_unique<content::TestWebUI>();
+ chromeos::DlcserviceClient::InitializeFake();
+ fake_dlcservice_client_ = static_cast<chromeos::FakeDlcserviceClient*>(
+ chromeos::DlcserviceClient::Get());
+
handler_ = std::make_unique<TestDlcHandler>();
handler_->set_web_ui(test_web_ui_.get());
handler_->RegisterMessages();
handler_->AllowJavascriptForTesting();
-
- chromeos::DlcserviceClient::InitializeFake();
- fake_dlcservice_client_ = static_cast<chromeos::FakeDlcserviceClient*>(
- chromeos::DlcserviceClient::Get());
}
void TearDown() override {
@@ -70,12 +70,12 @@ class DlcHandlerTest : public testing::Test {
return *test_web_ui_->call_data()[index];
}
- base::Value::ConstListView CallGetDlcListAndReturnList() {
+ base::Value::ConstListView NotifyDlcSubpageReadyAndReturnDlcList() {
size_t call_data_count_before_call = test_web_ui()->call_data().size();
base::ListValue args;
args.AppendString("handlerFunctionName");
- test_web_ui()->HandleReceivedMessage("getDlcList", &args);
+ test_web_ui()->HandleReceivedMessage("dlcSubpageReady", &args);
task_environment_.RunUntilIdle();
EXPECT_EQ(call_data_count_before_call + 1u,
@@ -83,9 +83,9 @@ class DlcHandlerTest : public testing::Test {
const content::TestWebUI::CallData& call_data =
CallDataAtIndex(call_data_count_before_call);
- EXPECT_EQ("cr.webUIResponse", call_data.function_name());
- EXPECT_EQ("handlerFunctionName", call_data.arg1()->GetString());
- return call_data.arg3()->GetList();
+ EXPECT_EQ("cr.webUIListenerCallback", call_data.function_name());
+ EXPECT_EQ("dlc-list-changed", call_data.arg1()->GetString());
+ return call_data.arg2()->GetList();
}
bool CallPurgeDlcAndReturnSuccess() {
@@ -108,26 +108,45 @@ class DlcHandlerTest : public testing::Test {
}
};
-TEST_F(DlcHandlerTest, GetDlcList) {
+TEST_F(DlcHandlerTest, SendDlcListOnDlcStatusChange) {
+ size_t call_data_count_before_call = test_web_ui()->call_data().size();
+ fake_dlcservice_client_->set_dlcs_with_content(CreateDlcModuleListOfSize(2u));
+
+ dlcservice::DlcState dlc_state;
+ dlc_state.set_state(dlcservice::DlcState::INSTALLING);
+ fake_dlcservice_client_->NotifyObserversForTest(dlc_state);
+ task_environment_.RunUntilIdle();
+
+ EXPECT_EQ(call_data_count_before_call + 1u,
+ test_web_ui()->call_data().size());
+
+ const content::TestWebUI::CallData& call_data =
+ CallDataAtIndex(call_data_count_before_call);
+ EXPECT_EQ("cr.webUIListenerCallback", call_data.function_name());
+ EXPECT_EQ("dlc-list-changed", call_data.arg1()->GetString());
+ EXPECT_EQ(call_data.arg2()->GetList().size(), 2u);
+}
+
+TEST_F(DlcHandlerTest, CorrectlyReturnsDlcMetadataListOnSubpageReady) {
fake_dlcservice_client_->set_dlcs_with_content(CreateDlcModuleListOfSize(2u));
fake_dlcservice_client_->SetGetExistingDlcsError(dlcservice::kErrorInternal);
- EXPECT_EQ(CallGetDlcListAndReturnList().size(), 0u);
+ EXPECT_EQ(NotifyDlcSubpageReadyAndReturnDlcList().size(), 0u);
fake_dlcservice_client_->SetGetExistingDlcsError(
dlcservice::kErrorNeedReboot);
- EXPECT_EQ(CallGetDlcListAndReturnList().size(), 0u);
+ EXPECT_EQ(NotifyDlcSubpageReadyAndReturnDlcList().size(), 0u);
fake_dlcservice_client_->SetGetExistingDlcsError(
dlcservice::kErrorInvalidDlc);
- EXPECT_EQ(CallGetDlcListAndReturnList().size(), 0u);
+ EXPECT_EQ(NotifyDlcSubpageReadyAndReturnDlcList().size(), 0u);
fake_dlcservice_client_->SetGetExistingDlcsError(
dlcservice::kErrorAllocation);
- EXPECT_EQ(CallGetDlcListAndReturnList().size(), 0u);
+ EXPECT_EQ(NotifyDlcSubpageReadyAndReturnDlcList().size(), 0u);
fake_dlcservice_client_->SetGetExistingDlcsError(dlcservice::kErrorNone);
- EXPECT_EQ(CallGetDlcListAndReturnList().size(), 2u);
+ EXPECT_EQ(NotifyDlcSubpageReadyAndReturnDlcList().size(), 2u);
}
TEST_F(DlcHandlerTest, PurgeDlc) {
@@ -157,7 +176,7 @@ TEST_F(DlcHandlerTest, FormattedCorrectly) {
fake_dlcservice_client_->set_dlcs_with_content(dlcs_with_content);
- auto result_list = CallGetDlcListAndReturnList();
+ auto result_list = NotifyDlcSubpageReadyAndReturnDlcList();
EXPECT_EQ(1UL, result_list.size());
EXPECT_EQ("fake id", result_list[0].FindKey("id")->GetString());
EXPECT_EQ("fake name", result_list[0].FindKey("name")->GetString());
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_section.cc
index 440b8feb397..7921e8838dd 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_section.cc
@@ -48,7 +48,7 @@ const std::vector<SearchConcept>& GetDeviceSearchConcepts() {
{IDS_OS_SETTINGS_TAG_KEYBOARD,
mojom::kKeyboardSubpagePath,
mojom::SearchResultIcon::kKeyboard,
- mojom::SearchResultDefaultRank::kHigh,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
{.subpage = mojom::Subpage::kKeyboard}},
{IDS_OS_SETTINGS_TAG_KEYBOARD_AUTO_REPEAT,
@@ -81,7 +81,7 @@ const std::vector<SearchConcept>& GetDeviceSearchConcepts() {
{IDS_OS_SETTINGS_TAG_STORAGE,
mojom::kStorageSubpagePath,
mojom::SearchResultIcon::kHardDrive,
- mojom::SearchResultDefaultRank::kHigh,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
{.subpage = mojom::Subpage::kStorage},
{IDS_OS_SETTINGS_TAG_STORAGE_ALT1, IDS_OS_SETTINGS_TAG_STORAGE_ALT2,
@@ -89,7 +89,7 @@ const std::vector<SearchConcept>& GetDeviceSearchConcepts() {
{IDS_OS_SETTINGS_TAG_DISPLAY_NIGHT_LIGHT,
mojom::kDisplaySubpagePath,
mojom::SearchResultIcon::kDisplay,
- mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultDefaultRank::kLow,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kNightLight},
{IDS_OS_SETTINGS_TAG_DISPLAY_NIGHT_LIGHT_ALT1,
@@ -98,7 +98,7 @@ const std::vector<SearchConcept>& GetDeviceSearchConcepts() {
{IDS_OS_SETTINGS_TAG_DISPLAY,
mojom::kDisplaySubpagePath,
mojom::SearchResultIcon::kDisplay,
- mojom::SearchResultDefaultRank::kHigh,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
{.subpage = mojom::Subpage::kDisplay},
{IDS_OS_SETTINGS_TAG_DISPLAY_ALT1, IDS_OS_SETTINGS_TAG_DISPLAY_ALT2,
@@ -121,13 +121,22 @@ const std::vector<SearchConcept>& GetDeviceSearchConcepts() {
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kKeyboardFunctionKeys}},
- {IDS_OS_SETTINGS_TAG_POWER_IDLE,
+ {IDS_OS_SETTINGS_TAG_POWER_IDLE_WHILE_CHARGING,
mojom::kPowerSubpagePath,
mojom::SearchResultIcon::kPower,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
- {.setting = mojom::Setting::kPowerIdleBehavior},
- {IDS_OS_SETTINGS_TAG_POWER_IDLE_ALT1, SearchConcept::kAltTagEnd}},
+ {.setting = mojom::Setting::kPowerIdleBehaviorWhileCharging},
+ {IDS_OS_SETTINGS_TAG_POWER_IDLE_WHILE_CHARGING_ALT1,
+ SearchConcept::kAltTagEnd}},
+ {IDS_OS_SETTINGS_TAG_POWER_IDLE_WHILE_ON_BATTERY,
+ mojom::kPowerSubpagePath,
+ mojom::SearchResultIcon::kPower,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kPowerIdleBehaviorWhileOnBattery},
+ {IDS_OS_SETTINGS_TAG_POWER_IDLE_WHILE_ON_BATTERY_ALT1,
+ SearchConcept::kAltTagEnd}},
});
return *tags;
}
@@ -155,7 +164,7 @@ const std::vector<SearchConcept>& GetTouchpadSearchConcepts() {
{IDS_OS_SETTINGS_TAG_TOUCHPAD,
mojom::kPointersSubpagePath,
mojom::SearchResultIcon::kLaptop,
- mojom::SearchResultDefaultRank::kHigh,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
{.subpage = mojom::Subpage::kPointers},
{IDS_OS_SETTINGS_TAG_TOUCHPAD_ALT1, SearchConcept::kAltTagEnd}},
@@ -210,7 +219,7 @@ const std::vector<SearchConcept>& GetMouseSearchConcepts() {
{IDS_OS_SETTINGS_TAG_MOUSE,
mojom::kPointersSubpagePath,
mojom::SearchResultIcon::kMouse,
- mojom::SearchResultDefaultRank::kHigh,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
{.subpage = mojom::Subpage::kPointers}},
{IDS_OS_SETTINGS_TAG_MOUSE_SCROLL_ACCELERATION,
@@ -281,36 +290,30 @@ const std::vector<SearchConcept>& GetDisplayArrangementSearchConcepts() {
const std::vector<SearchConcept>& GetDisplayMirrorSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
- // TODO(khorimoto): Add "Display mirror" search concepts.
+ {IDS_OS_SETTINGS_TAG_MIRRORING,
+ mojom::kDisplaySubpagePath,
+ mojom::SearchResultIcon::kDisplay,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kDisplayMirroring}},
});
return *tags;
}
const std::vector<SearchConcept>& GetDisplayUnifiedDesktopSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
- // TODO(khorimoto): Add "Display with Unified Desktop" search concepts.
- });
- return *tags;
-}
-
-const std::vector<SearchConcept>& GetDisplayMultipleSearchConcepts() {
- static const base::NoDestructor<std::vector<SearchConcept>> tags({
- // TODO(khorimoto): Add "Display multiple" search concepts.
+ {IDS_OS_SETTINGS_TAG_UNIFIED_DESKTOP,
+ mojom::kDisplaySubpagePath,
+ mojom::SearchResultIcon::kDisplay,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kAllowWindowsToSpanDisplays}},
});
return *tags;
}
const std::vector<SearchConcept>& GetDisplayExternalSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
- {IDS_OS_SETTINGS_TAG_DISPLAY_ORIENTATION,
- mojom::kDisplaySubpagePath,
- mojom::SearchResultIcon::kDisplay,
- mojom::SearchResultDefaultRank::kMedium,
- mojom::SearchResultType::kSetting,
- {.setting = mojom::Setting::kDisplayOrientation},
- {IDS_OS_SETTINGS_TAG_DISPLAY_ORIENTATION_ALT1,
- IDS_OS_SETTINGS_TAG_DISPLAY_ORIENTATION_ALT2,
- SearchConcept::kAltTagEnd}},
{IDS_OS_SETTINGS_TAG_DISPLAY_RESOLUTION,
mojom::kDisplaySubpagePath,
mojom::SearchResultIcon::kDisplay,
@@ -320,6 +323,12 @@ const std::vector<SearchConcept>& GetDisplayExternalSearchConcepts() {
{IDS_OS_SETTINGS_TAG_DISPLAY_RESOLUTION_ALT1,
IDS_OS_SETTINGS_TAG_DISPLAY_RESOLUTION_ALT2,
SearchConcept::kAltTagEnd}},
+ {IDS_OS_SETTINGS_TAG_DISPLAY_OVERSCAN,
+ mojom::kDisplaySubpagePath,
+ mojom::SearchResultIcon::kDisplay,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kDisplayOverscan}},
});
return *tags;
}
@@ -342,28 +351,74 @@ GetDisplayExternalWithRefreshSearchConcepts() {
const std::vector<SearchConcept>& GetDisplayOrientationSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
- // TODO(khorimoto): Add "Display orientation" search concepts.
+ {IDS_OS_SETTINGS_TAG_DISPLAY_ORIENTATION,
+ mojom::kDisplaySubpagePath,
+ mojom::SearchResultIcon::kDisplay,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kDisplayOrientation},
+ {IDS_OS_SETTINGS_TAG_DISPLAY_ORIENTATION_ALT1,
+ SearchConcept::kAltTagEnd}},
});
return *tags;
}
const std::vector<SearchConcept>& GetDisplayAmbientSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
- // TODO(khorimoto): Add "Display ambient" search concepts.
+ {IDS_OS_SETTINGS_TAG_DISPLAY_AMBIENT_COLORS,
+ mojom::kDisplaySubpagePath,
+ mojom::SearchResultIcon::kDisplay,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kAmbientColors}},
});
return *tags;
}
const std::vector<SearchConcept>& GetDisplayTouchCalibrationSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
- // TODO(khorimoto): Add "Display touch calibration" search concepts.
+ {IDS_OS_SETTINGS_TAG_DISPLAY_TOUCHSCREEN_CALIBRATION,
+ mojom::kDisplaySubpagePath,
+ mojom::SearchResultIcon::kDisplay,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kTouchscreenCalibration}},
});
return *tags;
}
const std::vector<SearchConcept>& GetDisplayNightLightOnSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
- // TODO(khorimoto): Add "Display Night Light on" search concepts.
+ {IDS_OS_SETTINGS_TAG_NIGHT_LIGHT_COLOR_TEMPERATURE,
+ mojom::kDisplaySubpagePath,
+ mojom::SearchResultIcon::kDisplay,
+ mojom::SearchResultDefaultRank::kLow,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kNightLightColorTemperature}},
+ });
+ return *tags;
+}
+
+const std::vector<SearchConcept>& GetDlcSearchConcepts() {
+ static const base::NoDestructor<std::vector<SearchConcept>> tags({
+ {IDS_OS_SETTINGS_TAG_DOWNLOADED_CONTENT,
+ mojom::kDlcSubpagePath,
+ mojom::SearchResultIcon::kHardDrive,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSubpage,
+ {.subpage = mojom::Subpage::kDlc},
+ {IDS_OS_SETTINGS_TAG_DOWNLOADED_CONTENT_ALT1,
+ SearchConcept::kAltTagEnd}},
+ {IDS_OS_SETTINGS_TAG_REMOVE_DOWNLOADED_CONTENT,
+ mojom::kDlcSubpagePath,
+ mojom::SearchResultIcon::kHardDrive,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kRemoveDlc},
+ {IDS_OS_SETTINGS_TAG_REMOVE_DOWNLOADED_CONTENT_ALT1,
+ IDS_OS_SETTINGS_TAG_REMOVE_DOWNLOADED_CONTENT_ALT2,
+ IDS_OS_SETTINGS_TAG_REMOVE_DOWNLOADED_CONTENT_ALT3,
+ SearchConcept::kAltTagEnd}},
});
return *tags;
}
@@ -694,10 +749,11 @@ DeviceSection::DeviceSection(Profile* profile,
PrefService* pref_service)
: OsSettingsSection(profile, search_tag_registry),
pref_service_(pref_service) {
- registry()->AddSearchTags(GetDeviceSearchConcepts());
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+ updater.AddSearchTags(GetDeviceSearchConcepts());
if (features::ShouldShowExternalStorageSettings(profile))
- registry()->AddSearchTags(GetExternalStorageSearchConcepts());
+ updater.AddSearchTags(GetExternalStorageSearchConcepts());
PowerManagerClient* power_manager_client = PowerManagerClient::Get();
if (power_manager_client) {
@@ -739,6 +795,14 @@ DeviceSection::DeviceSection(Profile* profile,
OnNightLightEnabledChanged(
ash::NightLightController::GetInstance()->GetEnabled());
}
+
+ // DLC settings search tags are added/removed dynamically.
+ DlcserviceClient* dlcservice_client = DlcserviceClient::Get();
+ if (features::ShouldShowDlcSettings() && dlcservice_client) {
+ dlcservice_client->AddObserver(this);
+ dlcservice_client->GetExistingDlcs(base::BindOnce(
+ &DeviceSection::OnGetExistingDlcs, weak_ptr_factory_.GetWeakPtr()));
+ }
}
DeviceSection::~DeviceSection() {
@@ -753,6 +817,10 @@ DeviceSection::~DeviceSection() {
ash::NightLightController::GetInstance();
if (night_light_controller)
night_light_controller->RemoveObserver(this);
+
+ DlcserviceClient* dlcservice_client = DlcserviceClient::Get();
+ if (features::ShouldShowDlcSettings() && dlcservice_client)
+ dlcservice_client->RemoveObserver(this);
}
void DeviceSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
@@ -797,18 +865,140 @@ void DeviceSection::AddHandlers(content::WebUI* web_ui) {
std::make_unique<chromeos::settings::StylusHandler>());
}
+int DeviceSection::GetSectionNameMessageId() const {
+ return IDS_SETTINGS_DEVICE_TITLE;
+}
+
+mojom::Section DeviceSection::GetSection() const {
+ return mojom::Section::kDevice;
+}
+
+mojom::SearchResultIcon DeviceSection::GetSectionIcon() const {
+ return mojom::SearchResultIcon::kLaptop;
+}
+
+std::string DeviceSection::GetSectionPath() const {
+ return mojom::kDeviceSectionPath;
+}
+
+void DeviceSection::RegisterHierarchy(HierarchyGenerator* generator) const {
+ // Pointers.
+ generator->RegisterTopLevelSubpage(
+ IDS_SETTINGS_MOUSE_AND_TOUCHPAD_TITLE, mojom::Subpage::kPointers,
+ mojom::SearchResultIcon::kMouse, mojom::SearchResultDefaultRank::kMedium,
+ mojom::kPointersSubpagePath);
+ static constexpr mojom::Setting kPointersSettings[] = {
+ mojom::Setting::kTouchpadTapToClick,
+ mojom::Setting::kTouchpadTapDragging,
+ mojom::Setting::kTouchpadReverseScrolling,
+ mojom::Setting::kTouchpadAcceleration,
+ mojom::Setting::kTouchpadScrollAcceleration,
+ mojom::Setting::kTouchpadSpeed,
+ mojom::Setting::kMouseSwapPrimaryButtons,
+ mojom::Setting::kMouseReverseScrolling,
+ mojom::Setting::kMouseAcceleration,
+ mojom::Setting::kMouseScrollAcceleration,
+ mojom::Setting::kMouseSpeed,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kPointers, kPointersSettings,
+ generator);
+
+ // Keyboard.
+ generator->RegisterTopLevelSubpage(
+ IDS_SETTINGS_KEYBOARD_TITLE, mojom::Subpage::kKeyboard,
+ mojom::SearchResultIcon::kKeyboard,
+ mojom::SearchResultDefaultRank::kMedium, mojom::kKeyboardSubpagePath);
+ static constexpr mojom::Setting kKeyboardSettings[] = {
+ mojom::Setting::kKeyboardFunctionKeys,
+ mojom::Setting::kKeyboardAutoRepeat,
+ mojom::Setting::kKeyboardShortcuts,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kKeyboard, kKeyboardSettings,
+ generator);
+
+ // Stylus.
+ generator->RegisterTopLevelSubpage(
+ IDS_SETTINGS_STYLUS_TITLE, mojom::Subpage::kStylus,
+ mojom::SearchResultIcon::kStylus, mojom::SearchResultDefaultRank::kMedium,
+ mojom::kStylusSubpagePath);
+ static constexpr mojom::Setting kStylusSettings[] = {
+ mojom::Setting::kStylusToolsInShelf,
+ mojom::Setting::kStylusNoteTakingApp,
+ mojom::Setting::kStylusNoteTakingFromLockScreen,
+ mojom::Setting::kStylusLatestNoteOnLockScreen,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kStylus, kStylusSettings,
+ generator);
+
+ // Display.
+ generator->RegisterTopLevelSubpage(
+ IDS_SETTINGS_DISPLAY_TITLE, mojom::Subpage::kDisplay,
+ mojom::SearchResultIcon::kDisplay,
+ mojom::SearchResultDefaultRank::kMedium, mojom::kDisplaySubpagePath);
+ static constexpr mojom::Setting kDisplaySettings[] = {
+ mojom::Setting::kDisplaySize,
+ mojom::Setting::kNightLight,
+ mojom::Setting::kDisplayOrientation,
+ mojom::Setting::kDisplayArrangement,
+ mojom::Setting::kDisplayResolution,
+ mojom::Setting::kDisplayRefreshRate,
+ mojom::Setting::kDisplayMirroring,
+ mojom::Setting::kAllowWindowsToSpanDisplays,
+ mojom::Setting::kAmbientColors,
+ mojom::Setting::kTouchscreenCalibration,
+ mojom::Setting::kNightLightColorTemperature,
+ mojom::Setting::kDisplayOverscan,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kDisplay, kDisplaySettings,
+ generator);
+
+ // Storage.
+ generator->RegisterTopLevelSubpage(
+ IDS_SETTINGS_STORAGE_TITLE, mojom::Subpage::kStorage,
+ mojom::SearchResultIcon::kHardDrive,
+ mojom::SearchResultDefaultRank::kMedium, mojom::kStorageSubpagePath);
+ generator->RegisterNestedSubpage(
+ IDS_SETTINGS_STORAGE_EXTERNAL, mojom::Subpage::kExternalStorage,
+ mojom::Subpage::kStorage, mojom::SearchResultIcon::kHardDrive,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::kExternalStorageSubpagePath);
+ generator->RegisterNestedSubpage(
+ IDS_SETTINGS_DLC_SUBPAGE_TITLE, mojom::Subpage::kDlc,
+ mojom::Subpage::kStorage, mojom::SearchResultIcon::kHardDrive,
+ mojom::SearchResultDefaultRank::kMedium, mojom::kDlcSubpagePath);
+ generator->RegisterNestedSetting(mojom::Setting::kRemoveDlc,
+ mojom::Subpage::kDlc);
+
+ // Power.
+ generator->RegisterTopLevelSubpage(
+ IDS_SETTINGS_POWER_TITLE, mojom::Subpage::kPower,
+ mojom::SearchResultIcon::kPower, mojom::SearchResultDefaultRank::kMedium,
+ mojom::kPowerSubpagePath);
+ static constexpr mojom::Setting kPowerSettings[] = {
+ mojom::Setting::kPowerIdleBehaviorWhileCharging,
+ mojom::Setting::kPowerIdleBehaviorWhileOnBattery,
+ mojom::Setting::kPowerSource,
+ mojom::Setting::kSleepWhenLaptopLidClosed,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kPower, kPowerSettings, generator);
+}
+
void DeviceSection::TouchpadExists(bool exists) {
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+
if (exists)
- registry()->AddSearchTags(GetTouchpadSearchConcepts());
+ updater.AddSearchTags(GetTouchpadSearchConcepts());
else
- registry()->RemoveSearchTags(GetTouchpadSearchConcepts());
+ updater.RemoveSearchTags(GetTouchpadSearchConcepts());
}
void DeviceSection::MouseExists(bool exists) {
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+
if (exists)
- registry()->AddSearchTags(GetMouseSearchConcepts());
+ updater.AddSearchTags(GetMouseSearchConcepts());
else
- registry()->RemoveSearchTags(GetMouseSearchConcepts());
+ updater.RemoveSearchTags(GetMouseSearchConcepts());
}
void DeviceSection::OnDeviceListsComplete() {
@@ -828,12 +1018,32 @@ void DeviceSection::OnDisplayConfigChanged() {
void DeviceSection::PowerChanged(
const power_manager::PowerSupplyProperties& properties) {
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+
if (properties.battery_state() !=
power_manager::PowerSupplyProperties_BatteryState_NOT_PRESENT) {
- registry()->AddSearchTags(GetPowerWithBatterySearchConcepts());
+ updater.AddSearchTags(GetPowerWithBatterySearchConcepts());
}
}
+void DeviceSection::OnGetExistingDlcs(
+ const std::string& err,
+ const dlcservice::DlcsWithContent& dlcs_with_content) {
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+
+ if (err != dlcservice::kErrorNone ||
+ dlcs_with_content.dlc_infos_size() == 0) {
+ updater.RemoveSearchTags(GetDlcSearchConcepts());
+ return;
+ }
+ updater.AddSearchTags(GetDlcSearchConcepts());
+}
+
+void DeviceSection::OnDlcStateChanged(const dlcservice::DlcState& dlc_state) {
+ DlcserviceClient::Get()->GetExistingDlcs(base::BindOnce(
+ &DeviceSection::OnGetExistingDlcs, weak_ptr_factory_.GetWeakPtr()));
+}
+
void DeviceSection::OnGetDisplayUnitInfoList(
std::vector<ash::mojom::DisplayUnitInfoPtr> display_unit_info_list) {
cros_display_config_->GetDisplayLayoutInfo(base::BindOnce(
@@ -863,73 +1073,71 @@ void DeviceSection::OnGetDisplayLayoutInfo(
ash::mojom::DisplayLayoutMode::kUnified;
}
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+
// Arrangement UI.
if (has_multiple_displays || is_mirrored)
- registry()->AddSearchTags(GetDisplayArrangementSearchConcepts());
+ updater.AddSearchTags(GetDisplayArrangementSearchConcepts());
else
- registry()->RemoveSearchTags(GetDisplayArrangementSearchConcepts());
+ updater.RemoveSearchTags(GetDisplayArrangementSearchConcepts());
// Mirror toggle.
if (is_mirrored || (!unified_desktop_mode && has_multiple_displays))
- registry()->AddSearchTags(GetDisplayMirrorSearchConcepts());
+ updater.AddSearchTags(GetDisplayMirrorSearchConcepts());
else
- registry()->RemoveSearchTags(GetDisplayMirrorSearchConcepts());
+ updater.RemoveSearchTags(GetDisplayMirrorSearchConcepts());
// Unified Desktop toggle.
if (unified_desktop_mode ||
(IsUnifiedDesktopAvailable() && has_multiple_displays && !is_mirrored)) {
- registry()->AddSearchTags(GetDisplayUnifiedDesktopSearchConcepts());
+ updater.AddSearchTags(GetDisplayUnifiedDesktopSearchConcepts());
} else {
- registry()->RemoveSearchTags(GetDisplayUnifiedDesktopSearchConcepts());
+ updater.RemoveSearchTags(GetDisplayUnifiedDesktopSearchConcepts());
}
- // Multiple displays UI.
- if (has_multiple_displays)
- registry()->AddSearchTags(GetDisplayMultipleSearchConcepts());
- else
- registry()->RemoveSearchTags(GetDisplayMultipleSearchConcepts());
-
// External display settings.
if (has_external_display)
- registry()->AddSearchTags(GetDisplayExternalSearchConcepts());
+ updater.AddSearchTags(GetDisplayExternalSearchConcepts());
else
- registry()->RemoveSearchTags(GetDisplayExternalSearchConcepts());
+ updater.RemoveSearchTags(GetDisplayExternalSearchConcepts());
// Refresh Rate dropdown.
if (has_external_display && IsListAllDisplayModesEnabled())
- registry()->AddSearchTags(GetDisplayExternalWithRefreshSearchConcepts());
+ updater.AddSearchTags(GetDisplayExternalWithRefreshSearchConcepts());
else
- registry()->RemoveSearchTags(GetDisplayExternalWithRefreshSearchConcepts());
+ updater.RemoveSearchTags(GetDisplayExternalWithRefreshSearchConcepts());
// Orientation settings.
if (!unified_desktop_mode)
- registry()->AddSearchTags(GetDisplayOrientationSearchConcepts());
+ updater.AddSearchTags(GetDisplayOrientationSearchConcepts());
else
- registry()->RemoveSearchTags(GetDisplayOrientationSearchConcepts());
+ updater.RemoveSearchTags(GetDisplayOrientationSearchConcepts());
// Ambient color settings.
if (DoesDeviceSupportAmbientColor() && has_internal_display)
- registry()->AddSearchTags(GetDisplayAmbientSearchConcepts());
+ updater.AddSearchTags(GetDisplayAmbientSearchConcepts());
else
- registry()->RemoveSearchTags(GetDisplayAmbientSearchConcepts());
+ updater.RemoveSearchTags(GetDisplayAmbientSearchConcepts());
// Touch calibration settings.
if (IsTouchCalibrationAvailable())
- registry()->AddSearchTags(GetDisplayTouchCalibrationSearchConcepts());
+ updater.AddSearchTags(GetDisplayTouchCalibrationSearchConcepts());
else
- registry()->RemoveSearchTags(GetDisplayTouchCalibrationSearchConcepts());
+ updater.RemoveSearchTags(GetDisplayTouchCalibrationSearchConcepts());
// Night Light on settings.
if (ash::NightLightController::GetInstance()->GetEnabled())
- registry()->AddSearchTags(GetDisplayNightLightOnSearchConcepts());
+ updater.AddSearchTags(GetDisplayNightLightOnSearchConcepts());
else
- registry()->RemoveSearchTags(GetDisplayNightLightOnSearchConcepts());
+ updater.RemoveSearchTags(GetDisplayNightLightOnSearchConcepts());
}
void DeviceSection::OnGotSwitchStates(
base::Optional<PowerManagerClient::SwitchStates> result) {
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+
if (result && result->lid_state != PowerManagerClient::LidState::NOT_PRESENT)
- registry()->AddSearchTags(GetPowerWithLaptopLidSearchConcepts());
+ updater.AddSearchTags(GetPowerWithLaptopLidSearchConcepts());
}
void DeviceSection::UpdateStylusSearchTags() {
@@ -937,13 +1145,15 @@ void DeviceSection::UpdateStylusSearchTags() {
if (!ui::DeviceDataManager::GetInstance()->AreDeviceListsComplete())
return;
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+
// TODO(https://crbug.com/1071905): Only show stylus settings if a stylus has
// been set up. HasStylusInput() will return true for any stylus-compatible
// device, even if it doesn't have a stylus.
if (ash::stylus_utils::HasStylusInput())
- registry()->AddSearchTags(GetStylusSearchConcepts());
+ updater.AddSearchTags(GetStylusSearchConcepts());
else
- registry()->RemoveSearchTags(GetStylusSearchConcepts());
+ updater.RemoveSearchTags(GetStylusSearchConcepts());
}
void DeviceSection::AddDevicePointersStrings(
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_section.h b/chromium/chrome/browser/ui/webui/settings/chromeos/device_section.h
index 255f63a4963..541b8dbaafc 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_section.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_section.h
@@ -13,6 +13,7 @@
#include "base/optional.h"
#include "chrome/browser/chromeos/system/pointer_device_observer.h"
#include "chrome/browser/ui/webui/settings/chromeos/os_settings_section.h"
+#include "chromeos/dbus/dlcservice/dlcservice_client.h"
#include "chromeos/dbus/power/power_manager_client.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
@@ -24,6 +25,10 @@ namespace content {
class WebUIDataSource;
} // namespace content
+namespace dlcservice {
+class DlcsWithContent;
+} // namespace dlcservice
+
namespace chromeos {
namespace settings {
@@ -35,7 +40,8 @@ class DeviceSection : public OsSettingsSection,
public ui::InputDeviceEventObserver,
public ash::NightLightController::Observer,
public ash::mojom::CrosDisplayConfigObserver,
- public PowerManagerClient::Observer {
+ public PowerManagerClient::Observer,
+ public DlcserviceClient::Observer {
public:
DeviceSection(Profile* profile,
SearchTagRegistry* search_tag_registry,
@@ -46,6 +52,11 @@ class DeviceSection : public OsSettingsSection,
// OsSettingsSection:
void AddLoadTimeData(content::WebUIDataSource* html_source) override;
void AddHandlers(content::WebUI* web_ui) override;
+ int GetSectionNameMessageId() const override;
+ mojom::Section GetSection() const override;
+ mojom::SearchResultIcon GetSectionIcon() const override;
+ std::string GetSectionPath() const override;
+ void RegisterHierarchy(HierarchyGenerator* generator) const override;
// system::PointerDeviceObserver::Observer:
void TouchpadExists(bool exists) override;
@@ -63,6 +74,9 @@ class DeviceSection : public OsSettingsSection,
// PowerManagerClient::Observer:
void PowerChanged(const power_manager::PowerSupplyProperties& proto) override;
+ // DlcserviceClient::Observer:
+ void OnDlcStateChanged(const dlcservice::DlcState& dlc_state) override;
+
void OnGotSwitchStates(
base::Optional<PowerManagerClient::SwitchStates> result);
@@ -74,6 +88,9 @@ class DeviceSection : public OsSettingsSection,
std::vector<ash::mojom::DisplayUnitInfoPtr> display_unit_info_list,
ash::mojom::DisplayLayoutInfoPtr display_layout_info);
+ void OnGetExistingDlcs(const std::string& err,
+ const dlcservice::DlcsWithContent& dlcs_with_content);
+
void AddDevicePointersStrings(content::WebUIDataSource* html_source);
PrefService* pref_service_;
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 584226636b8..e3961f58389 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
@@ -48,6 +48,8 @@ const char* CalculationTypeToEventName(
return "storage-crostini-size-changed";
case calculator::SizeCalculator::CalculationType::kOtherUsers:
return "storage-other-users-size-changed";
+ case calculator::SizeCalculator::CalculationType::kDlcs:
+ return "storage-dlcs-size-changed";
}
NOTREACHED();
return "";
@@ -63,6 +65,7 @@ StorageHandler::StorageHandler(Profile* profile,
apps_size_calculator_(profile),
crostini_size_calculator_(profile),
other_users_size_calculator_(),
+ dlcs_size_calculator_(),
profile_(profile),
source_name_(html_source->GetSource()),
arc_observer_(this),
@@ -115,6 +118,7 @@ void StorageHandler::OnJavascriptAllowed() {
apps_size_calculator_.AddObserver(this);
crostini_size_calculator_.AddObserver(this);
other_users_size_calculator_.AddObserver(this);
+ dlcs_size_calculator_.AddObserver(this);
}
void StorageHandler::OnJavascriptDisallowed() {
@@ -133,6 +137,9 @@ int64_t StorageHandler::RoundByteSize(int64_t bytes) {
return -1;
}
+ if (bytes == 0)
+ return 0;
+
// Subtract one to the original number of bytes.
bytes--;
// Set all the lower bits to 1.
@@ -164,6 +171,7 @@ void StorageHandler::HandleUpdateStorageInfo(const base::ListValue* args) {
apps_size_calculator_.StartCalculation();
crostini_size_calculator_.StartCalculation();
other_users_size_calculator_.StartCalculation();
+ dlcs_size_calculator_.StartCalculation();
}
void StorageHandler::HandleOpenMyFiles(const base::ListValue* unused_args) {
@@ -259,6 +267,7 @@ void StorageHandler::StopObservingEvents() {
apps_size_calculator_.RemoveObserver(this);
crostini_size_calculator_.RemoveObserver(this);
other_users_size_calculator_.RemoveObserver(this);
+ dlcs_size_calculator_.RemoveObserver(this);
}
void StorageHandler::UpdateStorageItem(
@@ -282,6 +291,12 @@ void StorageHandler::UpdateStorageItem(
bool no_other_users = (total_bytes == 0);
FireWebUIListener(CalculationTypeToEventName(calculation_type),
base::Value(message), base::Value(no_other_users));
+ } else if (calculation_type ==
+ calculator::SizeCalculator::CalculationType::kDlcs) {
+ bool dlcs_exist = (total_bytes > 0);
+ FireWebUIListener(CalculationTypeToEventName(calculation_type),
+ base::Value(dlcs_exist), base::Value(message));
+
} else {
FireWebUIListener(CalculationTypeToEventName(calculation_type),
base::Value(message));
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 cdd352797a6..d6b4e79a376 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
@@ -113,6 +113,7 @@ class StorageHandler : public ::settings::SettingsPageUIHandler,
calculator::AppsSizeCalculator apps_size_calculator_;
calculator::CrostiniSizeCalculator crostini_size_calculator_;
calculator::OtherUsersSizeCalculator other_users_size_calculator_;
+ calculator::DlcsSizeCalculator dlcs_size_calculator_;
// Controls if the size of each storage item has been calculated.
std::bitset<calculator::SizeCalculator::kCalculationTypeCount>
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
index 57c1ab89f3c..86e80c50226 100644
--- 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
@@ -23,6 +23,7 @@
#include "chrome/common/webui_url_constants.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile_manager.h"
+#include "chromeos/dbus/dlcservice/fake_dlcservice_client.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"
@@ -96,6 +97,8 @@ class StorageHandlerTest : public testing::Test {
other_users_size_test_api_ =
std::make_unique<calculator::OtherUsersSizeTestAPI>(
handler_.get(), new calculator::OtherUsersSizeCalculator());
+ dlcs_size_test_api_ = std::make_unique<calculator::DlcsSizeTestAPI>(
+ handler_.get(), new calculator::DlcsSizeCalculator());
// Create and register My files directory.
// By emulating chromeos running, GetMyFilesFolderForProfile will return the
@@ -109,6 +112,10 @@ class StorageHandlerTest : public testing::Test {
file_manager::util::GetDownloadsMountPointName(profile_),
storage::kFileSystemTypeNativeLocal, storage::FileSystemMountOption(),
my_files_path));
+
+ chromeos::DlcserviceClient::InitializeFake();
+ fake_dlcservice_client_ = static_cast<chromeos::FakeDlcserviceClient*>(
+ chromeos::DlcserviceClient::Get());
}
void TearDown() override {
@@ -119,7 +126,9 @@ class StorageHandlerTest : public testing::Test {
apps_size_test_api_.reset();
crostini_size_test_api_.reset();
other_users_size_test_api_.reset();
+ dlcs_size_test_api_.reset();
chromeos::disks::DiskMountManager::Shutdown();
+ chromeos::DlcserviceClient::Shutdown();
storage::ExternalMountPoints::GetSystemInstance()->RevokeAllFileSystems();
}
@@ -148,8 +157,11 @@ class StorageHandlerTest : public testing::Test {
!data->arg1()->GetAsString(&name)) {
continue;
}
- if (name == event_name)
+ if (name == event_name) {
+ if (name == "storage-dlcs-size-changed")
+ return data->arg3();
return data->arg2();
+ }
}
return nullptr;
}
@@ -191,6 +203,7 @@ class StorageHandlerTest : public testing::Test {
content::BrowserTaskEnvironment task_environment_;
std::unique_ptr<TestingProfileManager> profile_manager_;
Profile* profile_;
+ chromeos::FakeDlcserviceClient* fake_dlcservice_client_;
std::unique_ptr<calculator::SizeStatTestAPI> size_stat_test_api_;
std::unique_ptr<calculator::MyFilesSizeTestAPI> my_files_size_test_api_;
std::unique_ptr<calculator::BrowsingDataSizeTestAPI>
@@ -198,6 +211,7 @@ class StorageHandlerTest : public testing::Test {
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_;
+ std::unique_ptr<calculator::DlcsSizeTestAPI> dlcs_size_test_api_;
private:
std::unique_ptr<arc::ArcServiceManager> arc_service_manager_;
@@ -341,6 +355,26 @@ TEST_F(StorageHandlerTest, MyFilesSize) {
EXPECT_EQ("81.4 KB", callback->GetString());
}
+TEST_F(StorageHandlerTest, DlcsSize) {
+ dlcservice::DlcsWithContent dlcs_with_content;
+ auto* dlc_info = dlcs_with_content.add_dlc_infos();
+ dlc_info->set_used_bytes_on_disk(1);
+ dlc_info = dlcs_with_content.add_dlc_infos();
+ dlc_info->set_used_bytes_on_disk(2);
+ fake_dlcservice_client_->set_dlcs_with_content(dlcs_with_content);
+
+ // Calculate DLC size.
+ dlcs_size_test_api_->StartCalculation();
+ task_environment_.RunUntilIdle();
+
+ const base::Value* callback =
+ GetWebUICallbackMessage("storage-dlcs-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-dlcs-size-changed' callback";
+
+ // Check return value.
+ EXPECT_EQ("3 B", 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
@@ -449,10 +483,22 @@ TEST_F(StorageHandlerTest, SystemSize) {
ASSERT_FALSE(GetWebUICallbackMessage("storage-system-size-changed"));
// Simulate crostini size callback.
- crostini_size_test_api_->SimulateOnGetCrostiniSize(70 * GB);
+ crostini_size_test_api_->SimulateOnGetCrostiniSize(50 * GB);
callback = GetWebUICallbackMessage("storage-crostini-size-changed");
ASSERT_TRUE(callback) << "No 'storage-crostini-size-changed' callback";
- EXPECT_EQ("70.0 GB", callback->GetString());
+ EXPECT_EQ("50.0 GB", callback->GetString());
+ ASSERT_FALSE(GetWebUICallbackMessage("storage-system-size-changed"));
+
+ // Simulate DLC size callback
+ dlcservice::DlcsWithContent dlcs_with_content;
+ auto* dlc_info = dlcs_with_content.add_dlc_infos();
+ dlc_info->set_used_bytes_on_disk(20 * GB);
+ dlc_info = dlcs_with_content.add_dlc_infos();
+ dlcs_size_test_api_->SimulateOnGetExistingDlcs(dlcservice::kErrorNone,
+ dlcs_with_content);
+ callback = GetWebUICallbackMessage("storage-dlcs-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-dlcs-size-changed' callback";
+ EXPECT_EQ("20.0 GB", callback->GetString());
ASSERT_FALSE(GetWebUICallbackMessage("storage-system-size-changed"));
// Simulate other users size callback. No callback message until the sizes of
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/fake_hierarchy.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/fake_hierarchy.cc
new file mode 100644
index 00000000000..3cf8646c001
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/fake_hierarchy.cc
@@ -0,0 +1,53 @@
+// 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/fake_hierarchy.h"
+
+#include <utility>
+
+#include "chrome/browser/ui/webui/settings/chromeos/fake_os_settings_section.h"
+
+namespace chromeos {
+namespace settings {
+
+FakeHierarchy::FakeHierarchy(const OsSettingsSections* sections)
+ : Hierarchy(sections) {}
+
+FakeHierarchy::~FakeHierarchy() = default;
+
+void FakeHierarchy::AddSubpageMetadata(
+ int name_message_id,
+ mojom::Section section,
+ mojom::Subpage subpage,
+ mojom::SearchResultIcon icon,
+ mojom::SearchResultDefaultRank default_rank,
+ const std::string& url_path_with_parameters,
+ base::Optional<mojom::Subpage> parent_subpage) {
+ auto pair = subpage_map_.emplace(
+ std::piecewise_construct, std::forward_as_tuple(subpage),
+ std::forward_as_tuple(name_message_id, section, subpage, icon,
+ default_rank, url_path_with_parameters, this));
+ DCHECK(pair.second);
+ pair.first->second.parent_subpage = parent_subpage;
+}
+
+void FakeHierarchy::AddSettingMetadata(
+ mojom::Section section,
+ mojom::Setting setting,
+ base::Optional<mojom::Subpage> parent_subpage) {
+ auto pair = setting_map_.emplace(setting, section);
+ DCHECK(pair.second);
+ pair.first->second.primary.second = parent_subpage;
+}
+
+std::string FakeHierarchy::ModifySearchResultUrl(
+ mojom::Section section,
+ mojom::SearchResultType type,
+ OsSettingsIdentifier id,
+ const std::string& url_to_modify) const {
+ return FakeOsSettingsSection::ModifySearchResultUrl(section, url_to_modify);
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/fake_hierarchy.h b/chromium/chrome/browser/ui/webui/settings/chromeos/fake_hierarchy.h
new file mode 100644
index 00000000000..d0fbf813ff3
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/fake_hierarchy.h
@@ -0,0 +1,50 @@
+// 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_FAKE_HIERARCHY_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_FAKE_HIERARCHY_H_
+
+#include "base/optional.h"
+#include "chrome/browser/ui/webui/settings/chromeos/hierarchy.h"
+
+namespace chromeos {
+namespace settings {
+
+class OsSettingsSections;
+
+// Fake Hierarchy implementation. Note that this class currently does not
+// provide "alternate settings location" functionality.
+class FakeHierarchy : public Hierarchy {
+ public:
+ explicit FakeHierarchy(const OsSettingsSections* sections);
+ FakeHierarchy(const FakeHierarchy& other) = delete;
+ FakeHierarchy& operator=(const FakeHierarchy& other) = delete;
+ ~FakeHierarchy() override;
+
+ void AddSubpageMetadata(
+ int name_message_id,
+ mojom::Section section,
+ mojom::Subpage subpage,
+ mojom::SearchResultIcon icon,
+ mojom::SearchResultDefaultRank default_rank,
+ const std::string& url_path_with_parameters,
+ base::Optional<mojom::Subpage> parent_subpage = base::nullopt);
+ void AddSettingMetadata(
+ mojom::Section section,
+ mojom::Setting setting,
+ base::Optional<mojom::Subpage> parent_subpage = base::nullopt);
+
+ private:
+ // Hierarchy:
+ std::string ModifySearchResultUrl(
+ mojom::Section section,
+ mojom::SearchResultType type,
+ OsSettingsIdentifier id,
+ const std::string& url_to_modify) const override;
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_FAKE_HIERARCHY_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_section.cc
new file mode 100644
index 00000000000..473287ebec0
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_section.cc
@@ -0,0 +1,52 @@
+// 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/fake_os_settings_section.h"
+
+#include <sstream>
+
+#include "chrome/grit/generated_resources.h"
+
+namespace chromeos {
+namespace settings {
+
+FakeOsSettingsSection::FakeOsSettingsSection(mojom::Section section)
+ : section_(section) {}
+
+FakeOsSettingsSection::~FakeOsSettingsSection() = default;
+
+int FakeOsSettingsSection::GetSectionNameMessageId() const {
+ return IDS_INTERNAL_APP_SETTINGS;
+}
+
+mojom::Section FakeOsSettingsSection::GetSection() const {
+ return section_;
+}
+
+mojom::SearchResultIcon FakeOsSettingsSection::GetSectionIcon() const {
+ return mojom::SearchResultIcon::kWifi;
+}
+
+std::string FakeOsSettingsSection::GetSectionPath() const {
+ return std::string();
+}
+
+std::string FakeOsSettingsSection::ModifySearchResultUrl(
+ mojom::SearchResultType type,
+ OsSettingsIdentifier id,
+ const std::string& url_to_modify) const {
+ return ModifySearchResultUrl(section_, url_to_modify);
+}
+
+// static
+std::string FakeOsSettingsSection::ModifySearchResultUrl(
+ mojom::Section section,
+ const std::string& url_to_modify) {
+ std::stringstream ss;
+ ss << section << "::" << url_to_modify;
+ return ss.str();
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_section.h b/chromium/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_section.h
new file mode 100644
index 00000000000..4a58417228a
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_section.h
@@ -0,0 +1,56 @@
+// 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_FAKE_OS_SETTINGS_SECTION_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_FAKE_OS_SETTINGS_SECTION_H_
+
+#include "chrome/browser/ui/webui/settings/chromeos/os_settings_section.h"
+
+namespace chromeos {
+namespace settings {
+
+// Fake OsSettingsSection implementation.
+class FakeOsSettingsSection : public OsSettingsSection {
+ public:
+ explicit FakeOsSettingsSection(mojom::Section section);
+ ~FakeOsSettingsSection() override;
+
+ FakeOsSettingsSection(const FakeOsSettingsSection& other) = delete;
+ FakeOsSettingsSection& operator=(const FakeOsSettingsSection& other) = delete;
+
+ mojom::Section section() { return section_; }
+
+ // OsSettingsSection:
+ void AddLoadTimeData(content::WebUIDataSource* html_source) override {}
+ void RegisterHierarchy(HierarchyGenerator* generator) const override {}
+
+ // Returns the settings app name as a default value.
+ int GetSectionNameMessageId() const override;
+
+ mojom::Section GetSection() const override;
+
+ // These functions return arbitrary dummy values.
+ mojom::SearchResultIcon GetSectionIcon() const override;
+ std::string GetSectionPath() const override;
+
+ // Prepends the section name and "::" to the URL in |concept|. For example, if
+ // the URL is "networkDetails" and the section is mojom::Section::kNetwork,
+ // the returned URL is "Section::kNetwork::networkDetails".
+ std::string ModifySearchResultUrl(
+ mojom::SearchResultType type,
+ OsSettingsIdentifier id,
+ const std::string& url_to_modify) const override;
+
+ // Static function used to implement the function above.
+ static std::string ModifySearchResultUrl(mojom::Section section,
+ const std::string& url_to_modify);
+
+ private:
+ const mojom::Section section_;
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_FAKE_OS_SETTINGS_SECTION_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_sections.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_sections.cc
new file mode 100644
index 00000000000..253d965f65e
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_sections.cc
@@ -0,0 +1,24 @@
+// 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/fake_os_settings_sections.h"
+
+#include "chrome/browser/ui/webui/settings/chromeos/constants/constants_util.h"
+#include "chrome/browser/ui/webui/settings/chromeos/fake_os_settings_section.h"
+
+namespace chromeos {
+namespace settings {
+
+FakeOsSettingsSections::FakeOsSettingsSections() : OsSettingsSections() {
+ for (const auto& section : constants::AllSections()) {
+ auto fake_section = std::make_unique<FakeOsSettingsSection>(section);
+ sections_map_[section] = fake_section.get();
+ sections_.push_back(std::move(fake_section));
+ }
+}
+
+FakeOsSettingsSections::~FakeOsSettingsSections() = default;
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_sections.h b/chromium/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_sections.h
new file mode 100644
index 00000000000..2c148a72a69
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/fake_os_settings_sections.h
@@ -0,0 +1,26 @@
+// 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_FAKE_OS_SETTINGS_SECTIONS_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_FAKE_OS_SETTINGS_SECTIONS_H_
+
+#include "chrome/browser/ui/webui/settings/chromeos/os_settings_sections.h"
+
+namespace chromeos {
+namespace settings {
+
+// Collection of FakeOsSettingsSections.
+class FakeOsSettingsSections : public OsSettingsSections {
+ public:
+ FakeOsSettingsSections();
+ FakeOsSettingsSections(const FakeOsSettingsSections& other) = delete;
+ FakeOsSettingsSections& operator=(const FakeOsSettingsSections& other) =
+ delete;
+ ~FakeOsSettingsSections() override;
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_FAKE_OS_SETTINGS_SECTIONS_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/files_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/files_section.cc
index 3b1788101b1..7163b682b59 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/files_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/files_section.cc
@@ -52,7 +52,8 @@ const std::vector<SearchConcept>& GetFilesSearchConcepts() {
FilesSection::FilesSection(Profile* profile,
SearchTagRegistry* search_tag_registry)
: OsSettingsSection(profile, search_tag_registry) {
- registry()->AddSearchTags(GetFilesSearchConcepts());
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+ updater.AddSearchTags(GetFilesSearchConcepts());
}
FilesSection::~FilesSection() = default;
@@ -102,5 +103,31 @@ void FilesSection::AddHandlers(content::WebUI* web_ui) {
profile(), base::DoNothing()));
}
+int FilesSection::GetSectionNameMessageId() const {
+ return IDS_OS_SETTINGS_FILES;
+}
+
+mojom::Section FilesSection::GetSection() const {
+ return mojom::Section::kFiles;
+}
+
+mojom::SearchResultIcon FilesSection::GetSectionIcon() const {
+ return mojom::SearchResultIcon::kFolder;
+}
+
+std::string FilesSection::GetSectionPath() const {
+ return mojom::kFilesSectionPath;
+}
+
+void FilesSection::RegisterHierarchy(HierarchyGenerator* generator) const {
+ generator->RegisterTopLevelSetting(mojom::Setting::kGoogleDriveConnection);
+
+ // Network file shares.
+ generator->RegisterTopLevelSubpage(
+ IDS_SETTINGS_DOWNLOADS_SMB_SHARES, mojom::Subpage::kNetworkFileShares,
+ mojom::SearchResultIcon::kFolder, mojom::SearchResultDefaultRank::kMedium,
+ mojom::kNetworkFileSharesSubpagePath);
+}
+
} // namespace settings
} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/files_section.h b/chromium/chrome/browser/ui/webui/settings/chromeos/files_section.h
index 635bcb9abc0..38b9dc0b236 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/files_section.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/files_section.h
@@ -26,6 +26,11 @@ class FilesSection : public OsSettingsSection {
// OsSettingsSection:
void AddLoadTimeData(content::WebUIDataSource* html_source) override;
void AddHandlers(content::WebUI* web_ui) override;
+ int GetSectionNameMessageId() const override;
+ mojom::Section GetSection() const override;
+ mojom::SearchResultIcon GetSectionIcon() const override;
+ std::string GetSectionPath() const override;
+ void RegisterHierarchy(HierarchyGenerator* generator) const override;
};
} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/google_assistant_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/google_assistant_handler.cc
index 9ef5ec87581..337e66bd4bb 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/google_assistant_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/google_assistant_handler.cc
@@ -6,8 +6,8 @@
#include <utility>
-#include "ash/public/cpp/assistant/assistant_settings.h"
#include "ash/public/cpp/assistant/assistant_setup.h"
+#include "ash/public/cpp/assistant/controller/assistant_controller.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/values.h"
@@ -74,7 +74,7 @@ void GoogleAssistantHandler::RegisterMessages() {
void GoogleAssistantHandler::HandleShowGoogleAssistantSettings(
const base::ListValue* args) {
CHECK_EQ(0U, args->GetSize());
- ash::OpenAssistantSettings();
+ ash::AssistantController::Get()->OpenAssistantSettings();
}
void GoogleAssistantHandler::HandleRetrainVoiceModel(
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/hierarchy.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/hierarchy.cc
new file mode 100644
index 00000000000..7eef6651e04
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/hierarchy.cc
@@ -0,0 +1,318 @@
+// 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/hierarchy.h"
+
+#include <utility>
+
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/ui/webui/settings/chromeos/constants/constants_util.h"
+#include "chrome/browser/ui/webui/settings/chromeos/os_settings_section.h"
+#include "chrome/browser/ui/webui/settings/chromeos/os_settings_sections.h"
+#include "chrome/grit/generated_resources.h"
+#include "ui/base/l10n/l10n_util.h"
+
+namespace chromeos {
+namespace settings {
+namespace {
+
+// Used to generate localized names.
+constexpr double kDummyRelevanceScore = 0;
+
+} // namespace
+
+class Hierarchy::PerSectionHierarchyGenerator
+ : public OsSettingsSection::HierarchyGenerator {
+ public:
+ PerSectionHierarchyGenerator(mojom::Section section,
+ bool* only_contains_link_to_subpage,
+ Hierarchy* hierarchy)
+ : section_(section),
+ only_contains_link_to_subpage_(only_contains_link_to_subpage),
+ hierarchy_(hierarchy) {}
+
+ void RegisterTopLevelSubpage(
+ int name_message_id,
+ mojom::Subpage subpage,
+ mojom::SearchResultIcon icon,
+ mojom::SearchResultDefaultRank default_rank,
+ const std::string& url_path_with_parameters) override {
+ Hierarchy::SubpageMetadata& metadata = GetSubpageMetadata(
+ name_message_id, subpage, icon, default_rank, url_path_with_parameters);
+ CHECK_EQ(section_, metadata.section)
+ << "Subpage registered in multiple sections: " << subpage;
+
+ ++num_top_level_subpages_so_far_;
+
+ // If there are multiple top-level subpages, the section contains more than
+ // just a link to a subpage.
+ if (num_top_level_subpages_so_far_ > 1u)
+ *only_contains_link_to_subpage_ = false;
+ }
+
+ void RegisterNestedSubpage(
+ int name_message_id,
+ mojom::Subpage subpage,
+ mojom::Subpage parent_subpage,
+ mojom::SearchResultIcon icon,
+ mojom::SearchResultDefaultRank default_rank,
+ const std::string& url_path_with_parameters) override {
+ Hierarchy::SubpageMetadata& metadata = GetSubpageMetadata(
+ name_message_id, subpage, icon, default_rank, url_path_with_parameters);
+ CHECK_EQ(section_, metadata.section)
+ << "Subpage registered in multiple sections: " << subpage;
+ CHECK(!metadata.parent_subpage)
+ << "Subpage has multiple registered parent subpages: " << subpage;
+ metadata.parent_subpage = parent_subpage;
+ }
+
+ void RegisterTopLevelSetting(mojom::Setting setting) override {
+ Hierarchy::SettingMetadata& metadata = GetSettingMetadata(setting);
+ CHECK_EQ(section_, metadata.primary.first)
+ << "Setting registered in multiple primary sections: " << setting;
+ CHECK(!metadata.primary.second)
+ << "Setting registered in multiple primary locations: " << setting;
+
+ // If a top-level setting exists, the section contains more than just a link
+ // link to a subpage.
+ *only_contains_link_to_subpage_ = false;
+ }
+
+ void RegisterNestedSetting(mojom::Setting setting,
+ mojom::Subpage subpage) override {
+ Hierarchy::SettingMetadata& metadata = GetSettingMetadata(setting);
+ CHECK_EQ(section_, metadata.primary.first)
+ << "Setting registered in multiple primary sections: " << setting;
+ CHECK(!metadata.primary.second)
+ << "Setting registered in multiple primary locations: " << setting;
+ metadata.primary.second = subpage;
+ }
+
+ void RegisterTopLevelAltSetting(mojom::Setting setting) override {
+ Hierarchy::SettingMetadata& metadata = GetSettingMetadata(setting);
+ CHECK(metadata.primary.first != section_ || metadata.primary.second)
+ << "Setting's primary and alternate locations are identical: "
+ << setting;
+ for (const auto& alternate : metadata.alternates) {
+ CHECK(alternate.first != section_ || alternate.second)
+ << "Setting has multiple identical alternate locations: " << setting;
+ }
+ metadata.alternates.emplace_back(section_, /*subpage=*/base::nullopt);
+
+ // If a top-level setting exists, the section contains more than just a link
+ // link to a subpage.
+ *only_contains_link_to_subpage_ = false;
+ }
+
+ void RegisterNestedAltSetting(mojom::Setting setting,
+ mojom::Subpage subpage) override {
+ Hierarchy::SettingMetadata& metadata = GetSettingMetadata(setting);
+ CHECK(metadata.primary.first != section_ ||
+ metadata.primary.second != subpage)
+ << "Setting's primary and alternate locations are identical: "
+ << setting;
+ for (const auto& alternate : metadata.alternates) {
+ CHECK(alternate.first != section_ || alternate.second != subpage)
+ << "Setting has multiple identical alternate locations: " << setting;
+ }
+ metadata.alternates.emplace_back(section_, subpage);
+ }
+
+ private:
+ Hierarchy::SubpageMetadata& GetSubpageMetadata(
+ int name_message_id,
+ mojom::Subpage subpage,
+ mojom::SearchResultIcon icon,
+ mojom::SearchResultDefaultRank default_rank,
+ const std::string& url_path_with_parameters) {
+ auto& subpage_map = hierarchy_->subpage_map_;
+
+ auto it = subpage_map.find(subpage);
+
+ // Metadata already exists; return it.
+ if (it != subpage_map.end())
+ return it->second;
+
+ // Metadata does not exist yet; insert then return it.
+ auto pair = subpage_map.emplace(
+ std::piecewise_construct, std::forward_as_tuple(subpage),
+ std::forward_as_tuple(name_message_id, section_, subpage, icon,
+ default_rank, url_path_with_parameters,
+ hierarchy_));
+ CHECK(pair.second);
+ return pair.first->second;
+ }
+
+ Hierarchy::SettingMetadata& GetSettingMetadata(mojom::Setting setting) {
+ auto& settings_map = hierarchy_->setting_map_;
+
+ auto it = settings_map.find(setting);
+
+ // Metadata already exists; return it.
+ if (it != settings_map.end())
+ return it->second;
+
+ // Metadata does not exist yet; insert then return it.
+ auto pair = settings_map.emplace(setting, section_);
+ CHECK(pair.second);
+ return pair.first->second;
+ }
+
+ size_t num_top_level_subpages_so_far_ = 0u;
+ mojom::Section section_;
+ bool* only_contains_link_to_subpage_;
+ Hierarchy* hierarchy_;
+};
+
+// Note: |only_contains_link_to_subpage| starts out as true and is set to false
+// if other content is added.
+Hierarchy::SectionMetadata::SectionMetadata(mojom::Section section,
+ const Hierarchy* hierarchy)
+ : only_contains_link_to_subpage(true),
+ section_(section),
+ hierarchy_(hierarchy) {}
+
+Hierarchy::SectionMetadata::~SectionMetadata() = default;
+
+mojom::SearchResultPtr Hierarchy::SectionMetadata::ToSearchResult(
+ double relevance_score) const {
+ return hierarchy_->sections_->GetSection(section_)
+ ->GenerateSectionSearchResult(relevance_score);
+}
+
+Hierarchy::SubpageMetadata::SubpageMetadata(
+ int name_message_id,
+ mojom::Section section,
+ mojom::Subpage subpage,
+ mojom::SearchResultIcon icon,
+ mojom::SearchResultDefaultRank default_rank,
+ const std::string& url_path_with_parameters,
+ const Hierarchy* hierarchy)
+ : section(section),
+ subpage_(subpage),
+ name_message_id_(name_message_id),
+ icon_(icon),
+ default_rank_(default_rank),
+ unmodified_url_path_with_parameters_(url_path_with_parameters),
+ hierarchy_(hierarchy) {}
+
+Hierarchy::SubpageMetadata::~SubpageMetadata() = default;
+
+mojom::SearchResultPtr Hierarchy::SubpageMetadata::ToSearchResult(
+ double relevance_score) const {
+ return mojom::SearchResult::New(
+ /*result_text=*/l10n_util::GetStringUTF16(name_message_id_),
+ /*canonical_result_text=*/l10n_util::GetStringUTF16(name_message_id_),
+ hierarchy_->ModifySearchResultUrl(
+ section, mojom::SearchResultType::kSubpage, {.subpage = subpage_},
+ unmodified_url_path_with_parameters_),
+ icon_, relevance_score,
+ hierarchy_->GenerateAncestorHierarchyStrings(subpage_), default_rank_,
+ /*was_generated_from_text_match=*/false,
+ mojom::SearchResultType::kSubpage,
+ mojom::SearchResultIdentifier::NewSubpage(subpage_));
+}
+
+Hierarchy::SettingMetadata::SettingMetadata(mojom::Section primary_section)
+ : primary(primary_section, /*subpage=*/base::nullopt) {}
+
+Hierarchy::SettingMetadata::~SettingMetadata() = default;
+
+Hierarchy::Hierarchy(const OsSettingsSections* sections) : sections_(sections) {
+ for (const auto& section : constants::AllSections()) {
+ auto pair = section_map_.emplace(std::piecewise_construct,
+ std::forward_as_tuple(section),
+ std::forward_as_tuple(section, this));
+ CHECK(pair.second);
+
+ PerSectionHierarchyGenerator generator(
+ section, &pair.first->second.only_contains_link_to_subpage, this);
+ sections->GetSection(section)->RegisterHierarchy(&generator);
+ }
+}
+
+Hierarchy::~Hierarchy() = default;
+
+const Hierarchy::SectionMetadata& Hierarchy::GetSectionMetadata(
+ mojom::Section section) const {
+ const auto it = section_map_.find(section);
+ CHECK(it != section_map_.end())
+ << "Section missing from settings hierarchy: " << section;
+ return it->second;
+}
+
+const Hierarchy::SubpageMetadata& Hierarchy::GetSubpageMetadata(
+ mojom::Subpage subpage) const {
+ const auto it = subpage_map_.find(subpage);
+ CHECK(it != subpage_map_.end())
+ << "Subpage missing from settings hierarchy: " << subpage;
+ return it->second;
+}
+
+const Hierarchy::SettingMetadata& Hierarchy::GetSettingMetadata(
+ mojom::Setting setting) const {
+ const auto it = setting_map_.find(setting);
+ CHECK(it != setting_map_.end())
+ << "Setting missing from settings hierarchy: " << setting;
+ return it->second;
+}
+
+std::string Hierarchy::ModifySearchResultUrl(
+ mojom::Section section,
+ mojom::SearchResultType type,
+ OsSettingsIdentifier id,
+ const std::string& url_to_modify) const {
+ return sections_->GetSection(section)->ModifySearchResultUrl(type, id,
+ url_to_modify);
+}
+
+std::vector<base::string16> Hierarchy::GenerateAncestorHierarchyStrings(
+ mojom::Subpage subpage) const {
+ const SubpageMetadata& subpage_metadata = GetSubpageMetadata(subpage);
+
+ // Top-level subpage; simply return section hierarchy.
+ if (!subpage_metadata.parent_subpage)
+ return GenerateHierarchyStrings(subpage_metadata.section);
+
+ // Nested subpage; use recursive call, then append parent subpage name itself.
+ std::vector<base::string16> hierarchy_strings =
+ GenerateAncestorHierarchyStrings(*subpage_metadata.parent_subpage);
+ hierarchy_strings.push_back(
+ GetSubpageMetadata(*subpage_metadata.parent_subpage)
+ .ToSearchResult(kDummyRelevanceScore)
+ ->result_text);
+ return hierarchy_strings;
+}
+
+std::vector<base::string16> Hierarchy::GenerateAncestorHierarchyStrings(
+ mojom::Setting setting) const {
+ const SettingMetadata& setting_metadata = GetSettingMetadata(setting);
+
+ // Top-level setting; simply return section hierarchy.
+ if (!setting_metadata.primary.second)
+ return GenerateHierarchyStrings(setting_metadata.primary.first);
+
+ // Nested setting; use subpage ancestors, then append subpage name itself.
+ std::vector<base::string16> hierarchy_strings =
+ GenerateAncestorHierarchyStrings(*setting_metadata.primary.second);
+ hierarchy_strings.push_back(
+ GetSubpageMetadata(*setting_metadata.primary.second)
+ .ToSearchResult(kDummyRelevanceScore)
+ ->result_text);
+ return hierarchy_strings;
+}
+
+std::vector<base::string16> Hierarchy::GenerateHierarchyStrings(
+ mojom::Section section) const {
+ std::vector<base::string16> hierarchy_strings;
+ hierarchy_strings.push_back(
+ l10n_util::GetStringUTF16(IDS_INTERNAL_APP_SETTINGS));
+ hierarchy_strings.push_back(GetSectionMetadata(section)
+ .ToSearchResult(kDummyRelevanceScore)
+ ->result_text);
+ return hierarchy_strings;
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/hierarchy.h b/chromium/chrome/browser/ui/webui/settings/chromeos/hierarchy.h
new file mode 100644
index 00000000000..14b915670d4
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/hierarchy.h
@@ -0,0 +1,171 @@
+// 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_HIERARCHY_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_HIERARCHY_H_
+
+#include <unordered_map>
+#include <utility>
+#include <vector>
+
+#include "base/optional.h"
+#include "base/strings/string16.h"
+#include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h"
+#include "chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom.h"
+#include "chrome/browser/ui/webui/settings/chromeos/os_settings_identifier.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/search.mojom.h"
+
+namespace chromeos {
+namespace settings {
+
+class OsSettingsSections;
+
+// Tracks the OS settings page hierarchy. Settings is composed of a group of
+// sections containing subpages and/or settings, and this class provides
+// metadata for where these subpages/settings reside and what localized strings
+// are used to describe them.
+//
+// A subpage can either be a direct child of a section or can be a nested
+// subpage, meaning that its parent is another subpage.
+//
+// A setting can either be embedded as a direct child of a section or can be
+// a child of a subpage. Additionally, some settings appear in multiple places.
+// For example, the Wi-Fi on/off toggle appears in both the top-level Network
+// section as well as the Wi-Fi subpage. In cases like this, we consider the
+// "primary" location as the more-targeted one - in this example, the Wi-Fi
+// subpage is the primary location of the toggle since it is more specific to
+// Wi-Fi, and the alternate location is the one embedded in the Network section.
+class Hierarchy {
+ public:
+ explicit Hierarchy(const OsSettingsSections* sections);
+ Hierarchy(const Hierarchy& other) = delete;
+ Hierarchy& operator=(const Hierarchy& other) = delete;
+ virtual ~Hierarchy();
+
+ class SectionMetadata {
+ public:
+ SectionMetadata(mojom::Section section, const Hierarchy* hierarchy);
+ ~SectionMetadata();
+
+ // Whether the only contents of the section is a link to a subpage.
+ bool only_contains_link_to_subpage;
+
+ // Generates a search result for this section, using the canonical search
+ // tag as the search result text. |relevance_score| must be passed by the
+ // client, since this result is being created manually instead of via query
+ // matching.
+ mojom::SearchResultPtr ToSearchResult(double relevance_score) const;
+
+ private:
+ mojom::Section section_;
+ const Hierarchy* hierarchy_;
+ };
+
+ class SubpageMetadata {
+ public:
+ SubpageMetadata(int name_message_id,
+ mojom::Section section,
+ mojom::Subpage subpage,
+ mojom::SearchResultIcon icon,
+ mojom::SearchResultDefaultRank default_rank,
+ const std::string& url_path_with_parameters,
+ const Hierarchy* hierarchy);
+ ~SubpageMetadata();
+
+ // The section in which the subpage appears.
+ mojom::Section section;
+
+ // The parent subpage, if applicable. Only applies to nested subpages.
+ base::Optional<mojom::Subpage> parent_subpage;
+
+ // Generates a search result for this subpage, using the canonical search
+ // tag as the search result text. |relevance_score| must be passed by the
+ // client, since this result is being created manually instead of via query
+ // matching.
+ mojom::SearchResultPtr ToSearchResult(double relevance_score) const;
+
+ private:
+ mojom::Subpage subpage_;
+
+ // Message ID corresponding to the localized string used to describe this
+ // subpage.
+ int name_message_id_;
+
+ // Icon used for this subpage.
+ mojom::SearchResultIcon icon_;
+
+ // Default rank; used to order returned results.
+ mojom::SearchResultDefaultRank default_rank_;
+
+ // Static URL path, which may need to be modified via
+ // |modify_url_callback_|.
+ std::string unmodified_url_path_with_parameters_;
+
+ const Hierarchy* hierarchy_;
+ };
+
+ // The location of a setting, which includes its section and, if applicable,
+ // its subpage. Some settings are embedded directly into the section and have
+ // no associated subpage.
+ using SettingLocation =
+ std::pair<mojom::Section, base::Optional<mojom::Subpage>>;
+
+ struct SettingMetadata {
+ explicit SettingMetadata(mojom::Section primary_section);
+ ~SettingMetadata();
+
+ // The primary location, as described above.
+ SettingLocation primary;
+
+ // Alternate locations, as described above. Empty if the setting has no
+ // alternate location.
+ std::vector<SettingLocation> alternates;
+ };
+
+ const SectionMetadata& GetSectionMetadata(mojom::Section section) const;
+ const SubpageMetadata& GetSubpageMetadata(mojom::Subpage subpage) const;
+ const SettingMetadata& GetSettingMetadata(mojom::Setting setting) const;
+
+ // Generates a list of names of the ancestor sections/subpages for |subpage|.
+ // The list contains the Settings app name, the section name and, if
+ // applicable, parent subpage names. Names returned in this list are all
+ // localized string16s which can be displayed in the UI (e.g., as
+ // breadcrumbs).
+ //
+ // Example 1 - Wi-Fi Networks subpage (no parent subpage):
+ // ["Settings", "Network"]
+ // Example 2 - External storage (has parent subpage):
+ // ["Settings", "Device", "Storage management"]
+ std::vector<base::string16> GenerateAncestorHierarchyStrings(
+ mojom::Subpage subpage) const;
+
+ // Same as above, but for settings.
+ std::vector<base::string16> GenerateAncestorHierarchyStrings(
+ mojom::Setting setting) const;
+
+ protected:
+ std::unordered_map<mojom::Section, SectionMetadata> section_map_;
+ std::unordered_map<mojom::Subpage, SubpageMetadata> subpage_map_;
+ std::unordered_map<mojom::Setting, SettingMetadata> setting_map_;
+
+ private:
+ class PerSectionHierarchyGenerator;
+
+ // Generates an array with the Settings app name and |section|'s name.
+ std::vector<base::string16> GenerateHierarchyStrings(
+ mojom::Section section) const;
+
+ virtual std::string ModifySearchResultUrl(
+ mojom::Section section,
+ mojom::SearchResultType type,
+ OsSettingsIdentifier id,
+ const std::string& url_to_modify) const;
+
+ const OsSettingsSections* sections_;
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_HIERARCHY_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/internet_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/internet_section.cc
index c21b0002fb8..69248ed127e 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/internet_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/internet_section.cc
@@ -8,11 +8,13 @@
#include "ash/public/cpp/network_config_service.h"
#include "base/bind.h"
#include "base/no_destructor.h"
+#include "base/strings/stringprintf.h"
#include "chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.h"
#include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h"
#include "chrome/browser/ui/webui/settings/chromeos/internet_handler.h"
#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h"
#include "chrome/browser/ui/webui/webui_util.h"
+#include "chrome/common/chrome_features.h"
#include "chrome/common/url_constants.h"
#include "chrome/common/webui_url_constants.h"
#include "chrome/grit/chromium_strings.h"
@@ -32,7 +34,7 @@ const std::vector<SearchConcept>& GetNetworkSearchConcepts() {
{IDS_OS_SETTINGS_TAG_NETWORK_SETTINGS,
mojom::kNetworkSectionPath,
mojom::SearchResultIcon::kWifi,
- mojom::SearchResultDefaultRank::kHigh,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSection,
{.section = mojom::Section::kNetwork},
{IDS_OS_SETTINGS_TAG_NETWORK_SETTINGS_ALT1, SearchConcept::kAltTagEnd}},
@@ -57,7 +59,7 @@ const std::vector<SearchConcept>& GetEthernetConnectedSearchConcepts() {
{IDS_OS_SETTINGS_TAG_CONFIGURE_IP_AUTOMATICALLY,
mojom::kEthernetDetailsSubpagePath,
mojom::SearchResultIcon::kEthernet,
- mojom::SearchResultDefaultRank::kLow,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kEthernetAutoConfigureIp},
{IDS_OS_SETTINGS_TAG_CONFIGURE_IP_AUTOMATICALLY_ALT1,
@@ -66,7 +68,7 @@ const std::vector<SearchConcept>& GetEthernetConnectedSearchConcepts() {
{IDS_OS_SETTINGS_TAG_NAME_SERVERS,
mojom::kEthernetDetailsSubpagePath,
mojom::SearchResultIcon::kEthernet,
- mojom::SearchResultDefaultRank::kLow,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kEthernetDns},
{IDS_OS_SETTINGS_TAG_NAME_SERVERS_ALT1,
@@ -74,7 +76,7 @@ const std::vector<SearchConcept>& GetEthernetConnectedSearchConcepts() {
{IDS_OS_SETTINGS_TAG_PROXY,
mojom::kEthernetDetailsSubpagePath,
mojom::SearchResultIcon::kEthernet,
- mojom::SearchResultDefaultRank::kLow,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kEthernetProxy},
{IDS_OS_SETTINGS_TAG_PROXY_ALT1, IDS_OS_SETTINGS_TAG_PROXY_ALT2,
@@ -92,12 +94,11 @@ const std::vector<SearchConcept>& GetWifiSearchConcepts() {
mojom::SearchResultDefaultRank::kHigh,
mojom::SearchResultType::kSubpage,
{.subpage = mojom::Subpage::kWifiNetworks},
- {IDS_OS_SETTINGS_TAG_WIFI_ALT1, IDS_OS_SETTINGS_TAG_WIFI_ALT2,
- SearchConcept::kAltTagEnd}},
+ {IDS_OS_SETTINGS_TAG_WIFI_ALT1, SearchConcept::kAltTagEnd}},
{IDS_OS_SETTINGS_TAG_KNOWN_NETWORKS,
mojom::kKnownNetworksSubpagePath,
mojom::SearchResultIcon::kWifi,
- mojom::SearchResultDefaultRank::kHigh,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
{.subpage = mojom::Subpage::kKnownNetworks},
{IDS_OS_SETTINGS_TAG_KNOWN_NETWORKS_ALT1,
@@ -115,6 +116,12 @@ const std::vector<SearchConcept>& GetWifiOnSearchConcepts() {
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kWifiOnOff},
{IDS_OS_SETTINGS_TAG_WIFI_TURN_OFF_ALT1, SearchConcept::kAltTagEnd}},
+ {IDS_OS_SETTINGS_TAG_ADD_WIFI,
+ mojom::kWifiNetworksSubpagePath,
+ mojom::SearchResultIcon::kWifi,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kWifiAddNetwork}},
});
return *tags;
}
@@ -143,17 +150,11 @@ const std::vector<SearchConcept>& GetWifiConnectedSearchConcepts() {
{IDS_OS_SETTINGS_TAG_PREFER_WIFI_NETWORK,
mojom::kWifiDetailsSubpagePath,
mojom::SearchResultIcon::kWifi,
- mojom::SearchResultDefaultRank::kLow,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kPreferWifiNetwork},
{IDS_OS_SETTINGS_TAG_PREFER_WIFI_NETWORK_ALT1,
SearchConcept::kAltTagEnd}},
- {IDS_OS_SETTINGS_TAG_WIFI_CONFIGURE,
- mojom::kWifiDetailsSubpagePath,
- mojom::SearchResultIcon::kWifi,
- mojom::SearchResultDefaultRank::kMedium,
- mojom::SearchResultType::kSetting,
- {.setting = mojom::Setting::kConfigureWifi}},
{IDS_OS_SETTINGS_TAG_FORGET_WIFI,
mojom::kWifiDetailsSubpagePath,
mojom::SearchResultIcon::kWifi,
@@ -163,7 +164,7 @@ const std::vector<SearchConcept>& GetWifiConnectedSearchConcepts() {
{IDS_OS_SETTINGS_TAG_CONFIGURE_IP_AUTOMATICALLY,
mojom::kWifiDetailsSubpagePath,
mojom::SearchResultIcon::kWifi,
- mojom::SearchResultDefaultRank::kLow,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kWifiAutoConfigureIp},
{IDS_OS_SETTINGS_TAG_CONFIGURE_IP_AUTOMATICALLY_ALT1,
@@ -172,7 +173,7 @@ const std::vector<SearchConcept>& GetWifiConnectedSearchConcepts() {
{IDS_OS_SETTINGS_TAG_NAME_SERVERS,
mojom::kWifiDetailsSubpagePath,
mojom::SearchResultIcon::kWifi,
- mojom::SearchResultDefaultRank::kLow,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kWifiDns},
{IDS_OS_SETTINGS_TAG_NAME_SERVERS_ALT1,
@@ -180,7 +181,7 @@ const std::vector<SearchConcept>& GetWifiConnectedSearchConcepts() {
{IDS_OS_SETTINGS_TAG_PROXY,
mojom::kWifiDetailsSubpagePath,
mojom::SearchResultIcon::kWifi,
- mojom::SearchResultDefaultRank::kLow,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kWifiProxy},
{IDS_OS_SETTINGS_TAG_PROXY_ALT1, IDS_OS_SETTINGS_TAG_PROXY_ALT2,
@@ -189,7 +190,7 @@ const std::vector<SearchConcept>& GetWifiConnectedSearchConcepts() {
{IDS_OS_SETTINGS_TAG_AUTO_CONNECT_NETWORK,
mojom::kWifiDetailsSubpagePath,
mojom::SearchResultIcon::kWifi,
- mojom::SearchResultDefaultRank::kLow,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kWifiAutoConnectToNetwork},
{IDS_OS_SETTINGS_TAG_AUTO_CONNECT_NETWORK_ALT1,
@@ -198,6 +199,18 @@ const std::vector<SearchConcept>& GetWifiConnectedSearchConcepts() {
return *tags;
}
+const std::vector<SearchConcept>& GetWifiMeteredSearchConcepts() {
+ static const base::NoDestructor<std::vector<SearchConcept>> tags({
+ {IDS_SETTINGS_INTERNET_NETWORK_METERED,
+ mojom::kWifiDetailsSubpagePath,
+ mojom::SearchResultIcon::kWifi,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kWifiMetered}},
+ });
+ return *tags;
+}
+
const std::vector<SearchConcept>& GetCellularSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
{IDS_OS_SETTINGS_TAG_CELLULAR,
@@ -207,14 +220,7 @@ const std::vector<SearchConcept>& GetCellularSearchConcepts() {
mojom::SearchResultType::kSubpage,
{.subpage = mojom::Subpage::kCellularDetails},
{IDS_OS_SETTINGS_TAG_CELLULAR_ALT1, IDS_OS_SETTINGS_TAG_CELLULAR_ALT2,
- IDS_OS_SETTINGS_TAG_CELLULAR_ALT3, IDS_OS_SETTINGS_TAG_CELLULAR_ALT4,
- SearchConcept::kAltTagEnd}},
- });
- return *tags;
-}
-
-const std::vector<SearchConcept>& GetCellularOnSearchConcepts() {
- static const base::NoDestructor<std::vector<SearchConcept>> tags({
+ IDS_OS_SETTINGS_TAG_CELLULAR_ALT3, SearchConcept::kAltTagEnd}},
{IDS_OS_SETTINGS_TAG_CELLULAR_SIM_LOCK,
mojom::kCellularDetailsSubpagePath,
mojom::SearchResultIcon::kCellular,
@@ -228,6 +234,18 @@ const std::vector<SearchConcept>& GetCellularOnSearchConcepts() {
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kCellularRoaming}},
+ {IDS_OS_SETTINGS_TAG_CELLULAR_APN,
+ mojom::kCellularDetailsSubpagePath,
+ mojom::SearchResultIcon::kCellular,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kCellularApn}},
+ });
+ return *tags;
+}
+
+const std::vector<SearchConcept>& GetCellularOnSearchConcepts() {
+ static const base::NoDestructor<std::vector<SearchConcept>> tags({
{IDS_OS_SETTINGS_TAG_CELLULAR_TURN_OFF,
mojom::kNetworkSectionPath,
mojom::SearchResultIcon::kCellular,
@@ -235,12 +253,6 @@ const std::vector<SearchConcept>& GetCellularOnSearchConcepts() {
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kMobileOnOff},
{IDS_OS_SETTINGS_TAG_CELLULAR_TURN_OFF_ALT1, SearchConcept::kAltTagEnd}},
- {IDS_OS_SETTINGS_TAG_CELLULAR_APN,
- mojom::kCellularDetailsSubpagePath,
- mojom::SearchResultIcon::kCellular,
- mojom::SearchResultDefaultRank::kMedium,
- mojom::SearchResultType::kSetting,
- {.setting = mojom::Setting::kCellularApn}},
});
return *tags;
}
@@ -269,7 +281,7 @@ const std::vector<SearchConcept>& GetCellularConnectedSearchConcepts() {
{IDS_OS_SETTINGS_TAG_CONFIGURE_IP_AUTOMATICALLY,
mojom::kCellularDetailsSubpagePath,
mojom::SearchResultIcon::kCellular,
- mojom::SearchResultDefaultRank::kLow,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kCellularAutoConfigureIp},
{IDS_OS_SETTINGS_TAG_CONFIGURE_IP_AUTOMATICALLY_ALT1,
@@ -278,7 +290,7 @@ const std::vector<SearchConcept>& GetCellularConnectedSearchConcepts() {
{IDS_OS_SETTINGS_TAG_NAME_SERVERS,
mojom::kCellularDetailsSubpagePath,
mojom::SearchResultIcon::kCellular,
- mojom::SearchResultDefaultRank::kLow,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kCellularDns},
{IDS_OS_SETTINGS_TAG_NAME_SERVERS_ALT1,
@@ -286,7 +298,7 @@ const std::vector<SearchConcept>& GetCellularConnectedSearchConcepts() {
{IDS_OS_SETTINGS_TAG_PROXY,
mojom::kCellularDetailsSubpagePath,
mojom::SearchResultIcon::kCellular,
- mojom::SearchResultDefaultRank::kLow,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kCellularProxy},
{IDS_OS_SETTINGS_TAG_PROXY_ALT1, IDS_OS_SETTINGS_TAG_PROXY_ALT2,
@@ -295,7 +307,7 @@ const std::vector<SearchConcept>& GetCellularConnectedSearchConcepts() {
{IDS_OS_SETTINGS_TAG_AUTO_CONNECT_NETWORK,
mojom::kCellularDetailsSubpagePath,
mojom::SearchResultIcon::kCellular,
- mojom::SearchResultDefaultRank::kLow,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kCellularAutoConnectToNetwork},
{IDS_OS_SETTINGS_TAG_AUTO_CONNECT_NETWORK_ALT1,
@@ -304,6 +316,18 @@ const std::vector<SearchConcept>& GetCellularConnectedSearchConcepts() {
return *tags;
}
+const std::vector<SearchConcept>& GetCellularMeteredSearchConcepts() {
+ static const base::NoDestructor<std::vector<SearchConcept>> tags({
+ {IDS_SETTINGS_INTERNET_NETWORK_METERED,
+ mojom::kCellularDetailsSubpagePath,
+ mojom::SearchResultIcon::kCellular,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kCellularMetered}},
+ });
+ return *tags;
+}
+
const std::vector<SearchConcept>& GetInstantTetheringSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
{IDS_OS_SETTINGS_TAG_INSTANT_MOBILE_NETWORKS,
@@ -374,6 +398,52 @@ const std::vector<SearchConcept>& GetVpnConnectedSearchConcepts() {
return *tags;
}
+const std::vector<mojom::Setting>& GetEthernetDetailsSettings() {
+ static const base::NoDestructor<std::vector<mojom::Setting>> settings({
+ mojom::Setting::kConfigureEthernet,
+ mojom::Setting::kEthernetAutoConfigureIp,
+ mojom::Setting::kEthernetDns,
+ mojom::Setting::kEthernetProxy,
+ });
+ return *settings;
+}
+
+const std::vector<mojom::Setting>& GetWifiDetailsSettings() {
+ static const base::NoDestructor<std::vector<mojom::Setting>> settings({
+ mojom::Setting::kDisconnectWifiNetwork,
+ mojom::Setting::kPreferWifiNetwork,
+ mojom::Setting::kForgetWifiNetwork,
+ mojom::Setting::kWifiAutoConfigureIp,
+ mojom::Setting::kWifiDns,
+ mojom::Setting::kWifiProxy,
+ mojom::Setting::kWifiAutoConnectToNetwork,
+ mojom::Setting::kWifiMetered,
+ });
+ return *settings;
+}
+
+const std::vector<mojom::Setting>& GetCellularDetailsSettings() {
+ static const base::NoDestructor<std::vector<mojom::Setting>> settings({
+ mojom::Setting::kCellularSimLock,
+ mojom::Setting::kCellularRoaming,
+ mojom::Setting::kCellularApn,
+ mojom::Setting::kDisconnectCellularNetwork,
+ mojom::Setting::kCellularAutoConfigureIp,
+ mojom::Setting::kCellularDns,
+ mojom::Setting::kCellularProxy,
+ mojom::Setting::kCellularAutoConnectToNetwork,
+ mojom::Setting::kCellularMetered,
+ });
+ return *settings;
+}
+
+const std::vector<mojom::Setting>& GetTetherDetailsSettings() {
+ static const base::NoDestructor<std::vector<mojom::Setting>> settings({
+ mojom::Setting::kDisconnectTetherNetwork,
+ });
+ return *settings;
+}
+
bool IsConnected(network_config::mojom::ConnectionStateType connection_state) {
return connection_state ==
network_config::mojom::ConnectionStateType::kOnline ||
@@ -381,13 +451,49 @@ bool IsConnected(network_config::mojom::ConnectionStateType connection_state) {
network_config::mojom::ConnectionStateType::kConnected;
}
+bool IsPartOfDetailsSubpage(mojom::SearchResultType type,
+ OsSettingsIdentifier id,
+ mojom::Subpage details_subpage) {
+ switch (type) {
+ case mojom::SearchResultType::kSection:
+ // Applies to a section, not a details subpage.
+ return false;
+
+ case mojom::SearchResultType::kSubpage:
+ return id.subpage == details_subpage;
+
+ case mojom::SearchResultType::kSetting: {
+ const mojom::Setting& setting = id.setting;
+ switch (details_subpage) {
+ case mojom::Subpage::kEthernetDetails:
+ return base::Contains(GetEthernetDetailsSettings(), setting);
+ case mojom::Subpage::kWifiDetails:
+ return base::Contains(GetWifiDetailsSettings(), setting);
+ case mojom::Subpage::kCellularDetails:
+ return base::Contains(GetCellularDetailsSettings(), setting);
+ case mojom::Subpage::kTetherDetails:
+ return base::Contains(GetTetherDetailsSettings(), setting);
+ default:
+ return false;
+ }
+ }
+ }
+}
+
+std::string GetDetailsSubpageUrl(const std::string& url_to_modify,
+ const std::string& guid) {
+ return base::StringPrintf("%s?guid=%s", url_to_modify.c_str(), guid.c_str());
+}
+
} // namespace
InternetSection::InternetSection(Profile* profile,
SearchTagRegistry* search_tag_registry)
: OsSettingsSection(profile, search_tag_registry) {
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+
// General network search tags are always added.
- registry()->AddSearchTags(GetNetworkSearchConcepts());
+ updater.AddSearchTags(GetNetworkSearchConcepts());
// Receive updates when devices (e.g., Ethernet, Wi-Fi) go on/offline.
ash::GetNetworkConfigService(
@@ -396,7 +502,7 @@ InternetSection::InternetSection(Profile* profile,
// Fetch initial list of devices and active networks.
FetchDeviceList();
- FetchActiveNetworks();
+ FetchNetworkList();
}
InternetSection::~InternetSection() = default;
@@ -414,6 +520,7 @@ void InternetSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
{"internetConfigName", IDS_SETTINGS_INTERNET_CONFIG_NAME},
{"internetDetailPageTitle", IDS_SETTINGS_INTERNET_DETAIL},
{"internetDeviceEnabling", IDS_SETTINGS_INTERNET_DEVICE_ENABLING},
+ {"internetDeviceDisabling", IDS_SETTINGS_INTERNET_DEVICE_DISABLING},
{"internetDeviceInitializing", IDS_SETTINGS_INTERNET_DEVICE_INITIALIZING},
{"internetJoinType", IDS_SETTINGS_INTERNET_JOIN_TYPE},
{"internetKnownNetworksPageTitle", IDS_SETTINGS_INTERNET_KNOWN_NETWORKS},
@@ -461,6 +568,7 @@ void InternetSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
{"networkConnectNotAllowed", IDS_SETTINGS_INTERNET_CONNECT_NOT_ALLOWED},
{"networkIPAddress", IDS_SETTINGS_INTERNET_NETWORK_IP_ADDRESS},
{"networkIPConfigAuto", IDS_SETTINGS_INTERNET_NETWORK_IP_CONFIG_AUTO},
+ {"networkMetered", IDS_SETTINGS_INTERNET_NETWORK_METERED},
{"networkNameserversLearnMore", IDS_LEARN_MORE},
{"networkPrefer", IDS_SETTINGS_INTERNET_NETWORK_PREFER},
{"networkPrimaryUserControlled",
@@ -477,6 +585,8 @@ void InternetSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
{"networkSectionProxyExpandA11yLabel",
IDS_SETTINGS_INTERNET_NETWORK_SECTION_PROXY_ACCESSIBILITY_LABEL},
{"networkShared", IDS_SETTINGS_INTERNET_NETWORK_SHARED},
+ {"networkSharedOwner", IDS_SETTINGS_INTERNET_NETWORK_SHARED_OWNER},
+ {"networkSharedNotOwner", IDS_SETTINGS_INTERNET_NETWORK_SHARED_NOT_OWNER},
{"networkVpnBuiltin", IDS_NETWORK_TYPE_VPN_BUILTIN},
{"networkOutOfRange", IDS_SETTINGS_INTERNET_WIFI_NETWORK_OUT_OF_RANGE},
{"cellularContactSpecificCarrier",
@@ -535,14 +645,17 @@ void InternetSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
html_source->AddBoolean("showTechnologyBadge",
!ash::features::IsSeparateNetworkIconsEnabled());
+ html_source->AddBoolean(
+ "showMeteredToggle",
+ base::FeatureList::IsEnabled(features::kMeteredShowToggle));
html_source->AddString("networkGoogleNameserversLearnMoreUrl",
chrome::kGoogleNameserversLearnMoreURL);
html_source->AddString(
- "networkSyncedShared",
+ "networkNotSynced",
l10n_util::GetStringFUTF16(
- IDS_SETTINGS_INTERNET_NETWORK_SYNCED_SHARED,
+ IDS_SETTINGS_INTERNET_NETWORK_NOT_SYNCED,
GetHelpUrlWithBoard(chrome::kWifiSyncLearnMoreURL)));
html_source->AddString(
"networkSyncedUser",
@@ -550,6 +663,11 @@ void InternetSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
IDS_SETTINGS_INTERNET_NETWORK_SYNCED_USER,
GetHelpUrlWithBoard(chrome::kWifiSyncLearnMoreURL)));
html_source->AddString(
+ "networkSyncedDevice",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_INTERNET_NETWORK_SYNCED_DEVICE,
+ GetHelpUrlWithBoard(chrome::kWifiSyncLearnMoreURL)));
+ html_source->AddString(
"internetNoNetworksMobileData",
l10n_util::GetStringFUTF16(
IDS_SETTINGS_INTERNET_LOOKING_FOR_MOBILE_NETWORK,
@@ -560,13 +678,140 @@ void InternetSection::AddHandlers(content::WebUI* web_ui) {
web_ui->AddMessageHandler(std::make_unique<InternetHandler>(profile()));
}
+int InternetSection::GetSectionNameMessageId() const {
+ return IDS_SETTINGS_INTERNET;
+}
+
+mojom::Section InternetSection::GetSection() const {
+ return mojom::Section::kNetwork;
+}
+
+mojom::SearchResultIcon InternetSection::GetSectionIcon() const {
+ return mojom::SearchResultIcon::kWifi;
+}
+
+std::string InternetSection::GetSectionPath() const {
+ return mojom::kNetworkSectionPath;
+}
+
+void InternetSection::RegisterHierarchy(HierarchyGenerator* generator) const {
+ // Ethernet details.
+ generator->RegisterTopLevelSubpage(IDS_SETTINGS_INTERNET_ETHERNET_DETAILS,
+ mojom::Subpage::kEthernetDetails,
+ mojom::SearchResultIcon::kEthernet,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::kEthernetDetailsSubpagePath);
+ RegisterNestedSettingBulk(mojom::Subpage::kEthernetDetails,
+ GetEthernetDetailsSettings(), generator);
+
+ // Wi-Fi networks.
+ generator->RegisterTopLevelSubpage(
+ IDS_SETTINGS_INTERNET_WIFI_NETWORKS, mojom::Subpage::kWifiNetworks,
+ mojom::SearchResultIcon::kWifi, mojom::SearchResultDefaultRank::kMedium,
+ mojom::kWifiNetworksSubpagePath);
+ static constexpr mojom::Setting kWifiNetworksSettings[] = {
+ mojom::Setting::kWifiOnOff,
+ mojom::Setting::kWifiAddNetwork,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kWifiNetworks,
+ kWifiNetworksSettings, generator);
+ generator->RegisterTopLevelAltSetting(mojom::Setting::kWifiOnOff);
+
+ // Wi-Fi details.
+ generator->RegisterNestedSubpage(
+ IDS_SETTINGS_INTERNET_WIFI_DETAILS, mojom::Subpage::kWifiDetails,
+ mojom::Subpage::kWifiNetworks, mojom::SearchResultIcon::kWifi,
+ mojom::SearchResultDefaultRank::kMedium, mojom::kWifiDetailsSubpagePath);
+ RegisterNestedSettingBulk(mojom::Subpage::kWifiDetails,
+ GetWifiDetailsSettings(), generator);
+
+ // Known networks.
+ generator->RegisterNestedSubpage(
+ IDS_SETTINGS_INTERNET_KNOWN_NETWORKS, mojom::Subpage::kKnownNetworks,
+ mojom::Subpage::kWifiNetworks, mojom::SearchResultIcon::kWifi,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::kKnownNetworksSubpagePath);
+ generator->RegisterNestedAltSetting(mojom::Setting::kPreferWifiNetwork,
+ mojom::Subpage::kKnownNetworks);
+ generator->RegisterNestedAltSetting(mojom::Setting::kForgetWifiNetwork,
+ mojom::Subpage::kKnownNetworks);
+
+ // Mobile data. If Instant Tethering is available, a mobile data subpage is
+ // available which lists both Cellular and Instant Tethering networks. If
+ // Instant Tethering is not available, there is no mobile data subpage.
+ generator->RegisterTopLevelSubpage(IDS_SETTINGS_INTERNET_MOBILE_DATA_NETWORKS,
+ mojom::Subpage::kMobileDataNetworks,
+ mojom::SearchResultIcon::kCellular,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::kMobileDataNetworksSubpagePath);
+ static constexpr mojom::Setting kMobileDataNetworksSettings[] = {
+ mojom::Setting::kMobileOnOff,
+ mojom::Setting::kInstantTetheringOnOff,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kMobileDataNetworks,
+ kMobileDataNetworksSettings, generator);
+ generator->RegisterTopLevelAltSetting(mojom::Setting::kMobileOnOff);
+
+ // Cellular details. Cellular details are considered a child of the mobile
+ // data subpage. However, note that if Instant Tethering is not available,
+ // clicking on "Mobile data" at the Network section navigates users directly
+ // to the cellular details page and skips over the mobile data subpage.
+ generator->RegisterNestedSubpage(
+ IDS_SETTINGS_INTERNET_CELLULAR_DETAILS, mojom::Subpage::kCellularDetails,
+ mojom::Subpage::kMobileDataNetworks, mojom::SearchResultIcon::kCellular,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::kCellularDetailsSubpagePath);
+ RegisterNestedSettingBulk(mojom::Subpage::kCellularDetails,
+ GetCellularDetailsSettings(), generator);
+
+ // Instant Tethering. Although this is a multi-device feature, its UI resides
+ // in the network section.
+ generator->RegisterNestedSubpage(
+ IDS_SETTINGS_INTERNET_INSTANT_TETHERING_DETAILS,
+ mojom::Subpage::kTetherDetails, mojom::Subpage::kMobileDataNetworks,
+ mojom::SearchResultIcon::kInstantTethering,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::kTetherDetailsSubpagePath);
+ RegisterNestedSettingBulk(mojom::Subpage::kTetherDetails,
+ GetTetherDetailsSettings(), generator);
+
+ // VPN.
+ generator->RegisterTopLevelSubpage(
+ IDS_SETTINGS_INTERNET_VPN_DETAILS, mojom::Subpage::kVpnDetails,
+ mojom::SearchResultIcon::kWifi, mojom::SearchResultDefaultRank::kMedium,
+ mojom::kVpnDetailsSubpagePath);
+}
+
+std::string InternetSection::ModifySearchResultUrl(
+ mojom::SearchResultType type,
+ OsSettingsIdentifier id,
+ const std::string& url_to_modify) const {
+ if (IsPartOfDetailsSubpage(type, id, mojom::Subpage::kEthernetDetails))
+ return GetDetailsSubpageUrl(url_to_modify, *connected_ethernet_guid_);
+
+ if (IsPartOfDetailsSubpage(type, id, mojom::Subpage::kWifiDetails))
+ return GetDetailsSubpageUrl(url_to_modify, *connected_wifi_guid_);
+
+ if (IsPartOfDetailsSubpage(type, id, mojom::Subpage::kCellularDetails))
+ return GetDetailsSubpageUrl(url_to_modify, *cellular_guid_);
+
+ if (IsPartOfDetailsSubpage(type, id, mojom::Subpage::kTetherDetails))
+ return GetDetailsSubpageUrl(url_to_modify, *connected_tether_guid_);
+
+ if (IsPartOfDetailsSubpage(type, id, mojom::Subpage::kVpnDetails))
+ return GetDetailsSubpageUrl(url_to_modify, *connected_vpn_guid_);
+
+ // URL does not need to be modified; use default implementation.
+ return OsSettingsSection::ModifySearchResultUrl(type, id, url_to_modify);
+}
+
void InternetSection::OnDeviceStateListChanged() {
FetchDeviceList();
}
void InternetSection::OnActiveNetworksChanged(
std::vector<network_config::mojom::NetworkStatePropertiesPtr> networks) {
- OnActiveNetworks(std::move(networks));
+ FetchNetworkList();
}
void InternetSection::FetchDeviceList() {
@@ -579,40 +824,43 @@ void InternetSection::OnDeviceList(
using network_config::mojom::DeviceStateType;
using network_config::mojom::NetworkType;
- registry()->RemoveSearchTags(GetWifiSearchConcepts());
- registry()->RemoveSearchTags(GetWifiOnSearchConcepts());
- registry()->RemoveSearchTags(GetWifiOffSearchConcepts());
- registry()->RemoveSearchTags(GetCellularSearchConcepts());
- registry()->RemoveSearchTags(GetCellularOnSearchConcepts());
- registry()->RemoveSearchTags(GetCellularOffSearchConcepts());
- registry()->RemoveSearchTags(GetInstantTetheringSearchConcepts());
- registry()->RemoveSearchTags(GetInstantTetheringOnSearchConcepts());
- registry()->RemoveSearchTags(GetInstantTetheringOffSearchConcepts());
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+
+ updater.RemoveSearchTags(GetWifiSearchConcepts());
+ updater.RemoveSearchTags(GetWifiOnSearchConcepts());
+ updater.RemoveSearchTags(GetWifiOffSearchConcepts());
+ updater.RemoveSearchTags(GetCellularOnSearchConcepts());
+ updater.RemoveSearchTags(GetCellularOffSearchConcepts());
+ updater.RemoveSearchTags(GetInstantTetheringSearchConcepts());
+ updater.RemoveSearchTags(GetInstantTetheringOnSearchConcepts());
+ updater.RemoveSearchTags(GetInstantTetheringOffSearchConcepts());
for (const auto& device : devices) {
switch (device->type) {
case NetworkType::kWiFi:
- registry()->AddSearchTags(GetWifiSearchConcepts());
+ updater.AddSearchTags(GetWifiSearchConcepts());
if (device->device_state == DeviceStateType::kEnabled)
- registry()->AddSearchTags(GetWifiOnSearchConcepts());
+ updater.AddSearchTags(GetWifiOnSearchConcepts());
else if (device->device_state == DeviceStateType::kDisabled)
- registry()->AddSearchTags(GetWifiOffSearchConcepts());
+ updater.AddSearchTags(GetWifiOffSearchConcepts());
break;
case NetworkType::kCellular:
- registry()->AddSearchTags(GetCellularSearchConcepts());
+ // Note: Cellular search concepts all point to the cellular details
+ // page, which is only available if a cellular network exists. This
+ // check is in OnNetworkList().
if (device->device_state == DeviceStateType::kEnabled)
- registry()->AddSearchTags(GetCellularOnSearchConcepts());
+ updater.AddSearchTags(GetCellularOnSearchConcepts());
else if (device->device_state == DeviceStateType::kDisabled)
- registry()->AddSearchTags(GetCellularOffSearchConcepts());
+ updater.AddSearchTags(GetCellularOffSearchConcepts());
break;
case NetworkType::kTether:
- registry()->AddSearchTags(GetInstantTetheringSearchConcepts());
+ updater.AddSearchTags(GetInstantTetheringSearchConcepts());
if (device->device_state == DeviceStateType::kEnabled)
- registry()->AddSearchTags(GetInstantTetheringOnSearchConcepts());
+ updater.AddSearchTags(GetInstantTetheringOnSearchConcepts());
else if (device->device_state == DeviceStateType::kDisabled)
- registry()->AddSearchTags(GetInstantTetheringOffSearchConcepts());
+ updater.AddSearchTags(GetInstantTetheringOffSearchConcepts());
break;
default:
@@ -623,48 +871,76 @@ void InternetSection::OnDeviceList(
}
}
-void InternetSection::FetchActiveNetworks() {
+void InternetSection::FetchNetworkList() {
cros_network_config_->GetNetworkStateList(
network_config::mojom::NetworkFilter::New(
- network_config::mojom::FilterType::kActive,
+ network_config::mojom::FilterType::kVisible,
network_config::mojom::NetworkType::kAll,
network_config::mojom::kNoLimit),
- base::Bind(&InternetSection::OnActiveNetworks, base::Unretained(this)));
+ base::Bind(&InternetSection::OnNetworkList, base::Unretained(this)));
}
-void InternetSection::OnActiveNetworks(
+void InternetSection::OnNetworkList(
std::vector<network_config::mojom::NetworkStatePropertiesPtr> networks) {
using network_config::mojom::NetworkType;
- registry()->RemoveSearchTags(GetEthernetConnectedSearchConcepts());
- registry()->RemoveSearchTags(GetWifiConnectedSearchConcepts());
- registry()->RemoveSearchTags(GetCellularConnectedSearchConcepts());
- registry()->RemoveSearchTags(GetInstantTetheringConnectedSearchConcepts());
- registry()->RemoveSearchTags(GetVpnConnectedSearchConcepts());
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+
+ updater.RemoveSearchTags(GetEthernetConnectedSearchConcepts());
+ updater.RemoveSearchTags(GetWifiConnectedSearchConcepts());
+ updater.RemoveSearchTags(GetWifiMeteredSearchConcepts());
+ updater.RemoveSearchTags(GetCellularSearchConcepts());
+ updater.RemoveSearchTags(GetCellularConnectedSearchConcepts());
+ updater.RemoveSearchTags(GetCellularMeteredSearchConcepts());
+ updater.RemoveSearchTags(GetInstantTetheringConnectedSearchConcepts());
+ updater.RemoveSearchTags(GetVpnConnectedSearchConcepts());
+
+ cellular_guid_.reset();
+
+ connected_ethernet_guid_.reset();
+ connected_wifi_guid_.reset();
+ connected_tether_guid_.reset();
+ connected_vpn_guid_.reset();
for (const auto& network : networks) {
+ // Special case: Some cellular search functionality is available even if the
+ // network is not connected.
+ if (network->type == NetworkType::kCellular) {
+ cellular_guid_ = network->guid;
+ updater.AddSearchTags(GetCellularSearchConcepts());
+ }
+
if (!IsConnected(network->connection_state))
continue;
switch (network->type) {
case NetworkType::kEthernet:
- registry()->AddSearchTags(GetEthernetConnectedSearchConcepts());
+ connected_ethernet_guid_ = network->guid;
+ updater.AddSearchTags(GetEthernetConnectedSearchConcepts());
break;
case NetworkType::kWiFi:
- registry()->AddSearchTags(GetWifiConnectedSearchConcepts());
+ connected_wifi_guid_ = network->guid;
+ updater.AddSearchTags(GetWifiConnectedSearchConcepts());
+ if (base::FeatureList::IsEnabled(features::kMeteredShowToggle))
+ updater.AddSearchTags(GetWifiMeteredSearchConcepts());
break;
case NetworkType::kCellular:
- registry()->AddSearchTags(GetCellularConnectedSearchConcepts());
+ // Note: GUID is set above.
+ updater.AddSearchTags(GetCellularConnectedSearchConcepts());
+ if (base::FeatureList::IsEnabled(features::kMeteredShowToggle))
+ updater.AddSearchTags(GetCellularMeteredSearchConcepts());
break;
case NetworkType::kTether:
- registry()->AddSearchTags(GetInstantTetheringConnectedSearchConcepts());
+ connected_tether_guid_ = network->guid;
+ updater.AddSearchTags(GetInstantTetheringConnectedSearchConcepts());
break;
case NetworkType::kVPN:
- registry()->AddSearchTags(GetVpnConnectedSearchConcepts());
+ connected_vpn_guid_ = network->guid;
+ updater.AddSearchTags(GetVpnConnectedSearchConcepts());
break;
default:
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/internet_section.h b/chromium/chrome/browser/ui/webui/settings/chromeos/internet_section.h
index f467529b810..cbe35474631 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/internet_section.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/internet_section.h
@@ -5,8 +5,10 @@
#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_INTERNET_SECTION_H_
#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_INTERNET_SECTION_H_
+#include <string>
#include <vector>
+#include "base/optional.h"
#include "chrome/browser/ui/webui/settings/chromeos/os_settings_section.h"
#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h"
#include "mojo/public/cpp/bindings/receiver.h"
@@ -34,6 +36,15 @@ class InternetSection
// OsSettingsSection:
void AddLoadTimeData(content::WebUIDataSource* html_source) override;
void AddHandlers(content::WebUI* web_ui) override;
+ int GetSectionNameMessageId() const override;
+ mojom::Section GetSection() const override;
+ mojom::SearchResultIcon GetSectionIcon() const override;
+ std::string GetSectionPath() const override;
+ void RegisterHierarchy(HierarchyGenerator* generator) const override;
+ std::string ModifySearchResultUrl(
+ mojom::SearchResultType type,
+ OsSettingsIdentifier id,
+ const std::string& url_to_modify) const override;
// network_config::mojom::CrosNetworkConfigObserver:
void OnActiveNetworksChanged(
@@ -51,10 +62,19 @@ class InternetSection
void OnDeviceList(
std::vector<network_config::mojom::DeviceStatePropertiesPtr> devices);
- void FetchActiveNetworks();
- void OnActiveNetworks(
+ void FetchNetworkList();
+ void OnNetworkList(
std::vector<network_config::mojom::NetworkStatePropertiesPtr> networks);
+ // Null if no cellular network exists.
+ base::Optional<std::string> cellular_guid_;
+
+ // Note: If not connected, the below fields are null.
+ base::Optional<std::string> connected_ethernet_guid_;
+ base::Optional<std::string> connected_wifi_guid_;
+ base::Optional<std::string> connected_tether_guid_;
+ base::Optional<std::string> connected_vpn_guid_;
+
mojo::Receiver<network_config::mojom::CrosNetworkConfigObserver> receiver_{
this};
mojo::Remote<network_config::mojom::CrosNetworkConfig> cros_network_config_;
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/languages_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/languages_section.cc
index 0007f1a6a8b..78321bd8c64 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/languages_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/languages_section.cc
@@ -7,6 +7,7 @@
#include "base/feature_list.h"
#include "base/no_destructor.h"
#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/settings/chromeos/os_settings_features_util.h"
#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h"
#include "chrome/browser/ui/webui/settings/languages_handler.h"
@@ -14,6 +15,8 @@
#include "chrome/common/url_constants.h"
#include "chrome/grit/generated_resources.h"
#include "chromeos/constants/chromeos_features.h"
+#include "chromeos/constants/chromeos_pref_names.h"
+#include "components/prefs/pref_service.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"
@@ -57,7 +60,7 @@ const std::vector<SearchConcept>& GetLanguagesSearchConcepts() {
const std::vector<SearchConcept>& GetSmartInputsSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
{IDS_OS_SETTINGS_TAG_LANGUAGES_SMART_INPUTS,
- mojom::kSmartInputsSubagePath,
+ mojom::kSmartInputsSubpagePath,
mojom::SearchResultIcon::kGlobe,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
@@ -69,7 +72,7 @@ const std::vector<SearchConcept>& GetSmartInputsSearchConcepts() {
const std::vector<SearchConcept>& GetAssistivePersonalInfoSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
{IDS_OS_SETTINGS_TAG_LANGUAGES_PERSONAL_INFORMATION_SUGGESTIONS,
- mojom::kSmartInputsSubagePath,
+ mojom::kSmartInputsSubpagePath,
mojom::SearchResultIcon::kGlobe,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
@@ -78,13 +81,26 @@ const std::vector<SearchConcept>& GetAssistivePersonalInfoSearchConcepts() {
return *tags;
}
+const std::vector<SearchConcept>& GetEmojiSuggestionSearchConcepts() {
+ static const base::NoDestructor<std::vector<SearchConcept>> tags({
+ {IDS_OS_SETTINGS_TAG_LANGUAGES_EMOJI_SUGGESTIONS,
+ mojom::kSmartInputsSubpagePath,
+ mojom::SearchResultIcon::kGlobe,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kShowEmojiSuggestions}},
+ });
+ return *tags;
+}
+
bool IsAssistivePersonalInfoAllowed() {
return !features::IsGuestModeActive() &&
base::FeatureList::IsEnabled(
::chromeos::features::kAssistPersonalInfo);
}
-void AddSmartInputsStrings(content::WebUIDataSource* html_source) {
+void AddSmartInputsStrings(content::WebUIDataSource* html_source,
+ bool is_emoji_suggestion_allowed) {
static constexpr webui::LocalizedString kLocalizedStrings[] = {
{"smartInputsTitle", IDS_SETTINGS_SMART_INPUTS_TITLE},
{"personalInfoSuggestionTitle",
@@ -94,11 +110,71 @@ void AddSmartInputsStrings(content::WebUIDataSource* html_source) {
{"showPersonalInfoSuggestion",
IDS_SETTINGS_SMART_INPUTS_SHOW_PERSONAL_INFO},
{"managePersonalInfo", IDS_SETTINGS_SMART_INPUTS_MANAGE_PERSONAL_INFO},
+ {"emojiSuggestionTitle",
+ IDS_SETTINGS_SMART_INPUTS_EMOJI_SUGGESTION_TITLE},
+ {"emojiSuggestionDescription",
+ IDS_SETTINGS_SMART_INPUTS_EMOJI_SUGGESTION_DESCRIPTION},
+ {"showEmojiSuggestion", IDS_SETTINGS_SMART_INPUTS_SHOW_EMOJI_SUGGESTION},
};
AddLocalizedStringsBulk(html_source, kLocalizedStrings);
html_source->AddBoolean("allowAssistivePersonalInfo",
IsAssistivePersonalInfoAllowed());
+ html_source->AddBoolean("allowEmojiSuggestion", is_emoji_suggestion_allowed);
+}
+
+void AddInputMethodOptionsStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"inputMethodOptionsBasicSectionTitle",
+ IDS_SETTINGS_INPUT_METHOD_OPTIONS_BASIC},
+ {"inputMethodOptionsAdvancedSectionTitle",
+ IDS_SETTINGS_INPUT_METHOD_OPTIONS_ADVANCED},
+ {"inputMethodOptionsPhysicalKeyboardSectionTitle",
+ IDS_SETTINGS_INPUT_METHOD_OPTIONS_PHYSICAL_KEYBOARD},
+ {"inputMethodOptionsVirtualKeyboardSectionTitle",
+ IDS_SETTINGS_INPUT_METHOD_OPTIONS_VIRTUAL_KEYBOARD},
+ {"inputMethodOptionsEnableDoubleSpacePeriod",
+ IDS_SETTINGS_INPUT_METHOD_OPTIONS_ENABLE_DOUBLE_SPACE_PERIOD},
+ {"inputMethodOptionsEnableGestureTyping",
+ IDS_SETTINGS_INPUT_METHOD_OPTIONS_ENABLE_GESTURE_TYPING},
+ {"inputMethodOptionsEnablePrediction",
+ IDS_SETTINGS_INPUT_METHOD_OPTIONS_ENABLE_PREDICTION},
+ {"inputMethodOptionsEnableSoundOnKeypress",
+ IDS_SETTINGS_INPUT_METHOD_OPTIONS_ENABLE_SOUND_ON_KEYPRESS},
+ {"inputMethodOptionsEnableCapitalization",
+ IDS_SETTINGS_INPUT_METHOD_OPTIONS_ENABLE_CAPITALIZATION},
+ {"inputMethodOptionsAutoCorrection",
+ IDS_SETTINGS_INPUT_METHOD_OPTIONS_AUTO_CORRECTION},
+ {"inputMethodOptionsXkbLayout",
+ IDS_SETTINGS_INPUT_METHOD_OPTIONS_XKB_LAYOUT},
+ {"inputMethodOptionsEditUserDict",
+ IDS_SETTINGS_INPUT_METHOD_OPTIONS_EDIT_USER_DICT},
+ {"inputMethodOptionsPinyinChinesePunctuation",
+ IDS_SETTINGS_INPUT_METHOD_OPTIONS_PINYIN_CHINESE_PUNCTUATION},
+ {"inputMethodOptionsPinyinDefaultChinese",
+ IDS_SETTINGS_INPUT_METHOD_OPTIONS_PINYIN_DEFAULT_CHINESE},
+ {"inputMethodOptionsPinyinEnableFuzzy",
+ IDS_SETTINGS_INPUT_METHOD_OPTIONS_PINYIN_ENABLE_FUZZY},
+ {"inputMethodOptionsPinyinEnableLowerPaging",
+ IDS_SETTINGS_INPUT_METHOD_OPTIONS_PINYIN_ENABLE_LOWER_PAGING},
+ {"inputMethodOptionsPinyinEnableUpperPaging",
+ IDS_SETTINGS_INPUT_METHOD_OPTIONS_PINYIN_ENABLE_UPPER_PAGING},
+ {"inputMethodOptionsPinyinFullWidthCharacter",
+ IDS_SETTINGS_INPUT_METHOD_OPTIONS_PINYIN_FULL_WIDTH_CHARACTER},
+ {"inputMethodOptionsAutoCorrectionOff",
+ IDS_SETTINGS_INPUT_METHOD_OPTIONS_AUTO_CORRECTION_OFF},
+ {"inputMethodOptionsAutoCorrectionModest",
+ IDS_SETTINGS_INPUT_METHOD_OPTIONS_AUTO_CORRECTION_MODEST},
+ {"inputMethodOptionsAutoCorrectionAggressive",
+ IDS_SETTINGS_INPUT_METHOD_OPTIONS_AUTO_CORRECTION_AGGRESSIVE},
+ {"inputMethodOptionsUsKeyboard",
+ IDS_SETTINGS_INPUT_METHOD_OPTIONS_KEYBOARD_US},
+ {"inputMethodOptionsDvorakKeyboard",
+ IDS_SETTINGS_INPUT_METHOD_OPTIONS_KEYBOARD_DVORAK},
+ {"inputMethodOptionsColemakKeyboard",
+ IDS_SETTINGS_INPUT_METHOD_OPTIONS_KEYBOARD_COLEMAK},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
}
} // namespace
@@ -106,11 +182,15 @@ void AddSmartInputsStrings(content::WebUIDataSource* html_source) {
LanguagesSection::LanguagesSection(Profile* profile,
SearchTagRegistry* search_tag_registry)
: OsSettingsSection(profile, search_tag_registry) {
- registry()->AddSearchTags(GetLanguagesSearchConcepts());
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+ updater.AddSearchTags(GetLanguagesSearchConcepts());
- if (IsAssistivePersonalInfoAllowed()) {
- registry()->AddSearchTags(GetSmartInputsSearchConcepts());
- registry()->AddSearchTags(GetAssistivePersonalInfoSearchConcepts());
+ if (IsAssistivePersonalInfoAllowed() || IsEmojiSuggestionAllowed()) {
+ updater.AddSearchTags(GetSmartInputsSearchConcepts());
+ if (IsAssistivePersonalInfoAllowed())
+ updater.AddSearchTags(GetAssistivePersonalInfoSearchConcepts());
+ if (IsEmojiSuggestionAllowed())
+ updater.AddSearchTags(GetEmojiSuggestionSearchConcepts());
}
}
@@ -149,11 +229,15 @@ void LanguagesSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
{"moveUp", IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_MOVE_UP},
};
AddLocalizedStringsBulk(html_source, kLocalizedStrings);
- AddSmartInputsStrings(html_source);
+ AddSmartInputsStrings(html_source, IsEmojiSuggestionAllowed());
+ AddInputMethodOptionsStrings(html_source);
html_source->AddString(
"languagesLearnMoreURL",
base::ASCIIToUTF16(chrome::kLanguageSettingsLearnMoreUrl));
+ html_source->AddBoolean("imeOptionsInSettings",
+ base::FeatureList::IsEnabled(
+ ::chromeos::features::kImeOptionsInSettings));
}
void LanguagesSection::AddHandlers(content::WebUI* web_ui) {
@@ -161,5 +245,71 @@ void LanguagesSection::AddHandlers(content::WebUI* web_ui) {
std::make_unique<::settings::LanguagesHandler>(profile()));
}
+int LanguagesSection::GetSectionNameMessageId() const {
+ return IDS_OS_SETTINGS_LANGUAGES_AND_INPUT_PAGE_TITLE;
+}
+
+mojom::Section LanguagesSection::GetSection() const {
+ return mojom::Section::kLanguagesAndInput;
+}
+
+mojom::SearchResultIcon LanguagesSection::GetSectionIcon() const {
+ return mojom::SearchResultIcon::kGlobe;
+}
+
+std::string LanguagesSection::GetSectionPath() const {
+ return mojom::kLanguagesAndInputSectionPath;
+}
+
+bool LanguagesSection::IsEmojiSuggestionAllowed() const {
+ return base::FeatureList::IsEnabled(
+ ::chromeos::features::kEmojiSuggestAddition) &&
+ profile()->GetPrefs()->GetBoolean(
+ ::chromeos::prefs::kEmojiSuggestionEnterpriseAllowed);
+}
+
+void LanguagesSection::RegisterHierarchy(HierarchyGenerator* generator) const {
+ // Languages and input details.
+ generator->RegisterTopLevelSubpage(
+ IDS_OS_SETTINGS_LANGUAGES_AND_INPUT_PAGE_TITLE,
+ mojom::Subpage::kLanguagesAndInputDetails,
+ mojom::SearchResultIcon::kGlobe, mojom::SearchResultDefaultRank::kMedium,
+ mojom::kLanguagesAndInputDetailsSubpagePath);
+ static constexpr mojom::Setting kLanguagesAndInputDetailsSettings[] = {
+ mojom::Setting::kAddLanguage,
+ mojom::Setting::kShowInputOptionsInShelf,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kLanguagesAndInputDetails,
+ kLanguagesAndInputDetailsSettings, generator);
+
+ // Manage input methods.
+ generator->RegisterNestedSubpage(
+ IDS_SETTINGS_LANGUAGES_MANAGE_INPUT_METHODS_TITLE,
+ mojom::Subpage::kManageInputMethods,
+ mojom::Subpage::kLanguagesAndInputDetails,
+ mojom::SearchResultIcon::kGlobe, mojom::SearchResultDefaultRank::kMedium,
+ mojom::kManageInputMethodsSubpagePath);
+
+ // Input method options.
+ generator->RegisterNestedSubpage(
+ IDS_SETTINGS_LANGUAGES_INPUT_METHOD_OPTIONS_TITLE,
+ mojom::Subpage::kInputMethodOptions,
+ mojom::Subpage::kLanguagesAndInputDetails,
+ mojom::SearchResultIcon::kGlobe, mojom::SearchResultDefaultRank::kMedium,
+ mojom::kInputMethodOptionsSubpagePath);
+
+ // Smart inputs.
+ generator->RegisterTopLevelSubpage(
+ IDS_SETTINGS_SMART_INPUTS_TITLE, mojom::Subpage::kSmartInputs,
+ mojom::SearchResultIcon::kGlobe, mojom::SearchResultDefaultRank::kMedium,
+ mojom::kSmartInputsSubpagePath);
+ static constexpr mojom::Setting kSmartInputsFeaturesSettings[] = {
+ mojom::Setting::kShowPersonalInformationSuggestions,
+ mojom::Setting::kShowEmojiSuggestions,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kSmartInputs,
+ kSmartInputsFeaturesSettings, generator);
+}
+
} // namespace settings
} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/languages_section.h b/chromium/chrome/browser/ui/webui/settings/chromeos/languages_section.h
index d8a742babc2..9236455754d 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/languages_section.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/languages_section.h
@@ -28,6 +28,13 @@ class LanguagesSection : public OsSettingsSection {
// OsSettingsSection:
void AddLoadTimeData(content::WebUIDataSource* html_source) override;
void AddHandlers(content::WebUI* web_ui) override;
+ int GetSectionNameMessageId() const override;
+ mojom::Section GetSection() const override;
+ mojom::SearchResultIcon GetSectionIcon() const override;
+ std::string GetSectionPath() const override;
+ void RegisterHierarchy(HierarchyGenerator* generator) const override;
+
+ bool IsEmojiSuggestionAllowed() const;
};
} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/main_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/main_section.cc
index 9afd5882393..0868f9c866a 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/main_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/main_section.cc
@@ -39,8 +39,6 @@ void AddSearchInSettingsStrings(content::WebUIDataSource* html_source) {
{"searchNoResults", IDS_SEARCH_NO_RESULTS},
{"searchResults", IDS_SEARCH_RESULTS},
{"searchResultSelected", IDS_OS_SEARCH_RESULT_ROW_A11Y_RESULT_SELECTED},
- {"searchResultsOne", IDS_OS_SEARCH_BOX_A11Y_ONE_RESULT},
- {"searchResultsNumber", IDS_OS_SEARCH_BOX_A11Y_RESULT_COUNT},
// 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},
@@ -98,6 +96,10 @@ void MainSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
{"settings", IDS_SETTINGS_SETTINGS},
{"settingsAltPageTitle", IDS_SETTINGS_ALT_PAGE_TITLE},
{"subpageArrowRoleDescription", IDS_SETTINGS_SUBPAGE_BUTTON},
+ {"subpageBackButtonAriaLabel",
+ IDS_SETTINGS_SUBPAGE_BACK_BUTTON_ARIA_LABEL},
+ {"subpageBackButtonAriaRoleDescription",
+ IDS_SETTINGS_SUBPAGE_BACK_BUTTON_ARIA_ROLE_DESCRIPTION},
{"notValidWebAddress", IDS_SETTINGS_NOT_VALID_WEB_ADDRESS},
{"notValidWebAddressForContentType",
IDS_SETTINGS_NOT_VALID_WEB_ADDRESS_FOR_CONTENT_TYPE},
@@ -143,11 +145,6 @@ void MainSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
html_source->AddResourcePath("search/search.mojom-lite.js",
IDR_OS_SETTINGS_SEARCH_MOJOM_LITE_JS);
- html_source->AddString("browserSettingsBannerText",
- l10n_util::GetStringFUTF16(
- IDS_SETTINGS_BROWSER_SETTINGS_BANNER,
- base::ASCIIToUTF16(chrome::kChromeUISettingsURL)));
-
AddSearchInSettingsStrings(html_source);
AddChromeOSUserStrings(html_source);
@@ -162,6 +159,32 @@ void MainSection::AddHandlers(content::WebUI* web_ui) {
std::make_unique<::settings::BrowserLifetimeHandler>());
}
+int MainSection::GetSectionNameMessageId() const {
+ NOTIMPLEMENTED();
+ return 0;
+}
+
+mojom::Section MainSection::GetSection() const {
+ NOTIMPLEMENTED();
+ return mojom::Section::kMinValue;
+}
+
+mojom::SearchResultIcon MainSection::GetSectionIcon() const {
+ NOTIMPLEMENTED();
+ return mojom::SearchResultIcon::kMinValue;
+}
+
+std::string MainSection::GetSectionPath() const {
+ NOTIMPLEMENTED();
+ return std::string();
+}
+
+void MainSection::RegisterHierarchy(HierarchyGenerator* generator) const {
+ // MainSection is a container for common resources/functionality shared
+ // between sections and does not have its own subpages/settings.
+ NOTIMPLEMENTED();
+}
+
void MainSection::AddChromeOSUserStrings(
content::WebUIDataSource* html_source) {
const user_manager::User* user =
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/main_section.h b/chromium/chrome/browser/ui/webui/settings/chromeos/main_section.h
index 7f8d9de7d5c..fab6b9bfdc3 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/main_section.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/main_section.h
@@ -26,6 +26,11 @@ class MainSection : public OsSettingsSection {
// OsSettingsSection:
void AddLoadTimeData(content::WebUIDataSource* html_source) override;
void AddHandlers(content::WebUI* web_ui) override;
+ int GetSectionNameMessageId() const override;
+ mojom::Section GetSection() const override;
+ mojom::SearchResultIcon GetSectionIcon() const override;
+ std::string GetSectionPath() const override;
+ void RegisterHierarchy(HierarchyGenerator* generator) const override;
void AddChromeOSUserStrings(content::WebUIDataSource* html_source);
};
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_section.cc
index 7ce85eaf234..da38e8b2896 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_section.cc
@@ -4,19 +4,25 @@
#include "chrome/browser/ui/webui/settings/chromeos/multidevice_section.h"
+#include "base/feature_list.h"
#include "base/no_destructor.h"
#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/browser_features.h"
#include "chrome/browser/chromeos/android_sms/android_sms_service.h"
+#include "chrome/browser/nearby_sharing/nearby_sharing_prefs.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h"
#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h"
+#include "chrome/browser/ui/webui/settings/shared_settings_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/generated_resources.h"
+#include "chromeos/constants/chromeos_features.h"
#include "chromeos/services/multidevice_setup/public/cpp/prefs.h"
#include "chromeos/services/multidevice_setup/public/cpp/url_provider.h"
#include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h"
+#include "components/prefs/pref_service.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_data_source.h"
#include "ui/base/l10n/l10n_util.h"
@@ -27,8 +33,22 @@ namespace chromeos {
namespace settings {
namespace {
-const std::vector<SearchConcept>& GetMultiDeviceSearchConcepts() {
+const std::vector<SearchConcept>& GetMultiDeviceOptedInSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
+ {IDS_OS_SETTINGS_TAG_MULTIDEVICE_SMART_LOCK_OPTIONS,
+ mojom::kSmartLockSubpagePath,
+ mojom::SearchResultIcon::kLock,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSubpage,
+ {.subpage = mojom::Subpage::kSmartLock}},
+ {IDS_OS_SETTINGS_TAG_MULTIDEVICE_FORGET,
+ mojom::kMultiDeviceFeaturesSubpagePath,
+ mojom::SearchResultIcon::kPhone,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kForgetPhone},
+ {IDS_OS_SETTINGS_TAG_MULTIDEVICE_FORGET_ALT1,
+ SearchConcept::kAltTagEnd}},
{IDS_OS_SETTINGS_TAG_MULTIDEVICE_MESSAGES,
mojom::kMultiDeviceFeaturesSubpagePath,
mojom::SearchResultIcon::kMessages,
@@ -40,54 +60,78 @@ const std::vector<SearchConcept>& GetMultiDeviceSearchConcepts() {
{IDS_OS_SETTINGS_TAG_MULTIDEVICE,
mojom::kMultiDeviceFeaturesSubpagePath,
mojom::SearchResultIcon::kPhone,
- mojom::SearchResultDefaultRank::kHigh,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
{.subpage = mojom::Subpage::kMultiDeviceFeatures},
- {IDS_OS_SETTINGS_TAG_MULTIDEVICE_ALT1,
- IDS_OS_SETTINGS_TAG_MULTIDEVICE_ALT2,
- IDS_OS_SETTINGS_TAG_MULTIDEVICE_ALT3, SearchConcept::kAltTagEnd}},
+ {IDS_OS_SETTINGS_TAG_MULTIDEVICE_ALT1, SearchConcept::kAltTagEnd}},
{IDS_OS_SETTINGS_TAG_MULTIDEVICE_SMART_LOCK,
mojom::kMultiDeviceFeaturesSubpagePath,
mojom::SearchResultIcon::kLock,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
- {.subpage = mojom::Subpage::kSmartLock},
- {IDS_OS_SETTINGS_TAG_MULTIDEVICE_SMART_LOCK_ALT1,
- SearchConcept::kAltTagEnd}},
+ {.subpage = mojom::Subpage::kSmartLock}},
});
return *tags;
}
-const std::vector<SearchConcept>& GetMultiDeviceOptedInSearchConcepts() {
+const std::vector<SearchConcept>& GetMultiDeviceOptedOutSearchConcepts() {
+ static const base::NoDestructor<std::vector<SearchConcept>> tags([] {
+ // Special-case: The "set up" search tag also includes the names of the
+ // multi-device features as a way to increase discoverability of these
+ // features.
+ SearchConcept set_up_concept{
+ IDS_OS_SETTINGS_TAG_MULTIDEVICE_SET_UP,
+ mojom::kMultiDeviceSectionPath,
+ mojom::SearchResultIcon::kPhone,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kSetUpMultiDevice},
+ {IDS_OS_SETTINGS_TAG_MULTIDEVICE,
+ IDS_OS_SETTINGS_TAG_MULTIDEVICE_MESSAGES,
+ IDS_OS_SETTINGS_TAG_MULTIDEVICE_SMART_LOCK, SearchConcept::kAltTagEnd},
+ };
+
+ // If Instant Tethering is available, also include that in the list.
+ if (base::FeatureList::IsEnabled(features::kInstantTethering)) {
+ set_up_concept.alt_tag_ids[3] = IDS_OS_SETTINGS_TAG_INSTANT_TETHERING;
+ set_up_concept.alt_tag_ids[4] = SearchConcept::kAltTagEnd;
+ }
+
+ return std::vector<SearchConcept>{set_up_concept};
+ }());
+ return *tags;
+}
+
+const std::vector<SearchConcept>& GetNearbyShareOnSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
- {IDS_OS_SETTINGS_TAG_MULTIDEVICE_SMART_LOCK_OPTIONS,
- mojom::kSmartLockSubpagePath,
- mojom::SearchResultIcon::kLock,
+ {IDS_OS_SETTINGS_TAG_MULTIDEVICE_NEARBY_SHARE,
+ mojom::kNearbyShareSubpagePath,
+ mojom::SearchResultIcon::kNearbyShare,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
- {.subpage = mojom::Subpage::kSmartLock},
- {IDS_OS_SETTINGS_TAG_MULTIDEVICE_SMART_LOCK_OPTIONS_ALT1,
- SearchConcept::kAltTagEnd}},
- {IDS_OS_SETTINGS_TAG_MULTIDEVICE_FORGET,
- mojom::kMultiDeviceFeaturesSubpagePath,
- mojom::SearchResultIcon::kPhone,
+ {.subpage = mojom::Subpage::kNearbyShare}},
+ {IDS_OS_SETTINGS_TAG_NEARBY_SHARE_TURN_OFF,
+ mojom::kNearbyShareSubpagePath,
+ mojom::SearchResultIcon::kNearbyShare,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
- {.setting = mojom::Setting::kForgetPhone},
- {IDS_OS_SETTINGS_TAG_MULTIDEVICE_FORGET_ALT1,
+ {.setting = mojom::Setting::kNearbyShareOnOff},
+ {IDS_OS_SETTINGS_TAG_NEARBY_SHARE_TURN_OFF_ALT1,
SearchConcept::kAltTagEnd}},
});
return *tags;
}
-const std::vector<SearchConcept>& GetMultiDeviceOptedOutSearchConcepts() {
+const std::vector<SearchConcept>& GetNearbyShareOffSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
- {IDS_OS_SETTINGS_TAG_MULTIDEVICE_SET_UP,
+ {IDS_OS_SETTINGS_TAG_NEARBY_SHARE_TURN_ON,
mojom::kMultiDeviceSectionPath,
- mojom::SearchResultIcon::kPhone,
+ mojom::SearchResultIcon::kNearbyShare,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
- {.setting = mojom::Setting::kSetUpMultiDevice}},
+ {.setting = mojom::Setting::kNearbyShareOnOff},
+ {IDS_OS_SETTINGS_TAG_NEARBY_SHARE_TURN_ON_ALT1,
+ SearchConcept::kAltTagEnd}},
});
return *tags;
}
@@ -121,13 +165,21 @@ MultiDeviceSection::MultiDeviceSection(
multidevice_setup_client_(multidevice_setup_client),
android_sms_service_(android_sms_service),
pref_service_(pref_service) {
+ if (base::FeatureList::IsEnabled(::features::kNearbySharing)) {
+ pref_change_registrar_.Init(pref_service_);
+ pref_change_registrar_.Add(
+ ::prefs::kNearbySharingEnabledPrefName,
+ base::BindRepeating(&MultiDeviceSection::OnNearbySharingEnabledChanged,
+ base::Unretained(this)));
+ OnNearbySharingEnabledChanged();
+ }
+
// Note: |multidevice_setup_client_| is null when multi-device features are
// prohibited by policy.
if (!multidevice_setup_client_)
return;
multidevice_setup_client_->AddObserver(this);
- registry()->AddSearchTags(GetMultiDeviceSearchConcepts());
OnHostStatusChanged(multidevice_setup_client_->GetHostStatus());
}
@@ -214,6 +266,7 @@ void MultiDeviceSection::AddLoadTimeData(
GetHelpUrlWithBoard(chrome::kEasyUnlockLearnMoreUrl)));
AddEasyUnlockStrings(html_source);
+ ::settings::AddNearbyShareData(html_source);
}
void MultiDeviceSection::AddHandlers(content::WebUI* web_ui) {
@@ -231,15 +284,96 @@ void MultiDeviceSection::AddHandlers(content::WebUI* web_ui) {
: nullptr));
}
+int MultiDeviceSection::GetSectionNameMessageId() const {
+ return IDS_SETTINGS_MULTIDEVICE;
+}
+
+mojom::Section MultiDeviceSection::GetSection() const {
+ return mojom::Section::kMultiDevice;
+}
+
+mojom::SearchResultIcon MultiDeviceSection::GetSectionIcon() const {
+ return mojom::SearchResultIcon::kPhone;
+}
+
+std::string MultiDeviceSection::GetSectionPath() const {
+ return mojom::kMultiDeviceSectionPath;
+}
+
+void MultiDeviceSection::RegisterHierarchy(
+ HierarchyGenerator* generator) const {
+ generator->RegisterTopLevelSetting(mojom::Setting::kSetUpMultiDevice);
+ generator->RegisterTopLevelSetting(mojom::Setting::kVerifyMultiDeviceSetup);
+
+ // MultiDevice features.
+ generator->RegisterTopLevelSubpage(
+ IDS_SETTINGS_MULTIDEVICE, mojom::Subpage::kMultiDeviceFeatures,
+ mojom::SearchResultIcon::kPhone, mojom::SearchResultDefaultRank::kMedium,
+ mojom::kMultiDeviceFeaturesSubpagePath);
+ static constexpr mojom::Setting kMultiDeviceFeaturesSettings[] = {
+ mojom::Setting::kMultiDeviceOnOff,
+ mojom::Setting::kMessagesSetUp,
+ mojom::Setting::kMessagesOnOff,
+ mojom::Setting::kForgetPhone,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kMultiDeviceFeatures,
+ kMultiDeviceFeaturesSettings, generator);
+ generator->RegisterTopLevelAltSetting(mojom::Setting::kMultiDeviceOnOff);
+ // Note: Instant Tethering is part of the Network section, but it has an
+ // alternate setting within the MultiDevice section.
+ generator->RegisterNestedAltSetting(mojom::Setting::kInstantTetheringOnOff,
+ mojom::Subpage::kMultiDeviceFeatures);
+
+ // Smart Lock.
+ generator->RegisterNestedSubpage(
+ IDS_SETTINGS_EASY_UNLOCK_SECTION_TITLE, mojom::Subpage::kSmartLock,
+ mojom::Subpage::kMultiDeviceFeatures, mojom::SearchResultIcon::kLock,
+ mojom::SearchResultDefaultRank::kMedium, mojom::kSmartLockSubpagePath);
+ static constexpr mojom::Setting kSmartLockSettings[] = {
+ mojom::Setting::kSmartLockOnOff,
+ mojom::Setting::kSmartLockUnlockOrSignIn,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kSmartLock, kSmartLockSettings,
+ generator);
+ generator->RegisterNestedAltSetting(mojom::Setting::kSmartLockOnOff,
+ mojom::Subpage::kMultiDeviceFeatures);
+
+ // Nearby Share, registered regardless of the flag.
+ generator->RegisterTopLevelSubpage(
+ IDS_SETTINGS_NEARBY_SHARE_TITLE, mojom::Subpage::kNearbyShare,
+ mojom::SearchResultIcon::kNearbyShare,
+ mojom::SearchResultDefaultRank::kMedium, mojom::kNearbyShareSubpagePath);
+ static constexpr mojom::Setting kNearbyShareSettings[] = {
+ mojom::Setting::kNearbyShareOnOff,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kNearbyShare, kNearbyShareSettings,
+ generator);
+ generator->RegisterTopLevelAltSetting(mojom::Setting::kNearbyShareOnOff);
+}
+
void MultiDeviceSection::OnHostStatusChanged(
const multidevice_setup::MultiDeviceSetupClient::HostStatusWithDevice&
host_status_with_device) {
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+
if (IsOptedIn(host_status_with_device.first)) {
- registry()->RemoveSearchTags(GetMultiDeviceOptedOutSearchConcepts());
- registry()->AddSearchTags(GetMultiDeviceOptedInSearchConcepts());
+ updater.RemoveSearchTags(GetMultiDeviceOptedOutSearchConcepts());
+ updater.AddSearchTags(GetMultiDeviceOptedInSearchConcepts());
+ } else {
+ updater.RemoveSearchTags(GetMultiDeviceOptedInSearchConcepts());
+ updater.AddSearchTags(GetMultiDeviceOptedOutSearchConcepts());
+ }
+}
+
+void MultiDeviceSection::OnNearbySharingEnabledChanged() {
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+
+ if (pref_service_->GetBoolean(::prefs::kNearbySharingEnabledPrefName)) {
+ updater.RemoveSearchTags(GetNearbyShareOffSearchConcepts());
+ updater.AddSearchTags(GetNearbyShareOnSearchConcepts());
} else {
- registry()->RemoveSearchTags(GetMultiDeviceOptedInSearchConcepts());
- registry()->AddSearchTags(GetMultiDeviceOptedOutSearchConcepts());
+ updater.RemoveSearchTags(GetNearbyShareOnSearchConcepts());
+ updater.AddSearchTags(GetNearbyShareOffSearchConcepts());
}
}
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_section.h b/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_section.h
index d35711a2c9d..2c608c9e03c 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_section.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_section.h
@@ -7,6 +7,7 @@
#include "chrome/browser/ui/webui/settings/chromeos/os_settings_section.h"
#include "chromeos/services/multidevice_setup/public/cpp/multidevice_setup_client.h"
+#include "components/prefs/pref_change_registrar.h"
class PrefService;
@@ -43,15 +44,24 @@ class MultiDeviceSection
// OsSettingsSection:
void AddLoadTimeData(content::WebUIDataSource* html_source) override;
void AddHandlers(content::WebUI* web_ui) override;
+ int GetSectionNameMessageId() const override;
+ mojom::Section GetSection() const override;
+ mojom::SearchResultIcon GetSectionIcon() const override;
+ std::string GetSectionPath() const override;
+ void RegisterHierarchy(HierarchyGenerator* generator) const override;
// multidevice_setup::MultiDeviceSetupClient::Observer:
void OnHostStatusChanged(
const multidevice_setup::MultiDeviceSetupClient::HostStatusWithDevice&
host_status_with_device) override;
+ // Nearby Share enabled pref change observer.
+ void OnNearbySharingEnabledChanged();
+
multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client_;
android_sms::AndroidSmsService* android_sms_service_;
PrefService* pref_service_;
+ PrefChangeRegistrar pref_change_registrar_;
};
} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_identifier.h b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_identifier.h
new file mode 100644
index 00000000000..df287c3a928
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_identifier.h
@@ -0,0 +1,24 @@
+// 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_IDENTIFIER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_OS_SETTINGS_IDENTIFIER_H_
+
+#include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h"
+#include "chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom.h"
+
+namespace chromeos {
+namespace settings {
+
+// Uniquely identifies a settings item (section, subpage, or setting).
+union OsSettingsIdentifier {
+ mojom::Section section;
+ mojom::Subpage subpage;
+ mojom::Setting setting;
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_OS_SETTINGS_IDENTIFIER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.cc
index ce568062640..95cd5692e5c 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.cc
@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/feature_list.h"
#include "chrome/browser/chromeos/local_search_service/local_search_service.h"
+#include "chrome/browser/ui/webui/settings/chromeos/hierarchy.h"
#include "chrome/browser/ui/webui/settings/chromeos/os_settings_sections.h"
#include "chrome/browser/ui/webui/settings/chromeos/search/search_handler.h"
#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h"
@@ -40,10 +41,12 @@ OsSettingsManager::OsSettingsManager(
arc_app_list_prefs,
identity_manager,
android_sms_service,
- printers_manager)) {
+ printers_manager)),
+ hierarchy_(std::make_unique<Hierarchy>(sections_.get())) {
if (base::FeatureList::IsEnabled(features::kNewOsSettingsSearch)) {
search_handler_ = std::make_unique<SearchHandler>(
- search_tag_registry_.get(), local_search_service);
+ search_tag_registry_.get(), sections_.get(), hierarchy_.get(),
+ local_search_service);
}
}
@@ -64,6 +67,7 @@ void OsSettingsManager::Shutdown() {
// Note: These must be deleted in the opposite order of their creation to
// prevent against UAF violations.
search_handler_.reset();
+ hierarchy_.reset();
sections_.reset();
search_tag_registry_.reset();
}
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.h b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.h
index b60dbcbd181..78a9008a482 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.h
@@ -46,6 +46,7 @@ class MultiDeviceSetupClient;
namespace settings {
+class Hierarchy;
class OsSettingsSections;
class SearchHandler;
class SearchTagRegistry;
@@ -104,14 +105,17 @@ class OsSettingsManager : public KeyedService {
// Note: Returns null when the kNewOsSettingsSearch flag is disabled.
SearchHandler* search_handler() { return search_handler_.get(); }
+ const Hierarchy* hierarchy() const { return hierarchy_.get(); }
+
private:
- FRIEND_TEST_ALL_PREFIXES(OsSettingsManagerTest, Sections);
+ FRIEND_TEST_ALL_PREFIXES(OsSettingsManagerTest, Initialization);
// KeyedService:
void Shutdown() override;
std::unique_ptr<SearchTagRegistry> search_tag_registry_;
std::unique_ptr<OsSettingsSections> sections_;
+ std::unique_ptr<Hierarchy> hierarchy_;
std::unique_ptr<SearchHandler> search_handler_;
};
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_factory.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_factory.cc
index a238deaf5fb..71e5abc2b2f 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_factory.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_factory.cc
@@ -9,6 +9,7 @@
#include "chrome/browser/chromeos/local_search_service/local_search_service_factory.h"
#include "chrome/browser/chromeos/multidevice_setup/multidevice_setup_client_factory.h"
#include "chrome/browser/chromeos/printing/cups_printers_manager_factory.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/profiles/incognito_helpers.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/identity_manager_factory.h"
@@ -53,13 +54,23 @@ OsSettingsManagerFactory::~OsSettingsManagerFactory() = default;
KeyedService* OsSettingsManagerFactory::BuildServiceInstanceFor(
content::BrowserContext* context) const {
Profile* profile = Profile::FromBrowserContext(context);
+
+ // Edge case: KerberosCredentialsManagerFactory::Get(profile) returns the
+ // instance associated with the primary profile, even if |profile| is not the
+ // primary profile, which can cause issues in multi-profile environments.
+ // Only call Get() if the profile is primary; see https://crbug.com/1103140.
+ KerberosCredentialsManager* kerberos_credentials_manager =
+ ProfileHelper::IsPrimaryProfile(profile)
+ ? KerberosCredentialsManagerFactory::Get(profile)
+ : nullptr;
+
return new OsSettingsManager(
profile,
local_search_service::LocalSearchServiceFactory::GetForProfile(profile),
multidevice_setup::MultiDeviceSetupClientFactory::GetForProfile(profile),
ProfileSyncServiceFactory::GetForProfile(profile),
SupervisedUserServiceFactory::GetForProfile(profile),
- KerberosCredentialsManagerFactory::Get(profile),
+ kerberos_credentials_manager,
ArcAppListPrefsFactory::GetForBrowserContext(profile),
IdentityManagerFactory::GetForProfile(profile),
android_sms::AndroidSmsServiceFactory::GetForBrowserContext(profile),
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_unittest.cc
index ec50ed54481..dd20db6da77 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_unittest.cc
@@ -4,9 +4,12 @@
#include "chrome/browser/ui/webui/settings/chromeos/os_settings_manager.h"
+#include "base/metrics/histogram_base.h"
#include "base/no_destructor.h"
+#include "base/test/metrics/histogram_enum_reader.h"
#include "chrome/browser/ui/webui/settings/chromeos/constants/constants_util.h"
#include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h"
+#include "chrome/browser/ui/webui/settings/chromeos/hierarchy.h"
#include "chrome/browser/ui/webui/settings/chromeos/os_settings_manager_factory.h"
#include "chrome/browser/ui/webui/settings/chromeos/os_settings_sections.h"
#include "chrome/test/base/testing_browser_process.h"
@@ -40,12 +43,55 @@ class OsSettingsManagerTest : public testing::Test {
OsSettingsManager* manager_;
};
-TEST_F(OsSettingsManagerTest, Sections) {
- // For each mojom::Section value, there should be an associated
- // OsSettingsSection class registered.
+TEST_F(OsSettingsManagerTest, Initialization) {
+ base::Optional<base::HistogramEnumEntryMap> sections_enum_entry_map =
+ base::ReadEnumFromEnumsXml("OsSettingsSection");
+ ASSERT_TRUE(sections_enum_entry_map);
for (const auto& section : constants::AllSections()) {
+ // For each mojom::Section value, there should be an associated
+ // OsSettingsSection class registered.
EXPECT_TRUE(manager_->sections_->GetSection(section))
<< "No OsSettingsSection instance created for " << section << ".";
+
+ // Each mojom::Section should be registered in the hierarchy.
+ const Hierarchy::SectionMetadata& metadata =
+ manager_->hierarchy_->GetSectionMetadata(section);
+
+ // Only the "About Chrome OS" section contains only a link to a subpage.
+ EXPECT_EQ(metadata.only_contains_link_to_subpage,
+ section == mojom::Section::kAboutChromeOs);
+
+ EXPECT_TRUE(
+ base::Contains(*sections_enum_entry_map, static_cast<int32_t>(section)))
+ << "Missing OsSettingsSection enums.xml entry for " << section;
+ }
+
+ base::Optional<base::HistogramEnumEntryMap> subpages_enum_entry_map =
+ base::ReadEnumFromEnumsXml("OsSettingsSubpage");
+ ASSERT_TRUE(subpages_enum_entry_map);
+ for (const auto& subpage : constants::AllSubpages()) {
+ // Each mojom::Subpage should be registered in the hierarchy. Note that
+ // GetSubpageMetadata() internally CHECK()s that the metadata exists before
+ // returning it.
+ manager_->hierarchy_->GetSubpageMetadata(subpage);
+
+ EXPECT_TRUE(
+ base::Contains(*subpages_enum_entry_map, static_cast<int32_t>(subpage)))
+ << "Missing OsSettingsSubpage enums.xml entry for " << subpage;
+ }
+
+ base::Optional<base::HistogramEnumEntryMap> settings_enum_entry_map =
+ base::ReadEnumFromEnumsXml("OsSetting");
+ ASSERT_TRUE(settings_enum_entry_map);
+ for (const auto& setting : constants::AllSettings()) {
+ // Each mojom::Setting should be registered in the hierarchy. Note that
+ // GetSettingMetadata() internally CHECK()s that the metadata exists before
+ // returning it.
+ manager_->hierarchy_->GetSettingMetadata(setting);
+
+ EXPECT_TRUE(
+ base::Contains(*settings_enum_entry_map, static_cast<int32_t>(setting)))
+ << "Missing OsSetting enums.xml entry for " << setting;
}
}
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_section.cc
index af60b362b5f..02bdc340841 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_section.cc
@@ -7,6 +7,8 @@
#include "base/check.h"
#include "base/strings/utf_string_conversions.h"
#include "base/system/sys_info.h"
+#include "chrome/grit/generated_resources.h"
+#include "ui/base/l10n/l10n_util.h"
namespace chromeos {
namespace settings {
@@ -18,6 +20,15 @@ base::string16 OsSettingsSection::GetHelpUrlWithBoard(
"&b=" + base::SysInfo::GetLsbReleaseBoard());
}
+// static
+void OsSettingsSection::RegisterNestedSettingBulk(
+ mojom::Subpage subpage,
+ const base::span<const mojom::Setting>& settings,
+ HierarchyGenerator* generator) {
+ for (const auto& setting : settings)
+ generator->RegisterNestedSetting(setting, subpage);
+}
+
OsSettingsSection::~OsSettingsSection() = default;
OsSettingsSection::OsSettingsSection(Profile* profile,
@@ -27,5 +38,33 @@ OsSettingsSection::OsSettingsSection(Profile* profile,
DCHECK(search_tag_registry);
}
+OsSettingsSection::OsSettingsSection() = default;
+
+std::string OsSettingsSection::ModifySearchResultUrl(
+ mojom::SearchResultType type,
+ OsSettingsIdentifier id,
+ const std::string& url_to_modify) const {
+ // Default case for static URLs which do not need to be modified.
+ return url_to_modify;
+}
+
+mojom::SearchResultPtr OsSettingsSection::GenerateSectionSearchResult(
+ double relevance_score) const {
+ return mojom::SearchResult::New(
+ /*result_text=*/l10n_util::GetStringUTF16(GetSectionNameMessageId()),
+ /*canonical_result_text=*/
+ l10n_util::GetStringUTF16(GetSectionNameMessageId()),
+ ModifySearchResultUrl(mojom::SearchResultType::kSection,
+ {.section = GetSection()}, GetSectionPath()),
+ GetSectionIcon(), relevance_score,
+ std::vector<base::string16>{
+ l10n_util::GetStringUTF16(IDS_INTERNAL_APP_SETTINGS),
+ l10n_util::GetStringUTF16(GetSectionNameMessageId())},
+ mojom::SearchResultDefaultRank::kMedium,
+ /*was_generated_from_text_match=*/false,
+ mojom::SearchResultType::kSection,
+ mojom::SearchResultIdentifier::NewSection(GetSection()));
+}
+
} // namespace settings
} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_section.h b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_section.h
index 3e8b5b23bcd..b4406ff4c3e 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_section.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_section.h
@@ -8,7 +8,11 @@
#include <string>
#include <vector>
+#include "base/containers/span.h"
#include "base/strings/string16.h"
+#include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h"
+#include "chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/search.mojom.h"
#include "chrome/browser/ui/webui/settings/chromeos/search/search_concept.h"
class Profile;
@@ -38,6 +42,57 @@ class SearchTagRegistry;
// (i.e., browser to JS IPC mechanisms) to the page.
class OsSettingsSection {
public:
+ // Used to construct a hierarchy of this section (i.e., which settings and
+ // subpages are part of this section). See RegisterHierarchy() below.
+ //
+ // Note on primary vs. alternate setting locations: Some settings are located
+ // in multiple spots of settings. For example, the Wi-Fi on/off toggle appears
+ // in both the top-level Network section as well as the Wi-Fi subpage. In
+ // cases like this, we consider the "primary" location as the more-targeted
+ // one - in this example, the Wi-Fi subpage is the primary location of the
+ // toggle since it is more specific to Wi-Fi, and the alternate location is
+ // the one embedded in the Network section.
+ class HierarchyGenerator {
+ public:
+ virtual ~HierarchyGenerator() = default;
+
+ // Registers a subpage whose parent is this section.
+ virtual void RegisterTopLevelSubpage(
+ int name_message_id,
+ mojom::Subpage subpage,
+ mojom::SearchResultIcon icon,
+ mojom::SearchResultDefaultRank default_rank,
+ const std::string& url_path_with_parameters) = 0;
+
+ // Registers a subpage whose paernt is another subpage in this section.
+ virtual void RegisterNestedSubpage(
+ int name_message_id,
+ mojom::Subpage subpage,
+ mojom::Subpage parent_subpage,
+ mojom::SearchResultIcon icon,
+ mojom::SearchResultDefaultRank default_rank,
+ const std::string& url_path_with_parameters) = 0;
+
+ // Registers a setting embedded directly in the section (i.e., not within a
+ // subpage). This functions is for primary locations (see above).
+ virtual void RegisterTopLevelSetting(mojom::Setting setting) = 0;
+
+ // Registers a setting embedded within a subpage in this section. This
+ // function is for primary locations (see above).
+ virtual void RegisterNestedSetting(mojom::Setting setting,
+ mojom::Subpage subpage) = 0;
+
+ // Register an alternate location for a setting embedded directly in the
+ // section (i.e., not within a subpage). This function is for alternate
+ // locations (see above).
+ virtual void RegisterTopLevelAltSetting(mojom::Setting setting) = 0;
+
+ // Registers a setting embedded within a subpage in this section. This
+ // function is for alternate locations (see above).
+ virtual void RegisterNestedAltSetting(mojom::Setting setting,
+ mojom::Subpage subpage) = 0;
+ };
+
virtual ~OsSettingsSection();
OsSettingsSection(const OsSettingsSection& other) = delete;
@@ -51,12 +106,51 @@ class OsSettingsSection {
// derived type requires one or more handlers for this section.
virtual void AddHandlers(content::WebUI* web_ui) {}
+ // Provides the message ID for the name of this section.
+ virtual int GetSectionNameMessageId() const = 0;
+
+ // Provides the Section enum for this section.
+ virtual mojom::Section GetSection() const = 0;
+
+ // Provides the icon for this section.
+ virtual mojom::SearchResultIcon GetSectionIcon() const = 0;
+
+ // Provides the path for this section.
+ virtual std::string GetSectionPath() const = 0;
+
+ // Registers the subpages and/or settings which reside in this section.
+ virtual void RegisterHierarchy(HierarchyGenerator* generator) const = 0;
+
+ // Modifies a URL to be used by settings search. Some URLs require dynamic
+ // content (e.g., network detail settings use the GUID of the network as a URL
+ // parameter to route to details for a specific network). By default, this
+ // function simply returns |url_to_modify|, which provides functionality for
+ // static URLs.
+ virtual std::string ModifySearchResultUrl(
+ mojom::SearchResultType type,
+ OsSettingsIdentifier id,
+ const std::string& url_to_modify) const;
+
+ // Generates a search result corresponding to this section. |relevance_score|
+ // must be passed by the client, since this result is being created manually
+ // instead of via query matching.
+ mojom::SearchResultPtr GenerateSectionSearchResult(
+ double relevance_score) const;
+
protected:
static base::string16 GetHelpUrlWithBoard(const std::string& original_url);
+ static void RegisterNestedSettingBulk(
+ mojom::Subpage,
+ const base::span<const mojom::Setting>& settings,
+ HierarchyGenerator* generator);
OsSettingsSection(Profile* profile, SearchTagRegistry* search_tag_registry);
+ // Used by tests.
+ OsSettingsSection();
+
Profile* profile() { return profile_; }
+ const Profile* profile() const { return profile_; }
SearchTagRegistry* registry() { return search_tag_registry_; }
private:
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.cc
index 6239b2466c5..334128e8509 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.cc
@@ -4,6 +4,7 @@
#include "chrome/browser/ui/webui/settings/chromeos/os_settings_sections.h"
+#include "build/branding_buildflags.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/settings/chromeos/about_section.h"
#include "chrome/browser/ui/webui/settings/chromeos/accessibility_section.h"
@@ -125,16 +126,26 @@ OsSettingsSections::OsSettingsSections(
sections_map_[mojom::Section::kReset] = reset_section.get();
sections_.push_back(std::move(reset_section));
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
+ auto about_section = std::make_unique<AboutSection>(
+ profile, search_tag_registry, profile->GetPrefs());
+#else
auto about_section =
std::make_unique<AboutSection>(profile, search_tag_registry);
+#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
sections_map_[mojom::Section::kAboutChromeOs] = about_section.get();
sections_.push_back(std::move(about_section));
}
+OsSettingsSections::OsSettingsSections() = default;
+
OsSettingsSections::~OsSettingsSections() = default;
-OsSettingsSection* OsSettingsSections::GetSection(mojom::Section section) {
- return sections_map_[section];
+const OsSettingsSection* OsSettingsSections::GetSection(
+ mojom::Section section) const {
+ const auto it = sections_map_.find(section);
+ CHECK(it != sections_map_.end());
+ return it->second;
}
} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.h b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.h
index 44ddc68a34d..d1526481464 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.h
@@ -54,15 +54,18 @@ class OsSettingsSections {
CupsPrintersManager* printers_manager);
OsSettingsSections(const OsSettingsSections& other) = delete;
OsSettingsSections& operator=(const OsSettingsSections& other) = delete;
- ~OsSettingsSections();
+ virtual ~OsSettingsSections();
- OsSettingsSection* GetSection(mojom::Section section);
+ const OsSettingsSection* GetSection(mojom::Section section) const;
std::vector<std::unique_ptr<OsSettingsSection>>& sections() {
return sections_;
}
- private:
+ protected:
+ // Used by tests.
+ OsSettingsSections();
+
std::unordered_map<mojom::Section, OsSettingsSection*> sections_map_;
std::vector<std::unique_ptr<OsSettingsSection>> sections_;
};
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 97f2eeab8a9..8bddd59808d 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
@@ -68,6 +68,10 @@ OSSettingsUI::OSSettingsUI(content::WebUI* web_ui)
html_source->AddResourcePath("chromeos/lazy_load.html",
IDR_OS_SETTINGS_LAZY_LOAD_VULCANIZED_HTML);
html_source->SetDefaultResource(IDR_OS_SETTINGS_VULCANIZED_HTML);
+ html_source->AddResourcePath("chromeos/os_settings_v3.html",
+ IDR_OS_SETTINGS_OS_SETTINGS_V3_HTML);
+ html_source->AddResourcePath("chromeos/os_settings.js",
+ IDR_OS_SETTINGS_SETTINGS_ROLLUP_JS);
#else
webui::SetupWebUIDataSource(
html_source,
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/parental_controls_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/parental_controls_handler.cc
index 273e9456b69..fb9df81bbf4 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/parental_controls_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/parental_controls_handler.cc
@@ -14,10 +14,10 @@
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/browser_navigator_params.h"
#include "chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_ui.h"
-#include "chrome/services/app_service/public/cpp/app_registry_cache.h"
-#include "chrome/services/app_service/public/cpp/app_update.h"
-#include "chrome/services/app_service/public/mojom/types.mojom.h"
#include "chromeos/constants/chromeos_features.h"
+#include "components/services/app_service/public/cpp/app_registry_cache.h"
+#include "components/services/app_service/public/cpp/app_update.h"
+#include "components/services/app_service/public/mojom/types.mojom.h"
#include "ui/base/page_transition_types.h"
#include "ui/base/window_open_disposition.h"
#include "ui/display/types/display_constants.h"
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/people_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/people_section.cc
index 45486f9eed4..e5bb33b3244 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/people_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/people_section.cc
@@ -47,6 +47,7 @@
#include "components/user_manager/user_manager.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_data_source.h"
+#include "services/network/public/mojom/content_security_policy.mojom.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/webui/web_ui_util.h"
#include "ui/chromeos/resources/grit/ui_chromeos_resources.h"
@@ -68,7 +69,9 @@ const std::vector<SearchConcept>& GetPeopleSearchConcepts() {
mojom::SearchResultIcon::kLock,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
- {.setting = mojom::Setting::kChangeAuthPin}},
+ {.setting = mojom::Setting::kChangeAuthPin},
+ {IDS_OS_SETTINGS_TAG_LOCK_SCREEN_PIN_OR_PASSWORD_ALT1,
+ SearchConcept::kAltTagEnd}},
{IDS_OS_SETTINGS_TAG_USERNAMES_AND_PHOTOS,
mojom::kManageOtherPeopleSubpagePath,
mojom::SearchResultIcon::kAvatar,
@@ -110,12 +113,6 @@ const std::vector<SearchConcept>& GetPeopleSearchConcepts() {
{.setting = mojom::Setting::kLockScreen},
{IDS_OS_SETTINGS_TAG_LOCK_SCREEN_WHEN_WAKING_ALT1,
SearchConcept::kAltTagEnd}},
- {IDS_OS_SETTINGS_TAG_SYNC,
- mojom::kSyncSubpagePath,
- mojom::SearchResultIcon::kSync,
- mojom::SearchResultDefaultRank::kMedium,
- mojom::SearchResultType::kSubpage,
- {.subpage = mojom::Subpage::kSync}},
{IDS_OS_SETTINGS_TAG_PEOPLE_ACCOUNTS_REMOVE,
mojom::kMyAccountsSubpagePath,
mojom::SearchResultIcon::kAvatar,
@@ -145,27 +142,83 @@ const std::vector<SearchConcept>& GetPeopleSearchConcepts() {
return *tags;
}
-const std::vector<SearchConcept>& GetSyncOnSearchConcepts() {
+const std::vector<SearchConcept>& GetNonSplitSyncSearchConcepts() {
+ static const base::NoDestructor<std::vector<SearchConcept>> tags({
+ {IDS_OS_SETTINGS_TAG_SYNC_AND_GOOGLE_SERVICES,
+ mojom::kSyncDeprecatedSubpagePath,
+ mojom::SearchResultIcon::kSync,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSubpage,
+ {.subpage = mojom::Subpage::kSyncDeprecated}},
+ {IDS_OS_SETTINGS_TAG_SYNC_MANAGEMENT,
+ mojom::kSyncDeprecatedAdvancedSubpagePath,
+ mojom::SearchResultIcon::kSync,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSubpage,
+ {.subpage = mojom::Subpage::kSyncDeprecatedAdvanced}},
+ {IDS_OS_SETTINGS_TAG_SYNC_ENCRYPTION_OPTIONS,
+ mojom::kSyncDeprecatedSubpagePath,
+ mojom::SearchResultIcon::kSync,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kNonSplitSyncEncryptionOptions},
+ {IDS_OS_SETTINGS_TAG_SYNC_ENCRYPTION_OPTIONS_ALT1,
+ SearchConcept::kAltTagEnd}},
+ {IDS_OS_SETTINGS_TAG_AUTOCOMPLETE_SEARCHES_AND_URLS,
+ mojom::kSyncDeprecatedSubpagePath,
+ mojom::SearchResultIcon::kSync,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kAutocompleteSearchesAndUrls}},
+ {IDS_OS_SETTINGS_TAG_MAKE_SEARCHES_AND_BROWSER_BETTER,
+ mojom::kSyncDeprecatedSubpagePath,
+ mojom::SearchResultIcon::kSync,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kMakeSearchesAndBrowsingBetter}},
+ {IDS_OS_SETTINGS_TAG_GOOGLE_DRIVE_SEARCH_SUGGESTIONS,
+ mojom::kSyncDeprecatedSubpagePath,
+ mojom::SearchResultIcon::kSync,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kGoogleDriveSearchSuggestions}},
+ });
+ return *tags;
+}
+
+const std::vector<SearchConcept>& GetSplitSyncSearchConcepts() {
+ static const base::NoDestructor<std::vector<SearchConcept>> tags({
+ {IDS_OS_SETTINGS_TAG_SYNC,
+ mojom::kSyncSubpagePath,
+ mojom::SearchResultIcon::kSync,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSubpage,
+ {.subpage = mojom::Subpage::kSync}},
+ });
+ return *tags;
+}
+
+const std::vector<SearchConcept>& GetSplitSyncOnSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
{IDS_OS_SETTINGS_TAG_SYNC_TURN_OFF,
mojom::kSyncSubpagePath,
mojom::SearchResultIcon::kSync,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
- {.setting = mojom::Setting::kSyncOnOff},
+ {.setting = mojom::Setting::kSplitSyncOnOff},
{IDS_OS_SETTINGS_TAG_SYNC_TURN_OFF_ALT1, SearchConcept::kAltTagEnd}},
});
return *tags;
}
-const std::vector<SearchConcept>& GetSyncOffSearchConcepts() {
+const std::vector<SearchConcept>& GetSplitSyncOffSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
{IDS_OS_SETTINGS_TAG_SYNC_TURN_ON,
mojom::kSyncSubpagePath,
mojom::SearchResultIcon::kSync,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
- {.setting = mojom::Setting::kSyncOnOff},
+ {.setting = mojom::Setting::kSplitSyncOnOff},
{IDS_OS_SETTINGS_TAG_SYNC_TURN_ON_ALT1, SearchConcept::kAltTagEnd}},
});
return *tags;
@@ -176,25 +229,25 @@ const std::vector<SearchConcept>& GetKerberosSearchConcepts() {
{IDS_OS_SETTINGS_TAG_KERBEROS_ADD,
mojom::kKerberosSubpagePath,
mojom::SearchResultIcon::kAvatar,
- mojom::SearchResultDefaultRank::kLow,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kAddKerberosTicket}},
{IDS_OS_SETTINGS_TAG_KERBEROS_REMOVE,
mojom::kKerberosSubpagePath,
mojom::SearchResultIcon::kAvatar,
- mojom::SearchResultDefaultRank::kLow,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kRemoveKerberosTicket}},
{IDS_OS_SETTINGS_TAG_KERBEROS,
mojom::kKerberosSubpagePath,
mojom::SearchResultIcon::kAvatar,
- mojom::SearchResultDefaultRank::kLow,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
{.subpage = mojom::Subpage::kKerberos}},
{IDS_OS_SETTINGS_TAG_KERBEROS_ACTIVE,
mojom::kKerberosSubpagePath,
mojom::SearchResultIcon::kAvatar,
- mojom::SearchResultDefaultRank::kLow,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kSetActiveKerberosTicket}},
});
@@ -204,19 +257,19 @@ const std::vector<SearchConcept>& GetKerberosSearchConcepts() {
const std::vector<SearchConcept>& GetFingerprintSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
{IDS_OS_SETTINGS_TAG_FINGERPRINT_REMOVE,
- mojom::kFingerprintSubpathPath,
+ mojom::kFingerprintSubpagePath,
mojom::SearchResultIcon::kFingerprint,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kRemoveFingerprint}},
{IDS_OS_SETTINGS_TAG_FINGERPRINT_ADD,
- mojom::kFingerprintSubpathPath,
+ mojom::kFingerprintSubpagePath,
mojom::SearchResultIcon::kFingerprint,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kAddFingerprint}},
{IDS_OS_SETTINGS_TAG_FINGERPRINT,
- mojom::kFingerprintSubpathPath,
+ mojom::kFingerprintSubpagePath,
mojom::SearchResultIcon::kFingerprint,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
@@ -243,7 +296,11 @@ void AddAccountManagerPageStrings(content::WebUIDataSource* html_source) {
static constexpr webui::LocalizedString kLocalizedStrings[] = {
{"accountManagerDescription", IDS_SETTINGS_ACCOUNT_MANAGER_DESCRIPTION},
{"accountManagerChildDescription",
- IDS_SETTINGS_ACCOUNT_MANAGER_CHILD_DESCRIPTION_2},
+ IDS_SETTINGS_ACCOUNT_MANAGER_CHILD_DESCRIPTION},
+ {"accountManagerChildFirstMessage",
+ IDS_SETTINGS_ACCOUNT_MANAGER_CHILD_FIRST_MESSAGE},
+ {"accountManagerChildSecondMessage",
+ IDS_SETTINGS_ACCOUNT_MANAGER_CHILD_SECOND_MESSAGE},
{"accountListHeader", IDS_SETTINGS_ACCOUNT_MANAGER_LIST_HEADER},
{"accountManagerPrimaryAccountTooltip",
IDS_SETTINGS_ACCOUNT_MANAGER_PRIMARY_ACCOUNT_TOOLTIP},
@@ -431,7 +488,8 @@ void AddFingerprintStrings(content::WebUIDataSource* html_source,
// 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(
+ html_source->OverrideContentSecurityPolicy(
+ network::mojom::CSPDirectiveName::WorkerSrc,
"worker-src blob: 'self';");
html_source->AddResourcePath("finger_print.json",
IDR_LOGIN_FINGER_PRINT_TABLET_ANIMATION);
@@ -531,8 +589,8 @@ void AddSyncControlsStrings(content::WebUIDataSource* html_source) {
html_source->AddBoolean("splitSettingsSyncEnabled",
chromeos::features::IsSplitSettingsSyncEnabled());
- html_source->AddBoolean("splitSyncConsent",
- chromeos::features::IsSplitSyncConsentEnabled());
+ html_source->AddBoolean("useBrowserSyncConsent",
+ chromeos::features::ShouldUseBrowserSyncConsent());
html_source->AddBoolean(
"syncSetupFriendlySettings",
base::FeatureList::IsEnabled(::features::kSyncSetupFriendlySettings));
@@ -581,6 +639,7 @@ void AddParentalControlStrings(content::WebUIDataSource* html_source,
bool is_child = user_manager::UserManager::Get()->IsLoggedInAsChildUser();
html_source->AddBoolean("isChild", is_child);
+ base::string16 tooltip;
if (is_child) {
std::string custodian = supervised_user_service->GetCustodianName();
std::string second_custodian =
@@ -596,9 +655,10 @@ void AddParentalControlStrings(content::WebUIDataSource* html_source,
IDS_SETTINGS_ACCOUNT_MANAGER_CHILD_MANAGED_BY_TWO_PARENTS_TOOLTIP,
base::UTF8ToUTF16(custodian), base::UTF8ToUTF16(second_custodian));
}
- html_source->AddString("accountManagerPrimaryAccountChildManagedTooltip",
- child_managed_tooltip);
+ tooltip = child_managed_tooltip;
}
+ html_source->AddString("accountManagerPrimaryAccountChildManagedTooltip",
+ tooltip);
}
} // namespace
@@ -621,7 +681,8 @@ PeopleSection::PeopleSection(
if (features::IsGuestModeActive())
return;
- registry()->AddSearchTags(GetPeopleSearchConcepts());
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+ updater.AddSearchTags(GetPeopleSearchConcepts());
if (kerberos_credentials_manager_) {
// Kerberos search tags are added/removed dynamically.
@@ -629,28 +690,34 @@ PeopleSection::PeopleSection(
OnKerberosEnabledStateChanged();
}
- if (sync_service_ && chromeos::features::IsSplitSettingsSyncEnabled()) {
- // Sync search tags are added/removed dynamically.
- sync_service_->AddObserver(this);
- OnStateChanged(sync_service_);
+ if (chromeos::features::IsSplitSettingsSyncEnabled()) {
+ if (sync_service_) {
+ updater.AddSearchTags(GetSplitSyncSearchConcepts());
+
+ // Sync search tags are added/removed dynamically.
+ sync_service_->AddObserver(this);
+ OnStateChanged(sync_service_);
+ }
+ } else {
+ updater.AddSearchTags(GetNonSplitSyncSearchConcepts());
}
// Parental control search tags are added if necessary and do not update
// dynamically during a user session.
if (features::ShouldShowParentalControlSettings(profile))
- registry()->AddSearchTags(GetParentalSearchConcepts());
+ updater.AddSearchTags(GetParentalSearchConcepts());
// Fingerprint search tags are added if necessary and do not update
// dynamically during a user session.
if (AreFingerprintSettingsAllowed())
- registry()->AddSearchTags(GetFingerprintSearchConcepts());
+ updater.AddSearchTags(GetFingerprintSearchConcepts());
}
PeopleSection::~PeopleSection() {
if (kerberos_credentials_manager_)
kerberos_credentials_manager_->RemoveObserver(this);
- if (sync_service_ && chromeos::features::IsSplitSettingsSyncEnabled())
+ if (chromeos::features::IsSplitSettingsSyncEnabled() && sync_service_)
sync_service_->RemoveObserver(this);
}
@@ -678,7 +745,7 @@ void PeopleSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
html_source->AddBoolean("isAccountManagerEnabled",
chromeos::IsAccountManagerAvailable(profile()));
- if (chromeos::features::IsSplitSyncConsentEnabled()) {
+ if (chromeos::features::ShouldUseBrowserSyncConsent()) {
static constexpr webui::LocalizedString kTurnOffStrings[] = {
{"syncDisconnect", IDS_SETTINGS_PEOPLE_SYNC_TURN_OFF},
{"syncDisconnectTitle",
@@ -785,24 +852,144 @@ void PeopleSection::AddHandlers(content::WebUI* web_ui) {
}
}
+int PeopleSection::GetSectionNameMessageId() const {
+ return IDS_OS_SETTINGS_PEOPLE;
+}
+
+mojom::Section PeopleSection::GetSection() const {
+ return mojom::Section::kPeople;
+}
+
+mojom::SearchResultIcon PeopleSection::GetSectionIcon() const {
+ return mojom::SearchResultIcon::kAvatar;
+}
+
+std::string PeopleSection::GetSectionPath() const {
+ return mojom::kPeopleSectionPath;
+}
+
+void PeopleSection::RegisterHierarchy(HierarchyGenerator* generator) const {
+ generator->RegisterTopLevelSetting(mojom::Setting::kSetUpParentalControls);
+
+ // My accounts.
+ generator->RegisterTopLevelSubpage(
+ IDS_SETTINGS_ACCOUNT_MANAGER_PAGE_TITLE, mojom::Subpage::kMyAccounts,
+ mojom::SearchResultIcon::kAvatar, mojom::SearchResultDefaultRank::kMedium,
+ mojom::kMyAccountsSubpagePath);
+ static constexpr mojom::Setting kMyAccountsSettings[] = {
+ mojom::Setting::kAddAccount,
+ mojom::Setting::kRemoveAccount,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kMyAccounts, kMyAccountsSettings,
+ generator);
+
+ // Combined browser/OS sync.
+ generator->RegisterTopLevelSubpage(
+ IDS_SETTINGS_SYNC_SYNC_AND_NON_PERSONALIZED_SERVICES,
+ mojom::Subpage::kSyncDeprecated, mojom::SearchResultIcon::kSync,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::kSyncDeprecatedSubpagePath);
+ static constexpr mojom::Setting kSyncDeprecatedSettings[] = {
+ mojom::Setting::kNonSplitSyncEncryptionOptions,
+ mojom::Setting::kAutocompleteSearchesAndUrls,
+ mojom::Setting::kMakeSearchesAndBrowsingBetter,
+ mojom::Setting::kGoogleDriveSearchSuggestions,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kSyncDeprecated,
+ kSyncDeprecatedSettings, generator);
+ generator->RegisterNestedSubpage(
+ IDS_SETTINGS_SYNC_ADVANCED_PAGE_TITLE,
+ mojom::Subpage::kSyncDeprecatedAdvanced, mojom::Subpage::kSyncDeprecated,
+ mojom::SearchResultIcon::kSync, mojom::SearchResultDefaultRank::kMedium,
+ mojom::kSyncDeprecatedAdvancedSubpagePath);
+
+ // OS sync.
+ generator->RegisterTopLevelSubpage(
+ IDS_OS_SETTINGS_SYNC_PAGE_TITLE, mojom::Subpage::kSync,
+ mojom::SearchResultIcon::kSync, mojom::SearchResultDefaultRank::kMedium,
+ mojom::kSyncSubpagePath);
+ generator->RegisterNestedSetting(mojom::Setting::kSplitSyncOnOff,
+ mojom::Subpage::kSync);
+
+ // Security and sign-in.
+ generator->RegisterTopLevelSubpage(
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_TITLE_LOGIN_LOCK,
+ mojom::Subpage::kSecurityAndSignIn, mojom::SearchResultIcon::kLock,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::kSecurityAndSignInSubpagePath);
+ static constexpr mojom::Setting kSecurityAndSignInSettings[] = {
+ mojom::Setting::kLockScreen,
+ mojom::Setting::kChangeAuthPin,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kSecurityAndSignIn,
+ kSecurityAndSignInSettings, generator);
+
+ // Fingerprint.
+ generator->RegisterNestedSubpage(
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_FINGERPRINT_SUBPAGE_TITLE,
+ mojom::Subpage::kFingerprint, mojom::Subpage::kSecurityAndSignIn,
+ mojom::SearchResultIcon::kFingerprint,
+ mojom::SearchResultDefaultRank::kMedium, mojom::kFingerprintSubpagePath);
+ static constexpr mojom::Setting kFingerprintSettings[] = {
+ mojom::Setting::kAddFingerprint,
+ mojom::Setting::kRemoveFingerprint,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kFingerprint, kFingerprintSettings,
+ generator);
+
+ // Manage other people.
+ generator->RegisterTopLevelSubpage(IDS_SETTINGS_PEOPLE_MANAGE_OTHER_PEOPLE,
+ mojom::Subpage::kManageOtherPeople,
+ mojom::SearchResultIcon::kAvatar,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::kManageOtherPeopleSubpagePath);
+ static constexpr mojom::Setting kManageOtherPeopleSettings[] = {
+ mojom::Setting::kGuestBrowsing,
+ mojom::Setting::kShowUsernamesAndPhotosAtSignIn,
+ mojom::Setting::kRestrictSignIn,
+ mojom::Setting::kAddToUserWhitelist,
+ mojom::Setting::kRemoveFromUserWhitelist,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kManageOtherPeople,
+ kManageOtherPeopleSettings, generator);
+
+ // Kerberos.
+ generator->RegisterTopLevelSubpage(
+ IDS_SETTINGS_KERBEROS_ACCOUNTS_PAGE_TITLE, mojom::Subpage::kKerberos,
+ mojom::SearchResultIcon::kAvatar, mojom::SearchResultDefaultRank::kMedium,
+ mojom::kKerberosSubpagePath);
+ static constexpr mojom::Setting kKerberosSettings[] = {
+ mojom::Setting::kAddKerberosTicket,
+ mojom::Setting::kRemoveKerberosTicket,
+ mojom::Setting::kSetActiveKerberosTicket,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kKerberos, kKerberosSettings,
+ generator);
+}
+
void PeopleSection::OnStateChanged(syncer::SyncService* sync_service) {
DCHECK(chromeos::features::IsSplitSettingsSyncEnabled());
DCHECK_EQ(sync_service, sync_service_);
+
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+
if (sync_service_->IsEngineInitialized() &&
sync_service_->GetUserSettings()->IsOsSyncFeatureEnabled()) {
- registry()->AddSearchTags(GetSyncOnSearchConcepts());
- registry()->RemoveSearchTags(GetSyncOffSearchConcepts());
+ updater.AddSearchTags(GetSplitSyncOnSearchConcepts());
+ updater.RemoveSearchTags(GetSplitSyncOffSearchConcepts());
} else {
- registry()->RemoveSearchTags(GetSyncOnSearchConcepts());
- registry()->AddSearchTags(GetSyncOffSearchConcepts());
+ updater.RemoveSearchTags(GetSplitSyncOnSearchConcepts());
+ updater.AddSearchTags(GetSplitSyncOffSearchConcepts());
}
}
void PeopleSection::OnKerberosEnabledStateChanged() {
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+
if (kerberos_credentials_manager_->IsKerberosEnabled())
- registry()->AddSearchTags(GetKerberosSearchConcepts());
+ updater.AddSearchTags(GetKerberosSearchConcepts());
else
- registry()->RemoveSearchTags(GetKerberosSearchConcepts());
+ updater.RemoveSearchTags(GetKerberosSearchConcepts());
}
void PeopleSection::AddKerberosAccountsPageStrings(
@@ -833,8 +1020,10 @@ void PeopleSection::AddKerberosAccountsPageStrings(
// 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",
- kerberos_credentials_manager_->IsKerberosEnabled());
+ html_source->AddBoolean(
+ "isKerberosEnabled",
+ kerberos_credentials_manager_ != nullptr &&
+ kerberos_credentials_manager_->IsKerberosEnabled());
PrefService* local_state = g_browser_process->local_state();
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/people_section.h b/chromium/chrome/browser/ui/webui/settings/chromeos/people_section.h
index d10c6805d22..51e8a4b3ea8 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/people_section.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/people_section.h
@@ -54,6 +54,11 @@ class PeopleSection : public OsSettingsSection,
// OsSettingsSection:
void AddLoadTimeData(content::WebUIDataSource* html_source) override;
void AddHandlers(content::WebUI* web_ui) override;
+ int GetSectionNameMessageId() const override;
+ mojom::Section GetSection() const override;
+ mojom::SearchResultIcon GetSectionIcon() const override;
+ std::string GetSectionPath() const override;
+ void RegisterHierarchy(HierarchyGenerator* generator) const override;
// syncer::SyncServiceObserver:
void OnStateChanged(syncer::SyncService* sync_service) override;
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/personalization_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/personalization_section.cc
index e7b9d760bc5..dfbbaf17853 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/personalization_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/personalization_section.cc
@@ -48,7 +48,7 @@ const std::vector<SearchConcept>& GetPersonalizationSearchConcepts() {
{IDS_OS_SETTINGS_TAG_CHANGE_DEVICE_ACCOUNT_IMAGE,
mojom::kChangePictureSubpagePath,
mojom::SearchResultIcon::kAvatar,
- mojom::SearchResultDefaultRank::kLow,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
{.subpage = mojom::Subpage::kChangePicture},
{IDS_OS_SETTINGS_TAG_CHANGE_DEVICE_ACCOUNT_IMAGE_ALT1,
@@ -60,6 +60,7 @@ const std::vector<SearchConcept>& GetPersonalizationSearchConcepts() {
return *tags;
}
+// TODO(b/159766700): Add search concepts for |kAmbientModePhotosSubpagePath|.
const std::vector<SearchConcept>& GetAmbientModeSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
{IDS_OS_SETTINGS_TAG_AMBIENT_MODE,
@@ -122,10 +123,11 @@ PersonalizationSection::PersonalizationSection(
if (features::IsGuestModeActive())
return;
- registry()->AddSearchTags(GetPersonalizationSearchConcepts());
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+ updater.AddSearchTags(GetPersonalizationSearchConcepts());
if (IsAmbientModeAllowed()) {
- registry()->AddSearchTags(GetAmbientModeSearchConcepts());
+ updater.AddSearchTags(GetAmbientModeSearchConcepts());
pref_change_registrar_.Init(pref_service_);
pref_change_registrar_.Add(
@@ -197,13 +199,69 @@ void PersonalizationSection::AddHandlers(content::WebUI* web_ui) {
}
}
+int PersonalizationSection::GetSectionNameMessageId() const {
+ return IDS_OS_SETTINGS_PERSONALIZATION;
+}
+
+mojom::Section PersonalizationSection::GetSection() const {
+ return mojom::Section::kPersonalization;
+}
+
+mojom::SearchResultIcon PersonalizationSection::GetSectionIcon() const {
+ return mojom::SearchResultIcon::kPaintbrush;
+}
+
+std::string PersonalizationSection::GetSectionPath() const {
+ return mojom::kPersonalizationSectionPath;
+}
+
+void PersonalizationSection::RegisterHierarchy(
+ HierarchyGenerator* generator) const {
+ generator->RegisterTopLevelSetting(mojom::Setting::kOpenWallpaper);
+
+ // Change picture.
+ generator->RegisterTopLevelSubpage(
+ IDS_OS_SETTINGS_CHANGE_PICTURE_TITLE, mojom::Subpage::kChangePicture,
+ mojom::SearchResultIcon::kAvatar, mojom::SearchResultDefaultRank::kMedium,
+ mojom::kChangePictureSubpagePath);
+ generator->RegisterNestedSetting(mojom::Setting::kChangeDeviceAccountImage,
+ mojom::Subpage::kChangePicture);
+
+ // Ambient mode.
+ generator->RegisterTopLevelSubpage(
+ IDS_OS_SETTINGS_AMBIENT_MODE_TITLE, mojom::Subpage::kAmbientMode,
+ mojom::SearchResultIcon::kWallpaper,
+ mojom::SearchResultDefaultRank::kMedium, mojom::kAmbientModeSubpagePath);
+ static constexpr mojom::Setting kAmbientModeSettings[] = {
+ mojom::Setting::kAmbientModeOnOff,
+ mojom::Setting::kAmbientModeSource,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kAmbientMode, kAmbientModeSettings,
+ generator);
+
+ // Note: The subpage name in the UI is updated dynamically based on the topic
+ // source.
+ // TODO(b/159766700): Create a string for the page title and strings for the
+ // search.
+ generator->RegisterNestedSubpage(
+ IDS_OS_SETTINGS_AMBIENT_MODE_TITLE, mojom::Subpage::kAmbientModePhotos,
+ mojom::Subpage::kAmbientMode, mojom::SearchResultIcon::kWallpaper,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::kAmbientModePhotosSubpagePath);
+ generator->RegisterNestedSetting(
+ mojom::Setting::kAmbientModeUpdatePhotosContainers,
+ mojom::Subpage::kAmbientModePhotos);
+}
+
void PersonalizationSection::OnAmbientModeEnabledStateChanged() {
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+
if (pref_service_->GetBoolean(ash::ambient::prefs::kAmbientModeEnabled)) {
- registry()->AddSearchTags(GetAmbientModeOnSearchConcepts());
- registry()->RemoveSearchTags(GetAmbientModeOffSearchConcepts());
+ updater.AddSearchTags(GetAmbientModeOnSearchConcepts());
+ updater.RemoveSearchTags(GetAmbientModeOffSearchConcepts());
} else {
- registry()->RemoveSearchTags(GetAmbientModeOnSearchConcepts());
- registry()->AddSearchTags(GetAmbientModeOffSearchConcepts());
+ updater.RemoveSearchTags(GetAmbientModeOnSearchConcepts());
+ updater.AddSearchTags(GetAmbientModeOffSearchConcepts());
}
}
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/personalization_section.h b/chromium/chrome/browser/ui/webui/settings/chromeos/personalization_section.h
index b50653c34e6..f704a53d971 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/personalization_section.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/personalization_section.h
@@ -33,6 +33,11 @@ class PersonalizationSection : public OsSettingsSection {
// OsSettingsSection:
void AddLoadTimeData(content::WebUIDataSource* html_source) override;
void AddHandlers(content::WebUI* web_ui) override;
+ int GetSectionNameMessageId() const override;
+ mojom::Section GetSection() const override;
+ mojom::SearchResultIcon GetSectionIcon() const override;
+ std::string GetSectionPath() const override;
+ void RegisterHierarchy(HierarchyGenerator* generator) const override;
// ash::AmbientModeService::Observer:
void OnAmbientModeEnabledStateChanged();
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..38bf2e61ebc 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
@@ -27,11 +27,24 @@ void PluginVmHandler::RegisterMessages() {
"getPluginVmSharedPathsDisplayText",
base::BindRepeating(
&PluginVmHandler::HandleGetPluginVmSharedPathsDisplayText,
- weak_ptr_factory_.GetWeakPtr()));
+ base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"removePluginVmSharedPath",
base::BindRepeating(&PluginVmHandler::HandleRemovePluginVmSharedPath,
- weak_ptr_factory_.GetWeakPtr()));
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "wouldPermissionChangeRequireRelaunch",
+ base::BindRepeating(
+ &PluginVmHandler::HandleWouldPermissionChangeRequireRelaunch,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "setPluginVmPermission",
+ base::BindRepeating(&PluginVmHandler::HandleSetPluginVmPermission,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "relaunchPluginVm",
+ base::BindRepeating(&PluginVmHandler::HandleRelaunchPluginVm,
+ base::Unretained(this)));
}
void PluginVmHandler::HandleGetPluginVmSharedPathsDisplayText(
@@ -68,5 +81,42 @@ void PluginVmHandler::HandleRemovePluginVmSharedPath(
path));
}
+void PluginVmHandler::HandleWouldPermissionChangeRequireRelaunch(
+ const base::ListValue* args) {
+ AllowJavascript();
+ CHECK_EQ(3U, args->GetSize());
+ std::string callback_id = args->GetList()[0].GetString();
+ plugin_vm::PermissionType permission_type =
+ static_cast<plugin_vm::PermissionType>(args->GetList()[1].GetInt());
+ DCHECK(permission_type == plugin_vm::PermissionType::kCamera ||
+ permission_type == plugin_vm::PermissionType::kMicrophone);
+ plugin_vm::PluginVmManager* manager =
+ plugin_vm::PluginVmManagerFactory::GetForProfile(profile_);
+ bool current_value = manager->GetPermission(permission_type);
+ bool proposed_value = args->GetList()[2].GetBool();
+ bool requires_relaunch = proposed_value != current_value &&
+ manager->IsRelaunchNeededForNewPermissions();
+
+ ResolveJavascriptCallback(base::Value(callback_id),
+ base::Value(requires_relaunch));
+}
+
+void PluginVmHandler::HandleSetPluginVmPermission(const base::ListValue* args) {
+ CHECK_EQ(2U, args->GetSize());
+ plugin_vm::PermissionType permission_type =
+ static_cast<plugin_vm::PermissionType>(args->GetList()[0].GetInt());
+ bool proposed_value = args->GetList()[1].GetBool();
+ DCHECK(permission_type == plugin_vm::PermissionType::kCamera ||
+ permission_type == plugin_vm::PermissionType::kMicrophone);
+ plugin_vm::PluginVmManagerFactory::GetForProfile(profile_)->SetPermission(
+ permission_type, proposed_value);
+}
+
+void PluginVmHandler::HandleRelaunchPluginVm(const base::ListValue* args) {
+ CHECK_EQ(0U, args->GetList().size());
+ plugin_vm::PluginVmManagerFactory::GetForProfile(profile_)
+ ->RelaunchPluginVm();
+}
+
} // 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..e1d77e24424 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
@@ -8,6 +8,8 @@
#include <vector>
#include "base/memory/weak_ptr.h"
+#include "chrome/browser/chromeos/plugin_vm/plugin_vm_manager.h"
+#include "chrome/browser/chromeos/plugin_vm/plugin_vm_manager_factory.h"
#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
class Profile;
@@ -32,8 +34,16 @@ class PluginVmHandler : public ::settings::SettingsPageUIHandler {
void HandleGetPluginVmSharedPathsDisplayText(const base::ListValue* args);
// Remove a specified path from being shared.
void HandleRemovePluginVmSharedPath(const base::ListValue* args);
+ // Checks if Plugin VM would need to be relaunched if the proposed changes are
+ // made.
+ void HandleWouldPermissionChangeRequireRelaunch(const base::ListValue* args);
+ // Sets the specified permission to the value proposed.
+ void HandleSetPluginVmPermission(const base::ListValue* args);
+ // Relaunches Plugin VM.
+ void HandleRelaunchPluginVm(const base::ListValue* args);
Profile* profile_;
+
// weak_ptr_factory_ should always be last member.
base::WeakPtrFactory<PluginVmHandler> weak_ptr_factory_{this};
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/printing_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/printing_section.cc
index 3415a894f61..168efe1d2d6 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/printing_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/printing_section.cc
@@ -28,10 +28,7 @@ const std::vector<SearchConcept>& GetPrintingSearchConcepts() {
mojom::SearchResultIcon::kPrinter,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
- {.setting = mojom::Setting::kAddPrinter},
- {IDS_OS_SETTINGS_TAG_PRINTING_ADD_PRINTER_ALT1,
- IDS_OS_SETTINGS_TAG_PRINTING_ADD_PRINTER_ALT2,
- SearchConcept::kAltTagEnd}},
+ {.setting = mojom::Setting::kAddPrinter}},
{IDS_OS_SETTINGS_TAG_PRINTING_SAVED_PRINTERS,
mojom::kPrintingDetailsSubpagePath,
mojom::SearchResultIcon::kPrinter,
@@ -41,7 +38,7 @@ const std::vector<SearchConcept>& GetPrintingSearchConcepts() {
{IDS_OS_SETTINGS_TAG_PRINTING,
mojom::kPrintingDetailsSubpagePath,
mojom::SearchResultIcon::kPrinter,
- mojom::SearchResultDefaultRank::kHigh,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
{.subpage = mojom::Subpage::kPrintingDetails},
{IDS_OS_SETTINGS_TAG_PRINTING_ALT1, IDS_OS_SETTINGS_TAG_PRINTING_ALT2,
@@ -76,9 +73,10 @@ PrintingSection::PrintingSection(Profile* profile,
CupsPrintersManager* printers_manager)
: OsSettingsSection(profile, search_tag_registry),
printers_manager_(printers_manager) {
- registry()->AddSearchTags(GetPrintingSearchConcepts());
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+ updater.AddSearchTags(GetPrintingSearchConcepts());
if (IsPrintManagementEnabled())
- registry()->AddSearchTags(GetPrintingManagementSearchConcepts());
+ updater.AddSearchTags(GetPrintingManagementSearchConcepts());
}
PrintingSection::~PrintingSection() = default;
@@ -246,5 +244,38 @@ void PrintingSection::AddHandlers(content::WebUI* web_ui) {
std::make_unique<CupsPrintersHandler>(profile(), printers_manager_));
}
+int PrintingSection::GetSectionNameMessageId() const {
+ return IDS_SETTINGS_PRINTING;
+}
+
+mojom::Section PrintingSection::GetSection() const {
+ return mojom::Section::kPrinting;
+}
+
+mojom::SearchResultIcon PrintingSection::GetSectionIcon() const {
+ return mojom::SearchResultIcon::kPrinter;
+}
+
+std::string PrintingSection::GetSectionPath() const {
+ return mojom::kPrintingSectionPath;
+}
+
+void PrintingSection::RegisterHierarchy(HierarchyGenerator* generator) const {
+ generator->RegisterTopLevelSetting(mojom::Setting::kPrintJobs);
+
+ // Printing details.
+ generator->RegisterTopLevelSubpage(IDS_SETTINGS_PRINTING_CUPS_PRINTERS,
+ mojom::Subpage::kPrintingDetails,
+ mojom::SearchResultIcon::kPrinter,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::kPrintingDetailsSubpagePath);
+ static constexpr mojom::Setting kPrintingDetailsSettings[] = {
+ mojom::Setting::kAddPrinter,
+ mojom::Setting::kSavedPrinters,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kPrintingDetails,
+ kPrintingDetailsSettings, generator);
+}
+
} // namespace settings
} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/printing_section.h b/chromium/chrome/browser/ui/webui/settings/chromeos/printing_section.h
index b231aeec420..ddef65c546e 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/printing_section.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/printing_section.h
@@ -31,6 +31,11 @@ class PrintingSection : public OsSettingsSection {
// OsSettingsSection:
void AddLoadTimeData(content::WebUIDataSource* html_source) override;
void AddHandlers(content::WebUI* web_ui) override;
+ int GetSectionNameMessageId() const override;
+ mojom::Section GetSection() const override;
+ mojom::SearchResultIcon GetSectionIcon() const override;
+ std::string GetSectionPath() const override;
+ void RegisterHierarchy(HierarchyGenerator* generator) const override;
CupsPrintersManager* printers_manager_;
};
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc
index 94e70f481b3..85c6dea6016 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc
@@ -13,6 +13,7 @@
#include "chrome/common/chrome_features.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/generated_resources.h"
+#include "chromeos/constants/chromeos_features.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"
@@ -32,7 +33,7 @@ const std::vector<SearchConcept>& GetPrivacySearchConcepts() {
{IDS_OS_SETTINGS_TAG_PRIVACY,
mojom::kPrivacyAndSecuritySectionPath,
mojom::SearchResultIcon::kShield,
- mojom::SearchResultDefaultRank::kHigh,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSection,
{.section = mojom::Section::kPrivacyAndSecurity}},
{IDS_OS_SETTINGS_TAG_PRIVACY_WIFI_SLEEP,
@@ -68,9 +69,10 @@ const std::vector<SearchConcept>& GetPrivacyGoogleChromeSearchConcepts() {
PrivacySection::PrivacySection(Profile* profile,
SearchTagRegistry* search_tag_registry)
: OsSettingsSection(profile, search_tag_registry) {
- registry()->AddSearchTags(GetPrivacySearchConcepts());
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+ updater.AddSearchTags(GetPrivacySearchConcepts());
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
- registry()->AddSearchTags(GetPrivacyGoogleChromeSearchConcepts());
+ updater.AddSearchTags(GetPrivacyGoogleChromeSearchConcepts());
#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
}
@@ -84,6 +86,9 @@ void PrivacySection::AddLoadTimeData(content::WebUIDataSource* html_source) {
{"wakeOnWifi", IDS_SETTINGS_WAKE_ON_WIFI_DESCRIPTION},
{"enableContentProtectionAttestation",
IDS_SETTINGS_ENABLE_CONTENT_PROTECTION_ATTESTATION},
+ {"enableSuggestedContent", IDS_SETTINGS_ENABLE_SUGGESTED_CONTENT_TITLE},
+ {"enableSuggestedContentDesc",
+ IDS_SETTINGS_ENABLE_SUGGESTED_CONTENT_DESC},
};
AddLocalizedStringsBulk(html_source, kLocalizedStrings);
@@ -91,10 +96,40 @@ void PrivacySection::AddLoadTimeData(content::WebUIDataSource* html_source) {
"privacySettingsRedesignEnabled",
base::FeatureList::IsEnabled(::features::kPrivacySettingsRedesign));
+ html_source->AddBoolean("suggestedContentToggleEnabled",
+ base::FeatureList::IsEnabled(
+ ::chromeos::features::kSuggestedContentToggle));
+
+ html_source->AddString("suggestedContentLearnMoreURL",
+ chrome::kSuggestedContentLearnMoreURL);
+
html_source->AddString("syncAndGoogleServicesLearnMoreURL",
chrome::kSyncAndGoogleServicesLearnMoreURL);
::settings::AddPersonalizationOptionsStrings(html_source);
}
+int PrivacySection::GetSectionNameMessageId() const {
+ return IDS_SETTINGS_PRIVACY;
+}
+
+mojom::Section PrivacySection::GetSection() const {
+ return mojom::Section::kPrivacyAndSecurity;
+}
+
+mojom::SearchResultIcon PrivacySection::GetSectionIcon() const {
+ return mojom::SearchResultIcon::kShield;
+}
+
+std::string PrivacySection::GetSectionPath() const {
+ return mojom::kPrivacyAndSecuritySectionPath;
+}
+
+void PrivacySection::RegisterHierarchy(HierarchyGenerator* generator) const {
+ generator->RegisterTopLevelSetting(mojom::Setting::kVerifiedAccess);
+ generator->RegisterTopLevelSetting(mojom::Setting::kKeepWifiOnDuringSleep);
+ generator->RegisterTopLevelSetting(
+ mojom::Setting::kUsageStatsAndCrashReports);
+}
+
} // namespace settings
} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/privacy_section.h b/chromium/chrome/browser/ui/webui/settings/chromeos/privacy_section.h
index 3c5ba842681..4acbc9d465c 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/privacy_section.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/privacy_section.h
@@ -26,6 +26,11 @@ class PrivacySection : public OsSettingsSection {
private:
// OsSettingsSection:
void AddLoadTimeData(content::WebUIDataSource* html_source) override;
+ int GetSectionNameMessageId() const override;
+ mojom::Section GetSection() const override;
+ mojom::SearchResultIcon GetSectionIcon() const override;
+ std::string GetSectionPath() const override;
+ void RegisterHierarchy(HierarchyGenerator* generator) const override;
};
} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/reset_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/reset_section.cc
index 1275fb0e188..21216088ddc 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/reset_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/reset_section.cc
@@ -56,8 +56,9 @@ bool IsPowerwashAllowed() {
ResetSection::ResetSection(Profile* profile,
SearchTagRegistry* search_tag_registry)
: OsSettingsSection(profile, search_tag_registry) {
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
if (IsPowerwashAllowed())
- registry()->AddSearchTags(GetResetSearchConcepts());
+ updater.AddSearchTags(GetResetSearchConcepts());
}
ResetSection::~ResetSection() = default;
@@ -94,5 +95,25 @@ void ResetSection::AddHandlers(content::WebUI* web_ui) {
std::make_unique<::settings::ResetSettingsHandler>(profile()));
}
+int ResetSection::GetSectionNameMessageId() const {
+ return IDS_SETTINGS_RESET;
+}
+
+mojom::Section ResetSection::GetSection() const {
+ return mojom::Section::kReset;
+}
+
+mojom::SearchResultIcon ResetSection::GetSectionIcon() const {
+ return mojom::SearchResultIcon::kReset;
+}
+
+std::string ResetSection::GetSectionPath() const {
+ return mojom::kResetSectionPath;
+}
+
+void ResetSection::RegisterHierarchy(HierarchyGenerator* generator) const {
+ generator->RegisterTopLevelSetting(mojom::Setting::kPowerwash);
+}
+
} // namespace settings
} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/reset_section.h b/chromium/chrome/browser/ui/webui/settings/chromeos/reset_section.h
index ee99e0554c7..90287737e66 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/reset_section.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/reset_section.h
@@ -28,6 +28,11 @@ class ResetSection : public OsSettingsSection {
// OsSettingsSection:
void AddLoadTimeData(content::WebUIDataSource* html_source) override;
void AddHandlers(content::WebUI* web_ui) override;
+ int GetSectionNameMessageId() const override;
+ mojom::Section GetSection() const override;
+ mojom::SearchResultIcon GetSectionIcon() const override;
+ std::string GetSectionPath() const override;
+ void RegisterHierarchy(HierarchyGenerator* generator) const override;
};
} // namespace 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
index 4be5d33c332..d63ae03274c 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search.mojom
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search.mojom
@@ -30,6 +30,22 @@ enum SearchResultDefaultRank {
kLow,
};
+// Behavior used when determining whether to return parent results for a query.
+// Results are returned based on whether text for those results matches the
+// user's query, but we also support returning a result for the parent of the
+// original result. In this context, a "parent" refers to a section or subpage
+// which contains a child subpage or setting. For example,
+// Subpage::kWifiNetworks is a subpage whose parent is Section::kNetwork, and
+// Setting::kWifiOnOff is a setting whose parent is Subpage::kWifiNetworks.
+enum ParentResultBehavior {
+ // Returns parent results as long as the number of maximum results is not
+ // exceeded.
+ kAllowParentResults,
+
+ // Does not return parent results.
+ kDoNotIncludeParentResults,
+};
+
// Identifier for the result; each result describes one section, subpage, or
// setting.
union SearchResultIdentifier {
@@ -44,6 +60,12 @@ struct SearchResult {
// directly (i.e., not an ID but rather the actual text).
mojo_base.mojom.String16 result_text;
+ // String for the "canonical" version of this result. Some search results use
+ // alternate text (e.g., "Monitor" instead of "Display"). Note that it is
+ // often the case that |result_text| and |canonical_result_text| are the same
+ // string.
+ mojo_base.mojom.String16 canonical_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
@@ -57,29 +79,57 @@ struct SearchResult {
// string match.
double relevance_score;
- // List of names of the sections/subpages for this result, which may contain
- // names of sections and/or subpages. Names are all localized String16s, ready
- // to be displayed directly (e.g., as breadcrumbs).
+ // List of names of the ancestor sections/subpages for this result. The list
+ // contains the Settings app name and, if applicable, the ancestor section and
+ // subpage names. Names are all localized String16s which can be displayed in
+ // the UI (e.g., as breadcrumbs).
//
- // Example 1 - Wi-Fi subpage: ["Settings", "Network", "Wi-Fi"]
- // Example 2 - External storage: ["Settings", "Device", "Storage management",
- // "External storage preferences"]
+ // Example 1 - Wi-Fi subpage: ["Settings", "Network"]
+ // Example 2 - External storage: ["Settings", "Device", "Storage management"]
array<mojo_base.mojom.String16> settings_page_hierarchy;
// Default ranking, which is used to break ties when searching for results.
SearchResultDefaultRank default_rank;
+ // True if this result was generated due to a text match; this field can be
+ // false if it was constructed due to a ParentResultBehavior.
+ bool was_generated_from_text_match;
+
// The type and identifier for this search result. The value of the |type|
// field indicates the union member used by |id|.
SearchResultType type;
SearchResultIdentifier id;
};
+// Used to observe changes to search results.
+interface SearchResultsObserver {
+ // Called when the availability of one or more search results has changed. In
+ // this context, "availability" refers to whether a search result can be
+ // returned based on the user's current state. E.g., "Cellular" results are
+ // only shown if the device has an attached modem, so this function would be
+ // called whenever the user plugs in or unplugs a USB modem. Clients can use
+ // this function to ensure that they do not show "stale" results which are no
+ // longer actionable by the user.
+ OnSearchResultAvailabilityChanged();
+};
+
// 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);
+ //
+ // This function returns an array with a maximum size of |max_num_results|,
+ // but the array may contain fewer elements if there are fewer results.
+ // Clients should never pass a value of 0 for |max_num_results|, since that
+ // would return an empty result array.
+ Search(mojo_base.mojom.String16 query,
+ uint32 max_num_results,
+ ParentResultBehavior parent_result_behavior) =>
+ (array<SearchResult> results);
+
+ // Adds an observer of search results. Disconnected observers are discarded;
+ // to stop observing, close the connection.
+ Observe(pending_remote<SearchResultsObserver> observer);
};
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
index b3763fb0fd3..639dc470ce3 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_concept.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_concept.h
@@ -7,6 +7,7 @@
#include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h"
#include "chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom.h"
+#include "chrome/browser/ui/webui/settings/chromeos/os_settings_identifier.h"
#include "chrome/browser/ui/webui/settings/chromeos/search/search.mojom.h"
#include "chrome/browser/ui/webui/settings/chromeos/search/search_result_icon.mojom.h"
@@ -58,7 +59,7 @@ struct SearchConcept {
// The type and identifier for this search result. The value of the |type|
// field indicates the union member used by |id|.
mojom::SearchResultType type;
- Identifier id;
+ OsSettingsIdentifier id;
// Alternate message IDs (from os_settings_search_tag_strings.grdp)
// corresponding to this concept. These IDs refer to messages which represent
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
index 47c0052bbf0..1bde04057b2 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc
@@ -4,12 +4,14 @@
#include "chrome/browser/ui/webui/settings/chromeos/search/search_handler.h"
+#include <algorithm>
+
#include "base/strings/string_number_conversions.h"
-#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chromeos/local_search_service/local_search_service.h"
+#include "chrome/browser/ui/webui/settings/chromeos/hierarchy.h"
+#include "chrome/browser/ui/webui/settings/chromeos/os_settings_sections.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/browser/ui/webui/settings/chromeos/search/search_tag_registry.h"
#include "chrome/grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
@@ -17,30 +19,42 @@ namespace chromeos {
namespace settings {
namespace {
-const int32_t kLocalSearchServiceMaxResults = 10;
+bool ContainsSectionResult(const std::vector<mojom::SearchResultPtr>& results,
+ mojom::Section section) {
+ return std::find_if(
+ results.begin(), results.end(), [section](const auto& result) {
+ return result->type == mojom::SearchResultType::kSection &&
+ section == result->id->get_section();
+ }) != results.end();
+}
-// TODO(https://crbug.com/1071700): Delete this function.
-std::vector<base::string16> GenerateDummySettingsHierarchy(
- const char* url_path_with_parameters) {
- std::vector<base::string16> hierarchy;
- hierarchy.push_back(l10n_util::GetStringUTF16(IDS_INTERNAL_APP_SETTINGS));
- hierarchy.push_back(base::ASCIIToUTF16(url_path_with_parameters));
- return hierarchy;
+bool ContainsSubpageResult(const std::vector<mojom::SearchResultPtr>& results,
+ mojom::Subpage subpage) {
+ return std::find_if(
+ results.begin(), results.end(), [subpage](const auto& result) {
+ return result->type == mojom::SearchResultType::kSubpage &&
+ subpage == result->id->get_subpage();
+ }) != results.end();
}
} // namespace
-// static
-const size_t SearchHandler::kNumMaxResults = 5;
-
SearchHandler::SearchHandler(
SearchTagRegistry* search_tag_registry,
+ OsSettingsSections* sections,
+ Hierarchy* hierarchy,
local_search_service::LocalSearchService* local_search_service)
: search_tag_registry_(search_tag_registry),
+ sections_(sections),
+ hierarchy_(hierarchy),
index_(local_search_service->GetIndex(
- local_search_service::IndexId::kCrosSettings)) {}
+ local_search_service::IndexId::kCrosSettings)) {
+ search_tag_registry_->AddObserver(this);
+}
-SearchHandler::~SearchHandler() = default;
+SearchHandler::~SearchHandler() {
+ search_tag_registry_->RemoveObserver(this);
+}
void SearchHandler::BindInterface(
mojo::PendingReceiver<mojom::SearchHandler> pending_receiver) {
@@ -48,10 +62,19 @@ void SearchHandler::BindInterface(
}
std::vector<mojom::SearchResultPtr> SearchHandler::Search(
- const base::string16& query) {
+ const base::string16& query,
+ uint32_t max_num_results,
+ mojom::ParentResultBehavior parent_result_behavior) {
+ // Search for 5x the maximum set of results. If there are many matches for
+ // a query, it may be the case that |index_| returns some matches with higher
+ // SearchResultDefaultRank values later in the list. Requesting up to 5x the
+ // maximum number ensures that such results will be returned and can be ranked
+ // accordingly when sorted.
+ uint32_t max_local_search_service_results = 5 * max_num_results;
+
std::vector<local_search_service::Result> local_search_service_results;
local_search_service::ResponseStatus response_status = index_->Find(
- query, kLocalSearchServiceMaxResults, &local_search_service_results);
+ query, max_local_search_service_results, &local_search_service_results);
if (response_status != local_search_service::ResponseStatus::kSuccess) {
LOG(ERROR) << "Cannot search; LocalSearchService returned "
@@ -60,41 +83,149 @@ std::vector<mojom::SearchResultPtr> SearchHandler::Search(
return {};
}
- return GenerateSearchResultsArray(local_search_service_results);
+ return GenerateSearchResultsArray(local_search_service_results,
+ max_num_results, parent_result_behavior);
}
void SearchHandler::Search(const base::string16& query,
+ uint32_t max_num_results,
+ mojom::ParentResultBehavior parent_result_behavior,
SearchCallback callback) {
- std::move(callback).Run(Search(query));
+ std::move(callback).Run(
+ Search(query, max_num_results, parent_result_behavior));
+}
+
+void SearchHandler::Observe(
+ mojo::PendingRemote<mojom::SearchResultsObserver> observer) {
+ observers_.Add(std::move(observer));
+}
+
+void SearchHandler::OnRegistryUpdated() {
+ for (auto& observer : observers_)
+ observer->OnSearchResultAvailabilityChanged();
}
std::vector<mojom::SearchResultPtr> SearchHandler::GenerateSearchResultsArray(
const std::vector<local_search_service::Result>&
- local_search_service_results) {
+ local_search_service_results,
+ uint32_t max_num_results,
+ mojom::ParentResultBehavior parent_result_behavior) const {
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;
+ std::sort(search_results.begin(), search_results.end(), CompareSearchResults);
+
+ // Now that the results have been sorted, limit the size of to
+ // |max_num_results|.
+ search_results.resize(
+ std::min(static_cast<size_t>(max_num_results), search_results.size()));
+
+ if (parent_result_behavior ==
+ mojom::ParentResultBehavior::kAllowParentResults) {
+ AddParentResults(max_num_results, &search_results);
}
return search_results;
}
-mojom::SearchResultPtr SearchHandler::ResultToSearchResult(
- const local_search_service::Result& result) {
- int message_id;
+void SearchHandler::AddParentResults(
+ uint32_t max_num_results,
+ std::vector<mojom::SearchResultPtr>* search_results) const {
+ auto it = search_results->begin();
+ while (search_results->size() < max_num_results &&
+ it != search_results->end()) {
+ const mojom::SearchResultPtr& result = *it;
+ switch (result->type) {
+ case mojom::SearchResultType::kSection:
+ // Sections have no parents; nothing to do.
+ break;
- // The result's ID is expected to be a stringified int.
- if (!base::StringToInt(result.id, &message_id))
- return nullptr;
+ case mojom::SearchResultType::kSubpage: {
+ const Hierarchy::SubpageMetadata& metadata =
+ hierarchy_->GetSubpageMetadata(result->id->get_subpage());
+
+ // Nested subpage.
+ if (metadata.parent_subpage) {
+ it = AddSubpageResultIfPossible(it, *metadata.parent_subpage,
+ result->relevance_score,
+ search_results);
+ break;
+ }
+
+ // Top-level subpage.
+ it = AddSectionResultIfPossible(it, result, metadata.section,
+ search_results);
+ break;
+ }
+
+ case mojom::SearchResultType::kSetting: {
+ const Hierarchy::SettingMetadata& metadata =
+ hierarchy_->GetSettingMetadata(result->id->get_setting());
+
+ // Nested setting.
+ if (metadata.primary.second) {
+ it = AddSubpageResultIfPossible(it, *metadata.primary.second,
+ result->relevance_score,
+ search_results);
+ break;
+ }
+
+ // Top-level setting.
+ it = AddSectionResultIfPossible(it, result, metadata.primary.first,
+ search_results);
+ break;
+ }
+ }
+ ++it;
+ }
+}
+
+std::vector<mojom::SearchResultPtr>::iterator
+SearchHandler::AddSectionResultIfPossible(
+ const std::vector<mojom::SearchResultPtr>::iterator& curr_position,
+ const mojom::SearchResultPtr& child_result,
+ mojom::Section section,
+ std::vector<mojom::SearchResultPtr>* results) const {
+ // If |results| already includes |section|, do not add it again.
+ if (ContainsSectionResult(*results, section))
+ return curr_position;
+
+ mojom::SearchResultPtr section_result =
+ hierarchy_->GetSectionMetadata(section).ToSearchResult(
+ child_result->relevance_score);
+
+ // Don't add a result for a parent section if it has the exact same text as
+ // the child result, since this results in a broken-looking UI.
+ if (section_result->result_text == child_result->result_text)
+ return curr_position;
+
+ return results->insert(curr_position + 1, std::move(section_result));
+}
+
+std::vector<mojom::SearchResultPtr>::iterator
+SearchHandler::AddSubpageResultIfPossible(
+ const std::vector<mojom::SearchResultPtr>::iterator& curr_position,
+ mojom::Subpage subpage,
+ double relevance_score,
+ std::vector<mojom::SearchResultPtr>* results) const {
+ // If |results| already includes |subpage|, do not add it again.
+ if (ContainsSubpageResult(*results, subpage))
+ return curr_position;
+
+ return results->insert(
+ curr_position + 1,
+ hierarchy_->GetSubpageMetadata(subpage).ToSearchResult(relevance_score));
+}
+
+mojom::SearchResultPtr SearchHandler::ResultToSearchResult(
+ const local_search_service::Result& result) const {
const SearchConcept* concept =
- search_tag_registry_->GetCanonicalTagMetadata(message_id);
+ search_tag_registry_->GetTagMetadata(result.id);
// If the concept was not registered, no metadata is available. This can occur
// if the search tag was dynamically unregistered during the asynchronous
@@ -102,29 +233,85 @@ mojom::SearchResultPtr SearchHandler::ResultToSearchResult(
if (!concept)
return nullptr;
+ // |result| is expected to have one position, whose ID is a stringified int.
+ DCHECK_EQ(1u, result.positions.size());
+ int content_id;
+ if (!base::StringToInt(result.positions[0].content_id, &content_id))
+ return nullptr;
+
+ std::string url;
mojom::SearchResultIdentifierPtr result_id;
+ std::vector<base::string16> hierarchy_strings;
switch (concept->type) {
- case mojom::SearchResultType::kSection:
- result_id =
- mojom::SearchResultIdentifier::NewSection(concept->id.section);
+ case mojom::SearchResultType::kSection: {
+ mojom::Section section = concept->id.section;
+ url = GetModifiedUrl(*concept, section);
+ result_id = mojom::SearchResultIdentifier::NewSection(section);
+ hierarchy_strings.push_back(
+ l10n_util::GetStringUTF16(IDS_INTERNAL_APP_SETTINGS));
break;
- case mojom::SearchResultType::kSubpage:
- result_id =
- mojom::SearchResultIdentifier::NewSubpage(concept->id.subpage);
+ }
+ case mojom::SearchResultType::kSubpage: {
+ mojom::Subpage subpage = concept->id.subpage;
+ url = GetModifiedUrl(*concept,
+ hierarchy_->GetSubpageMetadata(subpage).section);
+ result_id = mojom::SearchResultIdentifier::NewSubpage(subpage);
+ hierarchy_strings = hierarchy_->GenerateAncestorHierarchyStrings(subpage);
break;
- case mojom::SearchResultType::kSetting:
- result_id =
- mojom::SearchResultIdentifier::NewSetting(concept->id.setting);
+ }
+ case mojom::SearchResultType::kSetting: {
+ mojom::Setting setting = concept->id.setting;
+ url = GetModifiedUrl(
+ *concept, hierarchy_->GetSettingMetadata(setting).primary.first);
+ result_id = mojom::SearchResultIdentifier::NewSetting(setting);
+ hierarchy_strings = hierarchy_->GenerateAncestorHierarchyStrings(setting);
break;
+ }
}
- // TODO(https://crbug.com/1071700): Generate real hierarchy instead of using
- // GenerateDummySettingsHierarchy().
return mojom::SearchResult::New(
- l10n_util::GetStringUTF16(message_id), concept->url_path_with_parameters,
- concept->icon, result.score,
- GenerateDummySettingsHierarchy(concept->url_path_with_parameters),
- concept->default_rank, concept->type, std::move(result_id));
+ /*result_text=*/l10n_util::GetStringUTF16(content_id),
+ /*canonical_result_text=*/
+ l10n_util::GetStringUTF16(concept->canonical_message_id), url,
+ concept->icon, result.score, hierarchy_strings, concept->default_rank,
+ /*was_generated_from_text_match=*/true, concept->type,
+ std::move(result_id));
+}
+
+std::string SearchHandler::GetModifiedUrl(const SearchConcept& concept,
+ mojom::Section section) const {
+ return sections_->GetSection(section)->ModifySearchResultUrl(
+ concept.type, concept.id, concept.url_path_with_parameters);
+}
+
+// static
+bool SearchHandler::CompareSearchResults(const mojom::SearchResultPtr& first,
+ const mojom::SearchResultPtr& second) {
+ // Compute the difference between the results' default rankings. Note that
+ // kHigh is declared before kMedium which is declared before kLow, so a
+ // negative value indicates that |first| is ranked higher than |second| and a
+ // positive value indicates that |second| is ranked higher than |first|.
+ int32_t default_rank_diff = static_cast<int32_t>(first->default_rank) -
+ static_cast<int32_t>(second->default_rank);
+ if (default_rank_diff < 0)
+ return true;
+ if (default_rank_diff > 0)
+ return false;
+
+ // At this point, the default ranks are equal, so compare relevance scores. A
+ // higher relevance score indicates a better text match, so the reverse is
+ // true this time.
+ if (first->relevance_score > second->relevance_score)
+ return true;
+ if (first->relevance_score < second->relevance_score)
+ return false;
+
+ // Default rank and relevance scores are equal, so prefer the result which is
+ // higher on the hierarchy. kSection is declared before kSubpage which is
+ // declared before kSetting, so follow the same pattern from default ranks
+ // above. Note that if the types are equal, this will return false, which
+ // induces a strict weak ordering.
+ return static_cast<int32_t>(first->type) < static_cast<int32_t>(second->type);
}
} // namespace settings
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
index 8247cccaa9d..2425c2b56ac 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.h
@@ -7,12 +7,16 @@
#include <vector>
+#include "base/gtest_prod_util.h"
#include "base/optional.h"
#include "chrome/browser/chromeos/local_search_service/index.h"
#include "chrome/browser/ui/webui/settings/chromeos/search/search.mojom.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "mojo/public/cpp/bindings/remote.h"
+#include "mojo/public/cpp/bindings/remote_set.h"
namespace local_search_service {
class LocalSearchService;
@@ -21,7 +25,9 @@ class LocalSearchService;
namespace chromeos {
namespace settings {
-class SearchTagRegistry;
+class Hierarchy;
+class OsSettingsSections;
+struct SearchConcept;
// 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
@@ -29,14 +35,13 @@ class SearchTagRegistry;
// indexed in the LocalSearchService and cross-referencing results with
// SearchTagRegistry.
//
-// SearchHandler returns at most |kNumMaxResults| results; searches which do not
-// provide any matches result in an empty results array.
-class SearchHandler : public mojom::SearchHandler {
+// Searches which do not provide any matches result in an empty results array.
+class SearchHandler : public mojom::SearchHandler,
+ public SearchTagRegistry::Observer {
public:
- // Maximum number of results returned by a Search() call.
- static const size_t kNumMaxResults;
-
SearchHandler(SearchTagRegistry* search_tag_registry,
+ OsSettingsSections* sections,
+ Hierarchy* hierarchy,
local_search_service::LocalSearchService* local_search_service);
~SearchHandler() override;
@@ -47,23 +52,64 @@ class SearchHandler : public mojom::SearchHandler {
mojo::PendingReceiver<mojom::SearchHandler> pending_receiver);
// Synchronous search implementation (for in-process clients).
- std::vector<mojom::SearchResultPtr> Search(const base::string16& query);
+ std::vector<mojom::SearchResultPtr> Search(
+ const base::string16& query,
+ uint32_t max_num_results,
+ mojom::ParentResultBehavior parent_result_behavior);
// mojom::SearchHandler:
- void Search(const base::string16& query, SearchCallback callback) override;
+ void Search(const base::string16& query,
+ uint32_t max_num_results,
+ mojom::ParentResultBehavior parent_result_behavior,
+ SearchCallback callback) override;
+ void Observe(
+ mojo::PendingRemote<mojom::SearchResultsObserver> observer) override;
private:
+ FRIEND_TEST_ALL_PREFIXES(SearchHandlerTest, CompareSearchResults);
+
+ // SearchTagRegistry::Observer:
+ void OnRegistryUpdated() override;
+
std::vector<mojom::SearchResultPtr> GenerateSearchResultsArray(
const std::vector<local_search_service::Result>&
- local_search_service_results);
+ local_search_service_results,
+ uint32_t max_num_results,
+ mojom::ParentResultBehavior parent_result_behavior) const;
+
+ void AddParentResults(
+ uint32_t max_num_results,
+ std::vector<mojom::SearchResultPtr>* search_results) const;
+
+ std::vector<mojom::SearchResultPtr>::iterator AddSectionResultIfPossible(
+ const std::vector<mojom::SearchResultPtr>::iterator& position,
+ const mojom::SearchResultPtr& child_result,
+ mojom::Section section,
+ std::vector<mojom::SearchResultPtr>* results) const;
+
+ std::vector<mojom::SearchResultPtr>::iterator AddSubpageResultIfPossible(
+ const std::vector<mojom::SearchResultPtr>::iterator& position,
+ mojom::Subpage subpage,
+ double relevance_score,
+ std::vector<mojom::SearchResultPtr>* results) const;
+
mojom::SearchResultPtr ResultToSearchResult(
- const local_search_service::Result& result);
+ const local_search_service::Result& result) const;
+ std::string GetModifiedUrl(const SearchConcept& concept,
+ mojom::Section section) const;
+
+ // Returns true if |first| should be ranked before |second|.
+ static bool CompareSearchResults(const mojom::SearchResultPtr& first,
+ const mojom::SearchResultPtr& second);
SearchTagRegistry* search_tag_registry_;
+ OsSettingsSections* sections_;
+ Hierarchy* hierarchy_;
local_search_service::Index* index_;
- // Note: Expected to have multiple clients, so a ReceiverSet is used.
+ // Note: Expected to have multiple clients, so ReceiverSet/RemoteSet are used.
mojo::ReceiverSet<mojom::SearchHandler> receivers_;
+ mojo::RemoteSet<mojom::SearchResultsObserver> observers_;
};
} // namespace settings
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
index f2c9d42af8d..d0ecd2baef6 100644
--- 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
@@ -10,17 +10,41 @@
#include "base/test/task_environment.h"
#include "chrome/browser/chromeos/local_search_service/local_search_service.h"
#include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h"
+#include "chrome/browser/ui/webui/settings/chromeos/fake_hierarchy.h"
+#include "chrome/browser/ui/webui/settings/chromeos/fake_os_settings_sections.h"
#include "chrome/browser/ui/webui/settings/chromeos/search/search.mojom-test-utils.h"
#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h"
#include "chrome/grit/generated_resources.h"
#include "chromeos/constants/chromeos_features.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/l10n/l10n_util.h"
namespace chromeos {
namespace settings {
namespace {
+class FakeObserver : public mojom::SearchResultsObserver {
+ public:
+ FakeObserver() = default;
+ ~FakeObserver() override = default;
+
+ mojo::PendingRemote<mojom::SearchResultsObserver> GenerateRemote() {
+ mojo::PendingRemote<mojom::SearchResultsObserver> remote;
+ receiver_.Bind(remote.InitWithNewPipeAndPassReceiver());
+ return remote;
+ }
+
+ size_t num_calls() const { return num_calls_; }
+
+ private:
+ // mojom::SearchResultsObserver:
+ void OnSearchResultAvailabilityChanged() override { ++num_calls_; }
+
+ size_t num_calls_ = 0;
+ mojo::Receiver<mojom::SearchResultsObserver> receiver_{this};
+};
+
// Note: Copied from printing_section.cc but does not need to stay in sync with
// it.
const std::vector<SearchConcept>& GetPrintingSearchConcepts() {
@@ -30,10 +54,7 @@ const std::vector<SearchConcept>& GetPrintingSearchConcepts() {
mojom::SearchResultIcon::kPrinter,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
- {.setting = mojom::Setting::kAddPrinter},
- {IDS_OS_SETTINGS_TAG_PRINTING_ADD_PRINTER_ALT1,
- IDS_OS_SETTINGS_TAG_PRINTING_ADD_PRINTER_ALT2,
- SearchConcept::kAltTagEnd}},
+ {.setting = mojom::Setting::kAddPrinter}},
{IDS_OS_SETTINGS_TAG_PRINTING_SAVED_PRINTERS,
mojom::kPrintingDetailsSubpagePath,
mojom::SearchResultIcon::kPrinter,
@@ -43,7 +64,7 @@ const std::vector<SearchConcept>& GetPrintingSearchConcepts() {
{IDS_OS_SETTINGS_TAG_PRINTING,
mojom::kPrintingDetailsSubpagePath,
mojom::SearchResultIcon::kPrinter,
- mojom::SearchResultDefaultRank::kHigh,
+ mojom::SearchResultDefaultRank::kLow,
mojom::SearchResultType::kSubpage,
{.subpage = mojom::Subpage::kPrintingDetails},
{IDS_OS_SETTINGS_TAG_PRINTING_ALT1, IDS_OS_SETTINGS_TAG_PRINTING_ALT2,
@@ -52,13 +73,30 @@ const std::vector<SearchConcept>& GetPrintingSearchConcepts() {
return *tags;
}
+// Creates a result with some default values.
+mojom::SearchResultPtr CreateDummyResult() {
+ return mojom::SearchResult::New(
+ /*result_text=*/base::string16(),
+ /*canonical_result_text=*/base::string16(), /*url=*/"",
+ mojom::SearchResultIcon::kPrinter, /*relevance_score=*/0.5,
+ /*hierarchy_strings=*/std::vector<base::string16>(),
+ mojom::SearchResultDefaultRank::kMedium,
+ /*was_generated_from_text_match=*/false,
+ mojom::SearchResultType::kSection,
+ mojom::SearchResultIdentifier::NewSection(mojom::Section::kPrinting));
+}
+
} // namespace
class SearchHandlerTest : public testing::Test {
protected:
SearchHandlerTest()
: search_tag_registry_(&local_search_service_),
- handler_(&search_tag_registry_, &local_search_service_) {}
+ fake_hierarchy_(&fake_sections_),
+ handler_(&search_tag_registry_,
+ &fake_sections_,
+ &fake_hierarchy_,
+ &local_search_service_) {}
~SearchHandlerTest() override = default;
// testing::Test:
@@ -66,37 +104,209 @@ class SearchHandlerTest : public testing::Test {
scoped_feature_list_.InitAndEnableFeature(
chromeos::features::kNewOsSettingsSearch);
handler_.BindInterface(handler_remote_.BindNewPipeAndPassReceiver());
+
+ fake_hierarchy_.AddSubpageMetadata(
+ IDS_SETTINGS_PRINTING_CUPS_PRINTERS, mojom::Section::kPrinting,
+ mojom::Subpage::kPrintingDetails, mojom::SearchResultIcon::kPrinter,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::kPrintingDetailsSubpagePath);
+ fake_hierarchy_.AddSettingMetadata(mojom::Section::kPrinting,
+ mojom::Setting::kAddPrinter);
+ fake_hierarchy_.AddSettingMetadata(mojom::Section::kPrinting,
+ mojom::Setting::kSavedPrinters);
+
+ handler_remote_->Observe(observer_.GenerateRemote());
+ handler_remote_.FlushForTesting();
+ }
+
+ void AddSearchTags(const std::vector<SearchConcept>& search_tags) {
+ SearchTagRegistry::ScopedTagUpdater updater =
+ search_tag_registry_.StartUpdate();
+ updater.AddSearchTags(search_tags);
+ }
+
+ void RemoveSearchTags(const std::vector<SearchConcept>& search_tags) {
+ SearchTagRegistry::ScopedTagUpdater updater =
+ search_tag_registry_.StartUpdate();
+ updater.RemoveSearchTags(search_tags);
}
base::test::TaskEnvironment task_environment_;
base::test::ScopedFeatureList scoped_feature_list_;
local_search_service::LocalSearchService local_search_service_;
SearchTagRegistry search_tag_registry_;
+ FakeOsSettingsSections fake_sections_;
+ FakeHierarchy fake_hierarchy_;
SearchHandler handler_;
mojo::Remote<mojom::SearchHandler> handler_remote_;
+ FakeObserver observer_;
};
TEST_F(SearchHandlerTest, AddAndRemove) {
- // Add printing search tags to registry and search for "Printing".
- search_tag_registry_.AddSearchTags(GetPrintingSearchConcepts());
+ // Add printing search tags to registry and search for "Print".
+ AddSearchTags(GetPrintingSearchConcepts());
+ handler_remote_.FlushForTesting();
+ EXPECT_EQ(1u, observer_.num_calls());
+
std::vector<mojom::SearchResultPtr> search_results;
+
+ // 3 results should be available for a "Print" query.
mojom::SearchHandlerAsyncWaiter(handler_remote_.get())
- .Search(base::ASCIIToUTF16("Printing"), &search_results);
+ .Search(base::ASCIIToUTF16("Print"),
+ /*max_num_results=*/3u,
+ mojom::ParentResultBehavior::kDoNotIncludeParentResults,
+ &search_results);
+ EXPECT_EQ(search_results.size(), 3u);
- // Multiple results should be available.
- EXPECT_GT(search_results.size(), 0u);
+ // Limit results to 1 max and ensure that only 1 result is returned.
+ mojom::SearchHandlerAsyncWaiter(handler_remote_.get())
+ .Search(base::ASCIIToUTF16("Print"),
+ /*max_num_results=*/1u,
+ mojom::ParentResultBehavior::kDoNotIncludeParentResults,
+ &search_results);
+ EXPECT_EQ(search_results.size(), 1u);
// Search for a query which should return no results.
mojom::SearchHandlerAsyncWaiter(handler_remote_.get())
- .Search(base::ASCIIToUTF16("QueryWithNoResults"), &search_results);
+ .Search(base::ASCIIToUTF16("QueryWithNoResults"),
+ /*max_num_results=*/3u,
+ mojom::ParentResultBehavior::kDoNotIncludeParentResults,
+ &search_results);
EXPECT_TRUE(search_results.empty());
// Remove printing search tags to registry and verify that no results are
// returned for "Printing".
- search_tag_registry_.RemoveSearchTags(GetPrintingSearchConcepts());
+ RemoveSearchTags(GetPrintingSearchConcepts());
mojom::SearchHandlerAsyncWaiter(handler_remote_.get())
- .Search(base::ASCIIToUTF16("Printing"), &search_results);
+ .Search(base::ASCIIToUTF16("Print"),
+ /*max_num_results=*/3u,
+ mojom::ParentResultBehavior::kDoNotIncludeParentResults,
+ &search_results);
EXPECT_TRUE(search_results.empty());
+ EXPECT_EQ(2u, observer_.num_calls());
+}
+
+TEST_F(SearchHandlerTest, UrlModification) {
+ // Add printing search tags to registry and search for "Saved".
+ AddSearchTags(GetPrintingSearchConcepts());
+ std::vector<mojom::SearchResultPtr> search_results;
+ mojom::SearchHandlerAsyncWaiter(handler_remote_.get())
+ .Search(base::ASCIIToUTF16("Saved"),
+ /*max_num_results=*/3u,
+ mojom::ParentResultBehavior::kDoNotIncludeParentResults,
+ &search_results);
+
+ // Only the "saved printers" item should be returned.
+ EXPECT_EQ(search_results.size(), 1u);
+
+ // The URL should have bee modified according to the FakeOsSettingSection
+ // scheme.
+ EXPECT_EQ(
+ std::string("Section::kPrinting::") + mojom::kPrintingDetailsSubpagePath,
+ search_results[0]->url_path_with_parameters);
+}
+
+TEST_F(SearchHandlerTest, AltTagMatch) {
+ // Add printing search tags to registry.
+ AddSearchTags(GetPrintingSearchConcepts());
+ std::vector<mojom::SearchResultPtr> search_results;
+
+ // Search for "CUPS". The IDS_OS_SETTINGS_TAG_PRINTING result has an alternate
+ // tag "CUPS" (referring to the Unix printing protocol), so we should receive
+ // one match.
+ mojom::SearchHandlerAsyncWaiter(handler_remote_.get())
+ .Search(base::ASCIIToUTF16("CUPS"),
+ /*max_num_results=*/3u,
+ mojom::ParentResultBehavior::kDoNotIncludeParentResults,
+ &search_results);
+ EXPECT_EQ(search_results.size(), 1u);
+
+ // Verify the result text and canonical restult text.
+ EXPECT_EQ(l10n_util::GetStringUTF16(IDS_OS_SETTINGS_TAG_PRINTING_ALT2),
+ search_results[0]->result_text);
+ EXPECT_EQ(l10n_util::GetStringUTF16(IDS_OS_SETTINGS_TAG_PRINTING),
+ search_results[0]->canonical_result_text);
+}
+
+TEST_F(SearchHandlerTest, AllowParentResult) {
+ // Add printing search tags to registry.
+ AddSearchTags(GetPrintingSearchConcepts());
+ std::vector<mojom::SearchResultPtr> search_results;
+
+ // Search for "Saved", which should only apply to the "saved printers" item.
+ // Pass the kAllowParentResults flag, which should also cause its parent
+ // subpage item to be returned.
+ mojom::SearchHandlerAsyncWaiter(handler_remote_.get())
+ .Search(base::ASCIIToUTF16("Saved"),
+ /*max_num_results=*/3u,
+ mojom::ParentResultBehavior::kAllowParentResults,
+ &search_results);
+ EXPECT_EQ(search_results.size(), 2u);
+ EXPECT_FALSE(search_results[1]->was_generated_from_text_match);
+}
+
+TEST_F(SearchHandlerTest, DefaultRank) {
+ // Add printing search tags to registry.
+ AddSearchTags(GetPrintingSearchConcepts());
+ std::vector<mojom::SearchResultPtr> search_results;
+
+ // Search for "Print". Only the IDS_OS_SETTINGS_TAG_PRINTING result
+ // contains the word "Printing", but the other results have the similar word
+ // "Printer". Thus, "Printing" has a higher relevance score.
+ mojom::SearchHandlerAsyncWaiter(handler_remote_.get())
+ .Search(base::ASCIIToUTF16("Print"),
+ /*max_num_results=*/3u,
+ mojom::ParentResultBehavior::kAllowParentResults,
+ &search_results);
+ EXPECT_EQ(search_results.size(), 3u);
+
+ // Since the IDS_OS_SETTINGS_TAG_PRINTING result has a default rank of kLow,
+ // it should be the *last* result returned even though it has a higher
+ // relevance score.
+ EXPECT_EQ(l10n_util::GetStringUTF16(IDS_OS_SETTINGS_TAG_PRINTING),
+ search_results[2]->result_text);
+}
+
+// Regression test for https://crbug.com/1090184.
+TEST_F(SearchHandlerTest, CompareSearchResults) {
+ // Create two equal dummy results.
+ mojom::SearchResultPtr a = CreateDummyResult();
+ mojom::SearchResultPtr b = CreateDummyResult();
+
+ // CompareSearchResults() returns whether |a| < |b|; since they are equal, it
+ // should return false regardless of the order of parameters.
+ EXPECT_FALSE(SearchHandler::CompareSearchResults(a, b));
+ EXPECT_FALSE(SearchHandler::CompareSearchResults(b, a));
+
+ // Differ only on default rank.
+ a = CreateDummyResult();
+ a->default_rank = mojom::SearchResultDefaultRank::kLow;
+ b = CreateDummyResult();
+ b->default_rank = mojom::SearchResultDefaultRank::kHigh;
+
+ // Comparison value should differ.
+ EXPECT_NE(SearchHandler::CompareSearchResults(b, a),
+ SearchHandler::CompareSearchResults(a, b));
+
+ // Differ only on relevance score.
+ a = CreateDummyResult();
+ a->relevance_score = 0;
+ b = CreateDummyResult();
+ b->relevance_score = 1;
+
+ // Comparison value should differ.
+ EXPECT_NE(SearchHandler::CompareSearchResults(b, a),
+ SearchHandler::CompareSearchResults(a, b));
+
+ // Differ only on type.
+ a = CreateDummyResult();
+ a->type = mojom::SearchResultType::kSection;
+ b = CreateDummyResult();
+ b->type = mojom::SearchResultType::kSubpage;
+
+ // Comparison value should differ.
+ EXPECT_NE(SearchHandler::CompareSearchResults(b, a),
+ SearchHandler::CompareSearchResults(a, b));
}
} // namespace settings
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
index 5f5b099b176..6be31452dc6 100644
--- 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
@@ -30,6 +30,7 @@ enum SearchResultIcon {
kMagnifyingGlass,
kMessages,
kMouse,
+ kNearbyShare,
kPaintbrush,
kPenguin,
kPhone,
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.cc
index e3b1b3a7b24..618022b76ba 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.cc
@@ -4,9 +4,11 @@
#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h"
+#include <algorithm>
+#include <sstream>
+
#include "base/feature_list.h"
#include "base/strings/string_number_conversions.h"
-#include "chrome/browser/chromeos/local_search_service/index.h"
#include "chrome/browser/chromeos/local_search_service/local_search_service.h"
#include "chrome/browser/ui/webui/settings/chromeos/search/search_concept.h"
#include "chromeos/constants/chromeos_features.h"
@@ -16,36 +18,85 @@ namespace chromeos {
namespace settings {
namespace {
-std::vector<local_search_service::Data> ConceptVectorToDataVector(
- const std::vector<SearchConcept>& search_tags) {
- std::vector<local_search_service::Data> data_list;
-
- for (const auto& concept : search_tags) {
- 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));
- }
+std::vector<int> GetMessageIds(const SearchConcept* concept) {
+ // Start with only the canonical ID.
+ std::vector<int> alt_tag_message_ids{concept->canonical_message_id};
- // Note: A stringified version of the canonical tag message ID is used as
- // the identifier for this search data.
- data_list.emplace_back(base::NumberToString(concept.canonical_message_id),
- search_tags);
+ // Add alternate IDs, if they exist.
+ for (size_t i = 0; i < SearchConcept::kMaxAltTagsPerConcept; ++i) {
+ int curr_alt_tag_message_id = concept->alt_tag_ids[i];
+ if (curr_alt_tag_message_id == SearchConcept::kAltTagEnd)
+ break;
+ alt_tag_message_ids.push_back(curr_alt_tag_message_id);
}
- return data_list;
+ return alt_tag_message_ids;
}
} // namespace
+SearchTagRegistry::ScopedTagUpdater::ScopedTagUpdater(
+ SearchTagRegistry* registry)
+ : registry_(registry) {}
+
+SearchTagRegistry::ScopedTagUpdater::ScopedTagUpdater(ScopedTagUpdater&&) =
+ default;
+
+SearchTagRegistry::ScopedTagUpdater::~ScopedTagUpdater() {
+ std::vector<const SearchConcept*> pending_adds;
+ std::vector<const SearchConcept*> pending_removals;
+
+ for (const auto& map_entry : pending_updates_) {
+ const std::string& result_id = map_entry.first;
+ const SearchConcept* concept = map_entry.second.first;
+ bool is_pending_add = map_entry.second.second;
+
+ // If tag metadata is present for this tag, it has already been added and is
+ // present in LocalSearchService.
+ bool is_concept_already_added =
+ registry_->GetTagMetadata(result_id) != nullptr;
+
+ // Only add concepts which are intended to be added and have not yet been
+ // added; only remove concepts which are intended to be removed and have
+ // already been added.
+ if (is_pending_add && !is_concept_already_added)
+ pending_adds.push_back(concept);
+ if (!is_pending_add && is_concept_already_added)
+ pending_removals.push_back(concept);
+ }
+
+ if (!pending_adds.empty())
+ registry_->AddSearchTags(pending_adds);
+ if (!pending_removals.empty())
+ registry_->RemoveSearchTags(pending_removals);
+}
+
+void SearchTagRegistry::ScopedTagUpdater::AddSearchTags(
+ const std::vector<SearchConcept>& search_tags) {
+ ProcessPendingSearchTags(search_tags, /*is_pending_add=*/true);
+}
+
+void SearchTagRegistry::ScopedTagUpdater::RemoveSearchTags(
+ const std::vector<SearchConcept>& search_tags) {
+ ProcessPendingSearchTags(search_tags, /*is_pending_add=*/false);
+}
+
+void SearchTagRegistry::ScopedTagUpdater::ProcessPendingSearchTags(
+ const std::vector<SearchConcept>& search_tags,
+ bool is_pending_add) {
+ for (const auto& concept : search_tags) {
+ std::string result_id = ToResultId(concept);
+ auto it = pending_updates_.find(result_id);
+ if (it == pending_updates_.end()) {
+ pending_updates_.emplace(std::piecewise_construct,
+ std::forward_as_tuple(result_id),
+ std::forward_as_tuple(&concept, is_pending_add));
+ } else {
+ it->second.second = is_pending_add;
+ }
+ }
+}
+
SearchTagRegistry::SearchTagRegistry(
local_search_service::LocalSearchService* local_search_service)
: index_(local_search_service->GetIndex(
@@ -53,8 +104,20 @@ SearchTagRegistry::SearchTagRegistry(
SearchTagRegistry::~SearchTagRegistry() = default;
+void SearchTagRegistry::AddObserver(Observer* observer) {
+ observer_list_.AddObserver(observer);
+}
+
+void SearchTagRegistry::RemoveObserver(Observer* observer) {
+ observer_list_.RemoveObserver(observer);
+}
+
+SearchTagRegistry::ScopedTagUpdater SearchTagRegistry::StartUpdate() {
+ return ScopedTagUpdater(this);
+}
+
void SearchTagRegistry::AddSearchTags(
- const std::vector<SearchConcept>& search_tags) {
+ const std::vector<const SearchConcept*>& search_tags) {
if (!base::FeatureList::IsEnabled(features::kNewOsSettingsSearch))
return;
@@ -63,31 +126,82 @@ void SearchTagRegistry::AddSearchTags(
// 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 : search_tags)
- canonical_id_to_metadata_map_[concept.canonical_message_id] = &concept;
+ for (const auto* concept : search_tags)
+ result_id_to_metadata_list_map_[ToResultId(*concept)] = concept;
+
+ NotifyRegistryUpdated();
}
void SearchTagRegistry::RemoveSearchTags(
- const std::vector<SearchConcept>& search_tags) {
+ const std::vector<const SearchConcept*>& search_tags) {
if (!base::FeatureList::IsEnabled(features::kNewOsSettingsSearch))
return;
- std::vector<std::string> ids;
- for (const auto& concept : search_tags) {
- canonical_id_to_metadata_map_.erase(concept.canonical_message_id);
- ids.push_back(base::NumberToString(concept.canonical_message_id));
+ std::vector<std::string> data_ids;
+ for (const auto* concept : search_tags) {
+ std::string result_id = ToResultId(*concept);
+ result_id_to_metadata_list_map_.erase(result_id);
+ data_ids.push_back(std::move(result_id));
}
- index_->Delete(ids);
+ index_->Delete(data_ids);
+
+ NotifyRegistryUpdated();
}
-const SearchConcept* SearchTagRegistry::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())
+const SearchConcept* SearchTagRegistry::GetTagMetadata(
+ const std::string& result_id) const {
+ const auto it = result_id_to_metadata_list_map_.find(result_id);
+ if (it == result_id_to_metadata_list_map_.end())
return nullptr;
return it->second;
}
+// static
+std::string SearchTagRegistry::ToResultId(const SearchConcept& concept) {
+ std::stringstream ss;
+ switch (concept.type) {
+ case mojom::SearchResultType::kSection:
+ ss << concept.id.section;
+ break;
+ case mojom::SearchResultType::kSubpage:
+ ss << concept.id.subpage;
+ break;
+ case mojom::SearchResultType::kSetting:
+ ss << concept.id.setting;
+ break;
+ }
+ ss << "," << concept.canonical_message_id;
+ return ss.str();
+}
+
+std::vector<local_search_service::Data>
+SearchTagRegistry::ConceptVectorToDataVector(
+ const std::vector<const SearchConcept*>& search_tags) {
+ std::vector<local_search_service::Data> data_list;
+
+ for (const auto* concept : search_tags) {
+ // Create a list of Content objects, which use the stringified version of
+ // message IDs as identifiers.
+ std::vector<local_search_service::Content> content_list;
+ for (int message_id : GetMessageIds(concept)) {
+ content_list.emplace_back(
+ /*id=*/base::NumberToString(message_id),
+ /*content=*/l10n_util::GetStringUTF16(message_id));
+ }
+
+ // Compute an identifier for this result; the same ID format it used in
+ // GetTagMetadata().
+ data_list.emplace_back(ToResultId(*concept), std::move(content_list));
+ }
+
+ return data_list;
+}
+
+void SearchTagRegistry::NotifyRegistryUpdated() {
+ for (auto& observer : observer_list_)
+ observer.OnRegistryUpdated();
+}
+
} // namespace settings
} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h
index c1c7a947f87..abd1f83b1fa 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h
@@ -6,8 +6,13 @@
#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_TAG_REGISTRY_H_
#include <unordered_map>
+#include <utility>
#include <vector>
+#include "base/gtest_prod_util.h"
+#include "base/observer_list.h"
+#include "base/observer_list_types.h"
+#include "chrome/browser/chromeos/local_search_service/index.h"
#include "chrome/browser/ui/webui/settings/chromeos/os_settings_section.h"
namespace local_search_service {
@@ -21,27 +26,82 @@ namespace settings {
struct SearchConcept;
// Processes all registered search tags by adding/removing them from
-// LocalSearchService and providing metadata via GetCanonicalTagMetadata().
+// LocalSearchService and providing metadata via GetTagMetadata().
class SearchTagRegistry {
public:
+ class Observer : public base::CheckedObserver {
+ public:
+ ~Observer() override = default;
+ virtual void OnRegistryUpdated() = 0;
+ };
+
+ class ScopedTagUpdater {
+ public:
+ ScopedTagUpdater(ScopedTagUpdater&&);
+ ScopedTagUpdater(const ScopedTagUpdater&) = delete;
+ ScopedTagUpdater& operator=(const ScopedTagUpdater&) = delete;
+ ~ScopedTagUpdater();
+
+ void AddSearchTags(const std::vector<SearchConcept>& search_tags);
+ void RemoveSearchTags(const std::vector<SearchConcept>& search_tags);
+
+ private:
+ friend class SearchTagRegistry;
+
+ explicit ScopedTagUpdater(SearchTagRegistry* registry);
+
+ void ProcessPendingSearchTags(const std::vector<SearchConcept>& search_tags,
+ bool is_pending_add);
+
+ SearchTagRegistry* registry_;
+
+ // A SearchConcept along with a bool of the pending update state. If the
+ // bool is true, the concept should be added; if the bool is false, the
+ // concept should be removed.
+ using ConceptWithShouldAddBool = std::pair<const SearchConcept*, bool>;
+ std::unordered_map<std::string, ConceptWithShouldAddBool> pending_updates_;
+ };
+
SearchTagRegistry(
local_search_service::LocalSearchService* local_search_service);
SearchTagRegistry(const SearchTagRegistry& other) = delete;
SearchTagRegistry& operator=(const SearchTagRegistry& other) = delete;
virtual ~SearchTagRegistry();
- void AddSearchTags(const std::vector<SearchConcept>& search_tags);
- void RemoveSearchTags(const std::vector<SearchConcept>& search_tags);
+ void AddObserver(Observer* observer);
+ void RemoveObserver(Observer* observer);
- // Returns the tag metadata associated with |canonical_message_id|, which must
- // be one of the canonical IDS_OS_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;
+ // Starts a tag update, which allows clients to add/remove search tags. The
+ // ScopedTagUpdater object is returned by value and only updates tags when it
+ // goes out of scope, so clients should not hold onto it outside the scope of
+ // a function.
+ ScopedTagUpdater StartUpdate();
+ // Returns the tag metadata associated with |result_id|, which is the ID
+ // returned by the LocalSearchService. If no metadata is available, null is
+ // returned.
+ const SearchConcept* GetTagMetadata(const std::string& result_id) const;
private:
+ FRIEND_TEST_ALL_PREFIXES(SearchTagRegistryTest, AddAndRemove);
+
+ static std::string ToResultId(const SearchConcept& concept);
+
+ void AddSearchTags(const std::vector<const SearchConcept*>& search_tags);
+ void RemoveSearchTags(const std::vector<const SearchConcept*>& search_tags);
+
+ std::vector<local_search_service::Data> ConceptVectorToDataVector(
+ const std::vector<const SearchConcept*>& search_tags);
+ void NotifyRegistryUpdated();
+
+ // Index used by the LocalSearchService for string matching.
local_search_service::Index* index_;
- std::unordered_map<int, const SearchConcept*> canonical_id_to_metadata_map_;
+
+ // In-memory cache of all results which have been added to the
+ // LocalSearchService. Contents are kept in sync with |index_|.
+ std::unordered_map<std::string, const SearchConcept*>
+ result_id_to_metadata_list_map_;
+
+ base::ObserverList<Observer> observer_list_;
};
} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry_unittest.cc
index 6eff74b2583..1aebe00ce35 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry_unittest.cc
@@ -5,19 +5,31 @@
#include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h"
#include "base/no_destructor.h"
-#include "base/test/scoped_feature_list.h"
#include "chrome/browser/chromeos/local_search_service/index.h"
#include "chrome/browser/chromeos/local_search_service/local_search_service.h"
#include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h"
#include "chrome/browser/ui/webui/settings/chromeos/search/search_concept.h"
#include "chrome/grit/generated_resources.h"
-#include "chromeos/constants/chromeos_features.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chromeos {
namespace settings {
namespace {
+class FakeObserver : public SearchTagRegistry::Observer {
+ public:
+ FakeObserver() = default;
+ ~FakeObserver() override = default;
+
+ size_t num_calls() const { return num_calls_; }
+
+ private:
+ // SearchTagRegistry::Observer:
+ void OnRegistryUpdated() override { ++num_calls_; }
+
+ size_t num_calls_ = 0;
+};
+
// Note: Copied from printing_section.cc but does not need to stay in sync with
// it.
const std::vector<SearchConcept>& GetPrintingSearchConcepts() {
@@ -27,10 +39,7 @@ const std::vector<SearchConcept>& GetPrintingSearchConcepts() {
mojom::SearchResultIcon::kPrinter,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
- {.setting = mojom::Setting::kAddPrinter},
- {IDS_OS_SETTINGS_TAG_PRINTING_ADD_PRINTER_ALT1,
- IDS_OS_SETTINGS_TAG_PRINTING_ADD_PRINTER_ALT2,
- SearchConcept::kAltTagEnd}},
+ {.setting = mojom::Setting::kAddPrinter}},
{IDS_OS_SETTINGS_TAG_PRINTING_SAVED_PRINTERS,
mojom::kPrintingDetailsSubpagePath,
mojom::SearchResultIcon::kPrinter,
@@ -40,7 +49,7 @@ const std::vector<SearchConcept>& GetPrintingSearchConcepts() {
{IDS_OS_SETTINGS_TAG_PRINTING,
mojom::kPrintingDetailsSubpagePath,
mojom::SearchResultIcon::kPrinter,
- mojom::SearchResultDefaultRank::kHigh,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
{.subpage = mojom::Subpage::kPrintingDetails},
{IDS_OS_SETTINGS_TAG_PRINTING_ALT1, IDS_OS_SETTINGS_TAG_PRINTING_ALT2,
@@ -58,37 +67,61 @@ class SearchTagRegistryTest : public testing::Test {
// testing::Test:
void SetUp() override {
- scoped_feature_list_.InitAndEnableFeature(
- chromeos::features::kNewOsSettingsSearch);
+ search_tag_registry_.AddObserver(&observer_);
index_ = local_search_service_.GetIndex(
local_search_service::IndexId::kCrosSettings);
}
- base::test::ScopedFeatureList scoped_feature_list_;
+ void TearDown() override { search_tag_registry_.RemoveObserver(&observer_); }
+
local_search_service::LocalSearchService local_search_service_;
SearchTagRegistry search_tag_registry_;
+ FakeObserver observer_;
local_search_service::Index* index_;
};
TEST_F(SearchTagRegistryTest, AddAndRemove) {
// Add search tags; size of the index should increase.
- search_tag_registry_.AddSearchTags(GetPrintingSearchConcepts());
+ {
+ SearchTagRegistry::ScopedTagUpdater updater =
+ search_tag_registry_.StartUpdate();
+ updater.AddSearchTags(GetPrintingSearchConcepts());
+
+ // Nothing should have happened yet, since |updater| has not gone out of
+ // scope.
+ EXPECT_EQ(0u, index_->GetSize());
+ EXPECT_EQ(0u, observer_.num_calls());
+ }
+ // Now that it went out of scope, the update should have occurred.
EXPECT_EQ(3u, index_->GetSize());
+ EXPECT_EQ(1u, observer_.num_calls());
- // Tags added should be available via GetCanonicalTagMetadata().
+ std::string first_tag_id =
+ SearchTagRegistry::ToResultId(GetPrintingSearchConcepts()[0]);
+
+ // Tags added should be available via GetTagMetadata().
const SearchConcept* add_printer_concept =
- search_tag_registry_.GetCanonicalTagMetadata(
- IDS_OS_SETTINGS_TAG_PRINTING_ADD_PRINTER);
+ search_tag_registry_.GetTagMetadata(first_tag_id);
ASSERT_TRUE(add_printer_concept);
EXPECT_EQ(mojom::Setting::kAddPrinter, add_printer_concept->id.setting);
// Remove search tag; size should go back to 0.
- search_tag_registry_.RemoveSearchTags(GetPrintingSearchConcepts());
+ {
+ SearchTagRegistry::ScopedTagUpdater updater =
+ search_tag_registry_.StartUpdate();
+ updater.RemoveSearchTags(GetPrintingSearchConcepts());
+
+ // Tags should not have been removed yet, since |updater| has not gone out
+ // of scope.
+ EXPECT_EQ(3u, index_->GetSize());
+ EXPECT_EQ(1u, observer_.num_calls());
+ }
+ // Now that it went out of scope, the update should have occurred.
EXPECT_EQ(0u, index_->GetSize());
+ EXPECT_EQ(2u, observer_.num_calls());
- // The tag should no longer be accessible via GetCanonicalTagMetadata().
- add_printer_concept = search_tag_registry_.GetCanonicalTagMetadata(
- IDS_OS_SETTINGS_TAG_PRINTING_ADD_PRINTER);
+ // The tag should no longer be accessible via GetTagMetadata().
+ add_printer_concept = search_tag_registry_.GetTagMetadata(first_tag_id);
ASSERT_FALSE(add_printer_concept);
}
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/search_section.cc
index 958071d8716..6f8763df333 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/search_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search_section.cc
@@ -9,6 +9,7 @@
#include "ash/public/cpp/assistant/assistant_state.h"
#include "base/no_destructor.h"
+#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chromeos/assistant/assistant_util.h"
#include "chrome/browser/profiles/profile.h"
@@ -19,10 +20,14 @@
#include "chrome/browser/ui/webui/webui_util.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/generated_resources.h"
+#include "chromeos/components/quick_answers/quick_answers_client.h"
#include "chromeos/constants/chromeos_features.h"
#include "chromeos/services/assistant/public/cpp/assistant_prefs.h"
#include "chromeos/services/assistant/public/cpp/features.h"
+#include "components/language/core/browser/pref_names.h"
+#include "components/prefs/pref_service.h"
#include "content/public/browser/web_ui_data_source.h"
+#include "third_party/icu/source/common/unicode/locid.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/webui/web_ui_util.h"
#include "ui/chromeos/devicetype_utils.h"
@@ -48,60 +53,45 @@ const std::vector<SearchConcept>& GetAssistantSearchConcepts() {
{IDS_OS_SETTINGS_TAG_ASSISTANT,
mojom::kAssistantSubpagePath,
mojom::SearchResultIcon::kAssistant,
- mojom::SearchResultDefaultRank::kHigh,
+ mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
{.subpage = mojom::Subpage::kAssistant}},
- {IDS_OS_SETTINGS_TAG_ASSISTANT_QUICK_ANSWERS,
+ });
+ return *tags;
+}
+
+const std::vector<SearchConcept>& GetAssistantOnSearchConcepts() {
+ static const base::NoDestructor<std::vector<SearchConcept>> tags({
+ {IDS_OS_SETTINGS_TAG_ASSISTANT_TURN_OFF,
mojom::kAssistantSubpagePath,
mojom::SearchResultIcon::kAssistant,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
- {.setting = mojom::Setting::kAssistantQuickAnswers}},
+ {.setting = mojom::Setting::kAssistantOnOff},
+ {IDS_OS_SETTINGS_TAG_ASSISTANT_TURN_OFF_ALT1,
+ SearchConcept::kAltTagEnd}},
{IDS_OS_SETTINGS_TAG_ASSISTANT_PREFERRED_INPUT,
mojom::kAssistantSubpagePath,
mojom::SearchResultIcon::kAssistant,
- mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultDefaultRank::kLow,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kAssistantVoiceInput}},
- {IDS_OS_SETTINGS_TAG_ASSISTANT_OK_GOOGLE,
- mojom::kAssistantSubpagePath,
- mojom::SearchResultIcon::kAssistant,
- mojom::SearchResultDefaultRank::kMedium,
- mojom::SearchResultType::kSetting,
- {.setting = mojom::Setting::kAssistantOkGoogle},
- {IDS_OS_SETTINGS_TAG_ASSISTANT_OK_GOOGLE_ALT1,
- IDS_OS_SETTINGS_TAG_ASSISTANT_OK_GOOGLE_ALT2,
- SearchConcept::kAltTagEnd}},
{IDS_OS_SETTINGS_TAG_ASSISTANT_NOTIFICATIONS,
mojom::kAssistantSubpagePath,
mojom::SearchResultIcon::kAssistant,
- mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultDefaultRank::kLow,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kAssistantNotifications}},
{IDS_OS_SETTINGS_TAG_ASSISTANT_RELATED_INFO,
mojom::kAssistantSubpagePath,
mojom::SearchResultIcon::kAssistant,
- mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultDefaultRank::kLow,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kAssistantRelatedInfo}},
});
return *tags;
}
-const std::vector<SearchConcept>& GetAssistantOnSearchConcepts() {
- static const base::NoDestructor<std::vector<SearchConcept>> tags({
- {IDS_OS_SETTINGS_TAG_ASSISTANT_TURN_OFF,
- mojom::kAssistantSubpagePath,
- mojom::SearchResultIcon::kAssistant,
- mojom::SearchResultDefaultRank::kMedium,
- mojom::SearchResultType::kSetting,
- {.setting = mojom::Setting::kAssistantOnOff},
- {IDS_OS_SETTINGS_TAG_ASSISTANT_TURN_OFF_ALT1,
- SearchConcept::kAltTagEnd}},
- });
- return *tags;
-}
-
const std::vector<SearchConcept>& GetAssistantOffSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
{IDS_OS_SETTINGS_TAG_ASSISTANT_TURN_ON,
@@ -117,21 +107,39 @@ const std::vector<SearchConcept>& GetAssistantOffSearchConcepts() {
const std::vector<SearchConcept>& GetAssistantQuickAnswersSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
- // TODO(khorimoto): Add "Assistant Quick Answers" search concepts.
+ {IDS_OS_SETTINGS_TAG_ASSISTANT_QUICK_ANSWERS,
+ mojom::kAssistantSubpagePath,
+ mojom::SearchResultIcon::kAssistant,
+ mojom::SearchResultDefaultRank::kLow,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kAssistantQuickAnswers}},
});
return *tags;
}
const std::vector<SearchConcept>& GetAssistantHotwordDspSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
- // TODO(khorimoto): Add "Assistant hotword DSP" search concepts.
+ {IDS_OS_SETTINGS_TAG_ASSISTANT_OK_GOOGLE,
+ mojom::kAssistantSubpagePath,
+ mojom::SearchResultIcon::kAssistant,
+ mojom::SearchResultDefaultRank::kLow,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kAssistantOkGoogle},
+ {IDS_OS_SETTINGS_TAG_ASSISTANT_OK_GOOGLE_ALT1,
+ IDS_OS_SETTINGS_TAG_ASSISTANT_OK_GOOGLE_ALT2,
+ SearchConcept::kAltTagEnd}},
});
return *tags;
}
const std::vector<SearchConcept>& GetAssistantVoiceMatchSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
- // TODO(khorimoto): Add "Assistant hotword DSP" search concepts.
+ {IDS_OS_SETTINGS_TAG_ASSISTANT_TRAIN_VOICE_MODEL,
+ mojom::kAssistantSubpagePath,
+ mojom::SearchResultIcon::kAssistant,
+ mojom::SearchResultDefaultRank::kLow,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kTrainAssistantVoiceModel}},
});
return *tags;
}
@@ -140,10 +148,6 @@ bool IsVoiceMatchAllowed() {
return !assistant::features::IsVoiceMatchDisabled();
}
-bool AreQuickAnswersAllowed() {
- return features::IsQuickAnswersSettingToggleEnabled();
-}
-
void AddGoogleAssistantStrings(content::WebUIDataSource* html_source) {
static constexpr webui::LocalizedString kLocalizedStrings[] = {
{"googleAssistantPageTitle", IDS_SETTINGS_GOOGLE_ASSISTANT},
@@ -186,7 +190,6 @@ void AddGoogleAssistantStrings(content::WebUIDataSource* html_source) {
html_source->AddBoolean("hotwordDspAvailable", IsHotwordDspAvailable());
html_source->AddBoolean("voiceMatchDisabled", !IsVoiceMatchAllowed());
- html_source->AddBoolean("quickAnswersAvailable", AreQuickAnswersAllowed());
}
} // namespace
@@ -194,11 +197,12 @@ void AddGoogleAssistantStrings(content::WebUIDataSource* html_source) {
SearchSection::SearchSection(Profile* profile,
SearchTagRegistry* search_tag_registry)
: OsSettingsSection(profile, search_tag_registry) {
- registry()->AddSearchTags(GetSearchPageSearchConcepts());
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+ updater.AddSearchTags(GetSearchPageSearchConcepts());
ash::AssistantState* assistant_state = ash::AssistantState::Get();
if (IsAssistantAllowed() && assistant_state) {
- registry()->AddSearchTags(GetAssistantSearchConcepts());
+ updater.AddSearchTags(GetAssistantSearchConcepts());
assistant_state->AddObserver(this);
UpdateAssistantSearchTags();
@@ -226,6 +230,7 @@ void SearchSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
const bool is_assistant_allowed = IsAssistantAllowed();
html_source->AddBoolean("isAssistantAllowed", is_assistant_allowed);
+ html_source->AddBoolean("quickAnswersAvailable", IsQuickAnswersAllowed());
html_source->AddLocalizedString("osSearchPageTitle",
is_assistant_allowed
? IDS_SETTINGS_SEARCH_AND_ASSISTANT
@@ -248,6 +253,44 @@ void SearchSection::AddHandlers(content::WebUI* web_ui) {
std::make_unique<chromeos::settings::GoogleAssistantHandler>());
}
+int SearchSection::GetSectionNameMessageId() const {
+ return IsAssistantAllowed() ? IDS_SETTINGS_SEARCH_AND_ASSISTANT
+ : IDS_SETTINGS_SEARCH;
+}
+
+mojom::Section SearchSection::GetSection() const {
+ return mojom::Section::kSearchAndAssistant;
+}
+
+mojom::SearchResultIcon SearchSection::GetSectionIcon() const {
+ return mojom::SearchResultIcon::kMagnifyingGlass;
+}
+
+std::string SearchSection::GetSectionPath() const {
+ return mojom::kSearchAndAssistantSectionPath;
+}
+
+void SearchSection::RegisterHierarchy(HierarchyGenerator* generator) const {
+ generator->RegisterTopLevelSetting(mojom::Setting::kPreferredSearchEngine);
+
+ // Assistant.
+ generator->RegisterTopLevelSubpage(
+ IDS_SETTINGS_GOOGLE_ASSISTANT, mojom::Subpage::kAssistant,
+ mojom::SearchResultIcon::kAssistant,
+ mojom::SearchResultDefaultRank::kMedium, mojom::kAssistantSubpagePath);
+ static constexpr mojom::Setting kAssistantSettings[] = {
+ mojom::Setting::kAssistantOnOff,
+ mojom::Setting::kAssistantRelatedInfo,
+ mojom::Setting::kAssistantQuickAnswers,
+ mojom::Setting::kAssistantOkGoogle,
+ mojom::Setting::kAssistantNotifications,
+ mojom::Setting::kAssistantVoiceInput,
+ mojom::Setting::kTrainAssistantVoiceModel,
+ };
+ RegisterNestedSettingBulk(mojom::Subpage::kAssistant, kAssistantSettings,
+ generator);
+}
+
void SearchSection::OnAssistantConsentStatusChanged(int consent_status) {
UpdateAssistantSearchTags();
}
@@ -264,19 +307,40 @@ void SearchSection::OnAssistantHotwordEnabled(bool enabled) {
UpdateAssistantSearchTags();
}
-bool SearchSection::IsAssistantAllowed() {
+bool SearchSection::IsAssistantAllowed() const {
// NOTE: This will be false when the flag is disabled.
return ::assistant::IsAssistantAllowedForProfile(profile()) ==
chromeos::assistant::AssistantAllowedState::ALLOWED;
}
+bool SearchSection::IsQuickAnswersAllowed() const {
+ if (!features::IsQuickAnswersSettingToggleEnabled())
+ return false;
+
+ const PrefService* prefs = profile()->GetPrefs();
+ std::string pref_locale =
+ prefs->GetString(language::prefs::kApplicationLocale);
+ // Also accept runtime locale which maybe an approximation of user's pref
+ // locale.
+ const std::string kRuntimeLocale = icu::Locale::getDefault().getName();
+
+ base::ReplaceChars(pref_locale, "-", "_", &pref_locale);
+ if (!::chromeos::quick_answers::QuickAnswersClient::
+ IsQuickAnswersAllowedForLocale(pref_locale, kRuntimeLocale))
+ return false;
+
+ return true;
+}
+
void SearchSection::UpdateAssistantSearchTags() {
+ SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
+
// Start without any Assistant search concepts, then add if needed below.
- registry()->RemoveSearchTags(GetAssistantOnSearchConcepts());
- registry()->RemoveSearchTags(GetAssistantOffSearchConcepts());
- registry()->RemoveSearchTags(GetAssistantQuickAnswersSearchConcepts());
- registry()->RemoveSearchTags(GetAssistantHotwordDspSearchConcepts());
- registry()->RemoveSearchTags(GetAssistantVoiceMatchSearchConcepts());
+ updater.RemoveSearchTags(GetAssistantOnSearchConcepts());
+ updater.RemoveSearchTags(GetAssistantOffSearchConcepts());
+ updater.RemoveSearchTags(GetAssistantQuickAnswersSearchConcepts());
+ updater.RemoveSearchTags(GetAssistantHotwordDspSearchConcepts());
+ updater.RemoveSearchTags(GetAssistantVoiceMatchSearchConcepts());
ash::AssistantState* assistant_state = ash::AssistantState::Get();
@@ -284,26 +348,26 @@ void SearchSection::UpdateAssistantSearchTags() {
// off, none of the sub-features are enabled.
if (!assistant_state->settings_enabled() ||
!assistant_state->settings_enabled().value()) {
- registry()->AddSearchTags(GetAssistantOffSearchConcepts());
+ updater.AddSearchTags(GetAssistantOffSearchConcepts());
return;
}
- registry()->AddSearchTags(GetAssistantOnSearchConcepts());
+ updater.AddSearchTags(GetAssistantOnSearchConcepts());
- if (AreQuickAnswersAllowed() && assistant_state->context_enabled() &&
+ if (IsQuickAnswersAllowed() && assistant_state->context_enabled() &&
assistant_state->context_enabled().value()) {
- registry()->AddSearchTags(GetAssistantQuickAnswersSearchConcepts());
+ updater.AddSearchTags(GetAssistantQuickAnswersSearchConcepts());
}
if (IsHotwordDspAvailable())
- registry()->AddSearchTags(GetAssistantHotwordDspSearchConcepts());
+ updater.AddSearchTags(GetAssistantHotwordDspSearchConcepts());
if (IsVoiceMatchAllowed() && assistant_state->hotword_enabled() &&
assistant_state->hotword_enabled().value() &&
assistant_state->consent_status() &&
assistant_state->consent_status().value() ==
assistant::prefs::ConsentStatus::kActivityControlAccepted) {
- registry()->AddSearchTags(GetAssistantVoiceMatchSearchConcepts());
+ updater.AddSearchTags(GetAssistantVoiceMatchSearchConcepts());
}
}
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search_section.h b/chromium/chrome/browser/ui/webui/settings/chromeos/search_section.h
index d53c8d0e1ff..1de2bc61d26 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/search_section.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search_section.h
@@ -30,6 +30,11 @@ class SearchSection : public OsSettingsSection,
// OsSettingsSection:
void AddLoadTimeData(content::WebUIDataSource* html_source) override;
void AddHandlers(content::WebUI* web_ui) override;
+ int GetSectionNameMessageId() const override;
+ mojom::Section GetSection() const override;
+ mojom::SearchResultIcon GetSectionIcon() const override;
+ std::string GetSectionPath() const override;
+ void RegisterHierarchy(HierarchyGenerator* generator) const override;
// ash::AssistantStateObserver:
void OnAssistantConsentStatusChanged(int consent_status) override;
@@ -37,7 +42,8 @@ class SearchSection : public OsSettingsSection,
void OnAssistantSettingsEnabled(bool enabled) override;
void OnAssistantHotwordEnabled(bool enabled) override;
- bool IsAssistantAllowed();
+ bool IsAssistantAllowed() const;
+ bool IsQuickAnswersAllowed() const;
void UpdateAssistantSearchTags();
};
diff --git a/chromium/chrome/browser/ui/webui/settings/custom_home_pages_table_model.cc b/chromium/chrome/browser/ui/webui/settings/custom_home_pages_table_model.cc
index e2f4c5719c7..b3fd20ec805 100644
--- a/chromium/chrome/browser/ui/webui/settings/custom_home_pages_table_model.cc
+++ b/chromium/chrome/browser/ui/webui/settings/custom_home_pages_table_model.cc
@@ -45,9 +45,8 @@ struct CustomHomePagesTableModel::Entry {
CustomHomePagesTableModel::CustomHomePagesTableModel(Profile* profile)
: profile_(profile),
- observer_(NULL),
- num_outstanding_title_lookups_(0) {
-}
+ observer_(nullptr),
+ num_outstanding_title_lookups_(0) {}
CustomHomePagesTableModel::~CustomHomePagesTableModel() {
}
diff --git a/chromium/chrome/browser/ui/webui/settings/recent_site_settings_helper_unittest.cc b/chromium/chrome/browser/ui/webui/settings/recent_site_settings_helper_unittest.cc
index 7984c581713..8d765b17cbe 100644
--- a/chromium/chrome/browser/ui/webui/settings/recent_site_settings_helper_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/recent_site_settings_helper_unittest.cc
@@ -20,10 +20,8 @@ namespace {
ContentSetting kBlocked = ContentSetting::CONTENT_SETTING_BLOCK;
ContentSetting kAllowed = ContentSetting::CONTENT_SETTING_ALLOW;
ContentSetting kDefault = ContentSetting::CONTENT_SETTING_DEFAULT;
-site_settings::SiteSettingSource kEmbargo =
- site_settings::SiteSettingSource::kEmbargo;
-site_settings::SiteSettingSource kPreference =
- site_settings::SiteSettingSource::kPreference;
+SiteSettingSource kEmbargo = site_settings::SiteSettingSource::kEmbargo;
+SiteSettingSource kPreference = site_settings::SiteSettingSource::kPreference;
ContentSettingsType kNotifications = ContentSettingsType::NOTIFICATIONS;
ContentSettingsType kPlugins = ContentSettingsType::PLUGINS;
ContentSettingsType kPopups = ContentSettingsType::POPUPS;
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 fabe2039537..81877f13bcf 100644
--- a/chromium/chrome/browser/ui/webui/settings/safety_check_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/safety_check_handler.cc
@@ -455,6 +455,9 @@ base::string16 SafetyCheckHandler::GetStringForPasswords(
case PasswordsStatus::kError:
return l10n_util::GetStringUTF16(
IDS_SETTINGS_CHECK_PASSWORDS_ERROR_GENERIC);
+ case PasswordsStatus::kFeatureUnavailable:
+ return l10n_util::GetStringUTF16(
+ IDS_SETTINGS_SAFETY_CHECK_PASSWORDS_FEATURE_UNAVAILABLE);
}
}
@@ -571,6 +574,7 @@ void SafetyCheckHandler::DetermineIfNoPasswordsOrSafe(
void SafetyCheckHandler::OnVersionUpdaterResult(VersionUpdater::Status status,
int progress,
bool rollback,
+ bool powerwash,
const std::string& version,
int64_t update_size,
const base::string16& message) {
@@ -632,6 +636,9 @@ void SafetyCheckHandler::OnStateChanged(
Done(0), Total(0));
break;
case BulkLeakCheckService::State::kTokenRequestFailure:
+ OnPasswordsCheckResult(PasswordsStatus::kFeatureUnavailable,
+ Compromised(0), Done(0), Total(0));
+ break;
case BulkLeakCheckService::State::kHashingFailure:
case BulkLeakCheckService::State::kServiceError:
OnPasswordsCheckResult(PasswordsStatus::kError, Compromised(0), Done(0),
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 0c73407ae34..8e6d9336183 100644
--- a/chromium/chrome/browser/ui/webui/settings/safety_check_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/safety_check_handler.h
@@ -30,7 +30,7 @@
// software.
class SafetyCheckHandler
: public settings::SettingsPageUIHandler,
- public password_manager::BulkLeakCheckService::Observer,
+ public password_manager::BulkLeakCheckServiceInterface::Observer,
public safety_check::SafetyCheck::SafetyCheckHandlerInterface {
public:
// The following enum represent the state of the safety check parent
@@ -70,8 +70,9 @@ class SafetyCheckHandler
kSignedOut = 5,
kQuotaLimit = 6,
kError = 7,
+ kFeatureUnavailable = 8,
// New enum values must go above here.
- kMaxValue = kError,
+ kMaxValue = kFeatureUnavailable,
};
enum class ExtensionsStatus {
kChecking = 0,
@@ -192,6 +193,7 @@ class SafetyCheckHandler
void OnVersionUpdaterResult(VersionUpdater::Status status,
int progress,
bool rollback,
+ bool powerwash,
const std::string& version,
int64_t update_size,
const base::string16& message);
@@ -235,12 +237,12 @@ class SafetyCheckHandler
std::unique_ptr<safety_check::UpdateCheckHelper> update_helper_;
std::unique_ptr<VersionUpdater> version_updater_;
- password_manager::BulkLeakCheckService* leak_service_ = nullptr;
+ password_manager::BulkLeakCheckServiceInterface* 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>
+ ScopedObserver<password_manager::BulkLeakCheckServiceInterface,
+ password_manager::BulkLeakCheckServiceInterface::Observer>
observed_leak_check_{this};
base::WeakPtrFactory<SafetyCheckHandler> weak_ptr_factory_{this};
};
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 c6e18dd2c36..9a790eea198 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
@@ -793,6 +793,25 @@ TEST_F(SafetyCheckHandlerTest, CheckPasswords_Error) {
SafetyCheckHandler::PasswordsStatus::kError, 1);
}
+TEST_F(SafetyCheckHandlerTest, CheckPasswords_FeatureUnavailable) {
+ safety_check_->PerformSafetyCheck();
+ EXPECT_TRUE(test_passwords_delegate_.StartPasswordCheckTriggered());
+ static_cast<password_manager::BulkLeakCheckService::Observer*>(
+ safety_check_.get())
+ ->OnStateChanged(
+ password_manager::BulkLeakCheckService::State::kTokenRequestFailure);
+ const base::DictionaryValue* event =
+ GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(
+ SafetyCheckHandler::PasswordsStatus::kFeatureUnavailable));
+ ASSERT_TRUE(event);
+ VerifyDisplayString(event, "Password check is not available in Chromium");
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.PasswordsResult",
+ SafetyCheckHandler::PasswordsStatus::kFeatureUnavailable, 1);
+}
+
TEST_F(SafetyCheckHandlerTest, CheckPasswords_RunningOneCompromised) {
test_passwords_delegate_.SetNumCompromisedCredentials(1);
safety_check_->PerformSafetyCheck();
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 8335deec5b6..831c737b3fa 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
@@ -254,8 +254,8 @@ void ClearBrowsingDataHandler::HandleClearBrowsingData(
if (!prefs->GetBoolean(prefs::kClearPluginLSODataEnabled))
site_data_mask &= ~ChromeBrowsingDataRemoverDelegate::DATA_TYPE_PLUGIN_DATA;
- int remove_mask = 0;
- int origin_mask = 0;
+ uint64_t remove_mask = 0;
+ uint64_t origin_mask = 0;
std::vector<BrowsingDataType> data_type_vector;
const base::ListValue* data_type_list = nullptr;
CHECK(args->GetList(1, &data_type_list));
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
index 98dca3b412e..28c96790a03 100644
--- 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
@@ -7,6 +7,7 @@
#include "base/values.h"
#include "chrome/browser/ui/web_applications/web_app_controller_browsertest.h"
+#include "chrome/browser/web_applications/test/web_app_test.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"
@@ -98,13 +99,10 @@ IN_PROC_BROWSER_TEST_P(ClearBrowsingDataHandlerBrowserTest, GetInstalledApps) {
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);
+INSTANTIATE_TEST_SUITE_P(All,
+ ClearBrowsingDataHandlerBrowserTest,
+ ::testing::Values(web_app::ProviderType::kBookmarkApps,
+ web_app::ProviderType::kWebApps),
+ web_app::ProviderTypeParamToString);
} // 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 eff2694ecfd..ccb1ccca58c 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
@@ -99,8 +99,9 @@
#include "components/prefs/pref_service.h"
#include "components/user_manager/user_manager.h"
#include "ui/chromeos/devicetype_utils.h"
-#else
+#else // !defined(OS_CHROMEOS)
#include "chrome/browser/ui/webui/settings/system_handler.h"
+#include "ui/accessibility/accessibility_features.h"
#endif
#if defined(OS_WIN)
@@ -156,6 +157,9 @@ void AddCommonStrings(content::WebUIDataSource* html_source, Profile* profile) {
{"settings", IDS_SETTINGS_SETTINGS},
{"settingsAltPageTitle", IDS_SETTINGS_ALT_PAGE_TITLE},
{"subpageArrowRoleDescription", IDS_SETTINGS_SUBPAGE_BUTTON},
+ {"subpageBackButtonAriaLabel", IDS_SETTINGS_SUBPAGE_BACK_BUTTON_ARIA_LABEL},
+ {"subpageBackButtonAriaRoleDescription",
+ IDS_SETTINGS_SUBPAGE_BACK_BUTTON_ARIA_ROLE_DESCRIPTION},
{"notValid", IDS_SETTINGS_NOT_VALID},
{"notValidWebAddress", IDS_SETTINGS_NOT_VALID_WEB_ADDRESS},
{"notValidWebAddressForContentType",
@@ -203,6 +207,9 @@ void AddA11yStrings(content::WebUIDataSource* html_source) {
{"manageAccessibilityFeatures",
IDS_SETTINGS_ACCESSIBILITY_MANAGE_ACCESSIBILITY_FEATURES},
{"androidAppsManageAppLinks", IDS_SETTINGS_ANDROID_APPS_MANAGE_APP_LINKS},
+#else // !defined(OS_CHROMEOS)
+ {"focusHighlightLabel",
+ IDS_SETTINGS_ACCESSIBILITY_FOCUS_HIGHLIGHT_DESCRIPTION},
#endif
};
AddLocalizedStringsBulk(html_source, kLocalizedStrings);
@@ -215,6 +222,12 @@ void AddA11yStrings(content::WebUIDataSource* html_source) {
"showExperimentalA11yLabels",
base::FeatureList::IsEnabled(features::kExperimentalAccessibilityLabels));
+#if !defined(OS_CHROMEOS)
+ html_source->AddBoolean(
+ "showFocusHighlightOption",
+ base::FeatureList::IsEnabled(features::kAccessibilityFocusHighlight));
+#endif
+
html_source->AddBoolean("enableLiveCaption",
base::FeatureList::IsEnabled(media::kLiveCaption));
@@ -460,7 +473,7 @@ void AddChromeCleanupStrings(content::WebUIDataSource* html_source) {
IDS_SETTINGS_RESET_CLEANUP_EXPLANATION_CURRENTLY_REMOVING},
{"chromeCleanupExplanationScanError",
IDS_SETTINGS_RESET_CLEANUP_EXPLANATION_SCAN_ERROR},
- {"chromeCleanupFindButtonLable",
+ {"chromeCleanupFindButtonLabel",
IDS_SETTINGS_RESET_CLEANUP_FIND_BUTTON_LABEL},
{"chromeCleanupLinkShowItems",
IDS_SETTINGS_RESET_CLEANUP_LINK_SHOW_FILES},
@@ -769,6 +782,7 @@ void AddAutofillStrings(content::WebUIDataSource* html_source,
static constexpr webui::LocalizedString kLocalizedStrings[] = {
{"autofillPageTitle", IDS_SETTINGS_AUTOFILL},
{"passwords", IDS_SETTINGS_PASSWORDS},
+ {"passwordsDevice", IDS_SETTINGS_DEVICE_PASSWORDS},
{"checkPasswords", IDS_SETTINGS_CHECK_PASSWORDS},
{"checkPasswordsCanceled", IDS_SETTINGS_CHECK_PASSWORDS_CANCELED},
{"checkedPasswords", IDS_SETTINGS_CHECKED_PASSWORDS},
@@ -817,8 +831,7 @@ void AddAutofillStrings(content::WebUIDataSource* html_source,
IDS_SETTINGS_COMPROMISED_EDIT_PASSWORD_APP},
{"alreadyChangedPasswordLink",
IDS_SETTINGS_COMPROMISED_ALREADY_CHANGED_PASSWORD},
- {"editDisclaimerTitle",
- IDS_SETTINGS_COMPROMISED_EDIT_DISCLAIMER_TITLE},
+ {"editDisclaimerTitle", IDS_SETTINGS_COMPROMISED_EDIT_DISCLAIMER_TITLE},
{"editDisclaimerDescription",
IDS_SETTINGS_COMPROMISED_EDIT_DISCLAIMER_DESCRIPTION},
{"creditCards", IDS_AUTOFILL_PAYMENT_METHODS},
@@ -846,6 +859,8 @@ void AddAutofillStrings(content::WebUIDataSource* html_source,
{"creditCardType", IDS_SETTINGS_AUTOFILL_CREDIT_CARD_TYPE_COLUMN_LABEL},
{"creditCardExpiration", IDS_SETTINGS_CREDIT_CARD_EXPIRATION_DATE},
{"creditCardName", IDS_SETTINGS_NAME_ON_CREDIT_CARD},
+ {"creditCardNickname", IDS_SETTINGS_CREDIT_CARD_NICKNAME},
+ {"creditCardNicknameInvalid", IDS_SETTINGS_CREDIT_CARD_NICKNAME_INVALID},
{"creditCardNumber", IDS_SETTINGS_CREDIT_CARD_NUMBER},
{"creditCardExpirationMonth", IDS_SETTINGS_CREDIT_CARD_EXPIRATION_MONTH},
{"creditCardExpirationYear", IDS_SETTINGS_CREDIT_CARD_EXPIRATION_YEAR},
@@ -874,6 +889,10 @@ void AddAutofillStrings(content::WebUIDataSource* html_source,
IDS_SETTINGS_PASSWORDS_LEAK_DETECTION_SIGNED_OUT_ENABLED_DESC},
{"savedPasswordsHeading", IDS_SETTINGS_PASSWORDS_SAVED_HEADING},
{"passwordExceptionsHeading", IDS_SETTINGS_PASSWORDS_EXCEPTIONS_HEADING},
+ {"deviceOnlyPasswordsHeading",
+ IDS_SETTINGS_DEVICE_PASSWORDS_ON_DEVICE_ONLY_HEADING},
+ {"deviceAndAccountPasswordsHeading",
+ IDS_SETTINGS_DEVICE_PASSWORDS_ON_DEVICE_AND_ACCOUNT_HEADING},
{"deletePasswordException", IDS_SETTINGS_PASSWORDS_DELETE_EXCEPTION},
{"removePassword", IDS_SETTINGS_PASSWORD_REMOVE},
{"searchPasswords", IDS_SETTINGS_PASSWORD_SEARCH},
@@ -882,6 +901,10 @@ void AddAutofillStrings(content::WebUIDataSource* html_source,
{"passwordDetailsTitle", IDS_SETTINGS_PASSWORDS_VIEW_DETAILS_TITLE},
{"passwordViewDetails", IDS_SETTINGS_PASSWORD_DETAILS},
{"copyPassword", IDS_SETTINGS_PASSWORD_COPY},
+ {"passwordStoredOnDevice", IDS_SETTINGS_PASSWORD_STORED_ON_DEVICE},
+ {"passwordStoredInAccount", IDS_SETTINGS_PASSWORD_STORED_IN_ACCOUNT},
+ {"passwordStoredInAccountAndOnDevice",
+ IDS_SETTINGS_PASSWORD_STORED_IN_ACCOUNT_AND_ON_DEVICE},
{"editPasswordWebsiteLabel", IDS_SETTINGS_PASSWORDS_WEBSITE},
{"editPasswordUsernameLabel", IDS_SETTINGS_PASSWORDS_USERNAME},
{"editPasswordPasswordLabel", IDS_SETTINGS_PASSWORDS_PASSWORD},
@@ -895,11 +918,38 @@ void AddAutofillStrings(content::WebUIDataSource* html_source,
{"optOutAccountStorageLabel",
IDS_SETTINGS_PASSWORDS_OPT_OUT_ACCOUNT_STORAGE_LABEL},
{"undoRemovePassword", IDS_SETTINGS_PASSWORD_UNDO},
+ {"movePasswordToAccount", IDS_SETTINGS_PASSWORD_MOVE_TO_ACCOUNT},
{"passwordDeleted", IDS_SETTINGS_PASSWORD_DELETED_PASSWORD},
{"passwordDeletedFromDevice",
IDS_SETTINGS_PASSWORD_DELETED_PASSWORD_FROM_DEVICE},
{"passwordDeletedFromAccount",
IDS_SETTINGS_PASSWORD_DELETED_PASSWORD_FROM_ACCOUNT},
+ {"passwordDeletedFromAccountAndDevice",
+ IDS_SETTINGS_PASSWORD_DELETED_PASSWORD_FROM_ACCOUNT_AND_DEVICE},
+ {"passwordMoveToAccountDialogTitle",
+ IDS_SETTINGS_PASSWORD_MOVE_TO_ACCOUNT_DIALOG_TITLE},
+ {"passwordMoveToAccountDialogBody",
+ IDS_SETTINGS_PASSWORD_MOVE_TO_ACCOUNT_DIALOG_BODY},
+ {"passwordMoveToAccountDialogMoveButtonText",
+ IDS_SETTINGS_PASSWORD_MOVE_TO_ACCOUNT_DIALOG_MOVE_BUTTON_TEXT},
+ {"passwordMoveToAccountDialogCancelButtonText",
+ IDS_SETTINGS_PASSWORD_MOVE_TO_ACCOUNT_DIALOG_CANCEL_BUTTON_TEXT},
+ {"passwordRemoveDialogTitle", IDS_SETTINGS_PASSWORD_REMOVE_DIALOG_TITLE},
+ {"passwordRemoveDialogBody", IDS_SETTINGS_PASSWORD_REMOVE_DIALOG_BODY},
+ {"passwordRemoveDialogRemoveButtonText",
+ IDS_SETTINGS_PASSWORD_REMOVE_DIALOG_REMOVE_BUTTON_TEXT},
+ {"passwordRemoveDialogCancelButtonText",
+ IDS_SETTINGS_PASSWORD_REMOVE_DIALOG_CANCEL_BUTTON_TEXT},
+ {"passwordRemoveDialogFromAccountCheckboxLabel",
+ IDS_SETTINGS_PASSWORD_REMOVE_DIALOG_FROM_ACCOUNT_CHECKBOX_LABEL},
+ {"passwordRemoveDialogFromDeviceCheckboxLabel",
+ IDS_SETTINGS_PASSWORD_REMOVE_DIALOG_FROM_DEVICE_CHECKBOX_LABEL},
+ {"devicePasswordsLinkLabelSingular",
+ IDS_SETTINGS_DEVICE_PASSWORDS_LINK_LABEL_SINGULAR},
+ {"devicePasswordsLinkLabelPlural",
+ IDS_SETTINGS_DEVICE_PASSWORDS_LINK_LABEL_PLURAL},
+ {"devicePasswordsLinkSubLabel",
+ IDS_SETTINGS_DEVICE_PASSWORDS_LINK_SUB_LABEL},
{"passwordRowMoreActionsButton", IDS_SETTINGS_PASSWORD_ROW_MORE_ACTIONS},
{"passwordRowFederatedMoreActionsButton",
IDS_SETTINGS_PASSWORD_ROW_FEDERATED_MORE_ACTIONS},
@@ -916,6 +966,8 @@ void AddAutofillStrings(content::WebUIDataSource* html_source,
IDS_SETTINGS_PASSWORDS_EXPORTING_FAILURE_TIP_ENOUGH_SPACE},
{"exportPasswordsFailTipsAnotherFolder",
IDS_SETTINGS_PASSWORDS_EXPORTING_FAILURE_TIP_ANOTHER_FOLDER},
+ {"managePasswordsPlaintext",
+ IDS_SETTINGS_PASSWORDS_MANAGE_PASSWORDS_PLAINTEXT},
{"savedToThisDeviceOnly",
IDS_SETTINGS_PAYMENTS_SAVED_TO_THIS_DEVICE_ONLY}};
@@ -928,6 +980,16 @@ void AddAutofillStrings(content::WebUIDataSource* html_source,
IDS_SETTINGS_PASSWORDS_MANAGE_PASSWORDS,
base::UTF8ToUTF16(google_password_manager_url.spec())));
html_source->AddString(
+ "optInAccountStorageBody",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_PASSWORDS_OPT_IN_ACCOUNT_STORAGE_BODY,
+ base::UTF8ToUTF16(google_password_manager_url.spec())));
+ html_source->AddString(
+ "optOutAccountStorageBody",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_PASSWORDS_OPT_OUT_ACCOUNT_STORAGE_BODY,
+ base::UTF8ToUTF16(google_password_manager_url.spec())));
+ html_source->AddString(
"checkPasswordsErrorQuotaGoogleAccount",
l10n_util::GetStringFUTF16(
IDS_SETTINGS_CHECK_PASSWORDS_ERROR_QUOTA_LIMIT_GOOGLE_ACCOUNT,
@@ -951,6 +1013,11 @@ void AddAutofillStrings(content::WebUIDataSource* html_source,
autofill::payments::GetManageInstrumentsUrl().spec());
html_source->AddString("paymentMethodsLearnMoreURL",
chrome::kPaymentMethodsLearnMoreURL);
+ html_source->AddString(
+ "siteSettingsFlashWildcardsUnsupported",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_SITE_SETTINGS_FLASH_WILDCARD_UNSUPPORTED,
+ base::UTF8ToUTF16(chrome::kChromeFlashRoadmapURL)));
bool is_guest_mode = false;
#if defined(OS_CHROMEOS)
@@ -982,6 +1049,10 @@ void AddAutofillStrings(content::WebUIDataSource* html_source,
base::FeatureList::IsEnabled(
autofill::features::kAutofillSaveAndFillVPA));
+ html_source->AddBoolean(
+ "nicknameManagementEnabled",
+ base::FeatureList::IsEnabled(
+ autofill::features::kAutofillEnableCardNicknameManagement));
AddLocalizedStringsBulk(html_source, kLocalizedStrings);
}
@@ -989,15 +1060,15 @@ void AddSignOutDialogStrings(content::WebUIDataSource* html_source,
Profile* profile) {
#if defined(OS_CHROMEOS)
bool is_dice_enabled = false;
- bool is_split_sync_consent_enabled =
- chromeos::features::IsSplitSyncConsentEnabled();
+ bool use_browser_sync_consent =
+ chromeos::features::ShouldUseBrowserSyncConsent();
#else
bool is_dice_enabled =
AccountConsistencyModeManager::IsDiceEnabledForProfile(profile);
- bool is_split_sync_consent_enabled = false;
+ bool use_browser_sync_consent = false;
#endif
- if (is_split_sync_consent_enabled || is_dice_enabled) {
+ if (use_browser_sync_consent || is_dice_enabled) {
static constexpr webui::LocalizedString kTurnOffStrings[] = {
{"syncDisconnect", IDS_SETTINGS_PEOPLE_SYNC_TURN_OFF},
{"syncDisconnectTitle",
@@ -1136,6 +1207,10 @@ void AddPrivacyStrings(content::WebUIDataSource* html_source,
static constexpr webui::LocalizedString kLocalizedStrings[] = {
{"privacyPageTitle", IDS_SETTINGS_PRIVACY},
{"privacyPageMore", IDS_SETTINGS_PRIVACY_MORE},
+ // TODO(crbug.com/1116608): This seemingly unrelated string resource is
+ // used because it already has a localized version available in M85, so
+ // we can ship this label in M85 on short notice.
+ {"discardedPerSiteSetting", IDS_POLICY_LABEL_IGNORED},
{"doNotTrack", IDS_SETTINGS_ENABLE_DO_NOT_TRACK},
{"doNotTrackDialogTitle", IDS_SETTINGS_ENABLE_DO_NOT_TRACK_DIALOG_TITLE},
// TODO(crbug.com/1062607): This string is no longer used. Remove.
@@ -1293,6 +1368,10 @@ void AddPrivacyStrings(content::WebUIDataSource* html_source,
IDS_SETTINGS_SAFETY_CHECK_EXTENSIONS_PRIMARY_LABEL},
{"safetyCheckExtensionsButtonAriaLabel",
IDS_SETTINGS_SAFETY_CHECK_EXTENSIONS_BUTTON_ARIA_LABEL},
+ {"safetyCheckChromeCleanerPrimaryLabel",
+ IDS_SETTINGS_SAFETY_CHECK_CHROME_CLEANER_PRIMARY_LABEL},
+ {"safetyCheckChromeCleanerButtonAriaLabel",
+ IDS_SETTINGS_SAFETY_CHECK_CHROME_CLEANER_BUTTON_ARIA_LABEL},
};
AddLocalizedStringsBulk(html_source, kLocalizedStrings);
@@ -1401,8 +1480,6 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
Profile* profile) {
static constexpr webui::LocalizedString kLocalizedStrings[] = {
{"addSite", IDS_SETTINGS_ADD_SITE},
- {"addSiteExceptionPlaceholder",
- IDS_SETTINGS_ADD_SITE_EXCEPTION_PLACEHOLDER},
{"addSiteTitle", IDS_SETTINGS_ADD_SITE_TITLE},
#if defined(OS_CHROMEOS)
{"androidSmsNote", IDS_SETTINGS_ANDROID_SMS_NOTE},
@@ -1710,6 +1787,7 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
{"siteSettingsSourcePolicyAsk", IDS_PAGE_INFO_PERMISSION_ASK_BY_POLICY},
{"siteSettingsAdsBlockNotBlacklistedSingular",
IDS_SETTINGS_SITE_SETTINGS_ADS_BLOCK_NOT_BLACKLISTED_SINGULAR},
+ {"siteSettingsAllowlisted", IDS_SETTINGS_SITE_SETTINGS_ALLOWLISTED},
{"siteSettingsAdsBlockBlacklistedSingular",
IDS_SETTINGS_SITE_SETTINGS_ADS_BLOCK_BLACKLISTED_SINGULAR},
{"siteSettingsSourceDrmDisabled",
@@ -1853,6 +1931,8 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
IDS_SETTINGS_SITE_SETTINGS_WINDOW_PLACEMENT},
{"siteSettingsWindowPlacementAsk",
IDS_SETTINGS_SITE_SETTINGS_WINDOW_PLACEMENT_ASK},
+ {"siteSettingsWindowPlacementAskRecommended",
+ IDS_SETTINGS_SITE_SETTINGS_WINDOW_PLACEMENT_ASK_RECOMMENDED},
{"siteSettingsWindowPlacementBlock",
IDS_SETTINGS_SITE_SETTINGS_WINDOW_PLACEMENT_BLOCK},
};
@@ -1928,9 +2008,8 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
base::FeatureList::IsEnabled(
features::kWebBluetoothNewPermissionsBackend));
- html_source->AddBoolean(
- "enableWebXrContentSetting",
- base::FeatureList::IsEnabled(features::kWebXrPermissionsApi));
+ // The exception placeholder should not be translated. See crbug.com/1095878.
+ html_source->AddString("addSiteExceptionPlaceholder", "[*.]example.com");
}
#if !defined(OS_CHROMEOS)
diff --git a/chromium/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc b/chromium/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc
index 83923229636..a06c62efb33 100644
--- a/chromium/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc
@@ -11,7 +11,6 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/value_conversions.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/gaia_info_update_service.h"
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
index b0818ee920f..85887e9be9a 100644
--- a/chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc
@@ -8,7 +8,6 @@
#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/secure_dns_config.h"
@@ -24,10 +23,12 @@
#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/doh_provider_entry.h"
#include "net/dns/public/util.h"
#include "ui/base/l10n/l10n_util.h"
+namespace secure_dns = chrome_browser_net::secure_dns;
+
namespace settings {
namespace {
@@ -57,11 +58,7 @@ std::unique_ptr<base::DictionaryValue> CreateSecureDnsSettingDict() {
} // namespace
-SecureDnsHandler::SecureDnsHandler()
- : network_context_getter_(
- base::BindRepeating(&SecureDnsHandler::GetNetworkContext,
- base::Unretained(this))) {}
-
+SecureDnsHandler::SecureDnsHandler() = default;
SecureDnsHandler::~SecureDnsHandler() = default;
void SecureDnsHandler::RegisterMessages() {
@@ -111,38 +108,14 @@ 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 SecureDnsHandler::GetSecureDnsResolverList() {
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()});
- }
+ for (const auto* entry : providers_) {
+ base::Value dict(base::Value::Type::DICTIONARY);
+ dict.SetStringKey("name", entry->ui_name);
+ dict.SetStringKey("value", entry->dns_over_https_template);
+ dict.SetStringKey("policy", entry->privacy_policy);
+ resolvers.Append(std::move(dict));
}
// Randomize the order of the resolvers.
@@ -150,13 +123,10 @@ base::Value SecureDnsHandler::GetSecureDnsResolverListForCountry(
// 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()));
+ custom.SetStringKey("name", l10n_util::GetStringUTF8(IDS_SETTINGS_CUSTOM));
+ custom.SetStringKey("value", std::string()); // Empty value means custom.
+ custom.SetStringKey("policy", std::string());
resolvers.Insert(resolvers.GetList().begin(), std::move(custom));
- resolver_histogram_map_.insert(
- {"custom", net::DohProviderIdForHistogram::kCustom});
return resolvers;
}
@@ -176,15 +146,18 @@ network::mojom::NetworkContext* SecureDnsHandler::GetNetworkContext() {
->GetNetworkContext();
}
+void SecureDnsHandler::SetProvidersForTesting(
+ net::DohProviderEntry::List providers) {
+ providers_ = std::move(providers);
+}
+
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()));
+ ResolveJavascriptCallback(base::Value(callback_id),
+ GetSecureDnsResolverList());
}
void SecureDnsHandler::HandleGetSecureDnsSetting(const base::ListValue* args) {
@@ -203,14 +176,12 @@ void SecureDnsHandler::HandleParseCustomDnsEntry(const base::ListValue* args) {
// Return all templates in the entry, or none if they are not all valid.
base::Value templates(base::Value::Type::LIST);
- if (chrome_browser_net::secure_dns::IsValidGroup(custom_entry)) {
- for (base::StringPiece t :
- chrome_browser_net::secure_dns::SplitGroup(custom_entry)) {
+ if (secure_dns::IsValidGroup(custom_entry)) {
+ for (base::StringPiece t : secure_dns::SplitGroup(custom_entry)) {
templates.Append(t);
}
}
- UMA_HISTOGRAM_BOOLEAN("Net.DNS.UI.ValidationAttemptSuccess",
- !templates.GetList().empty());
+ secure_dns::UpdateValidationHistogram(!templates.GetList().empty());
ResolveJavascriptCallback(*callback_id, templates);
}
@@ -236,7 +207,7 @@ void SecureDnsHandler::HandleProbeCustomDnsTemplate(
overrides.attempts = 1;
overrides.randomize_ports = false;
overrides.secure_dns_mode = net::DnsConfig::SecureDnsMode::SECURE;
- chrome_browser_net::secure_dns::ApplyTemplate(&overrides, server_template);
+ secure_dns::ApplyTemplate(&overrides, server_template);
DCHECK(!runner_);
runner_ = std::make_unique<chrome_browser_net::DnsProbeRunner>(
overrides, network_context_getter_);
@@ -251,29 +222,15 @@ void SecureDnsHandler::HandleRecordUserDropdownInteraction(
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);
- }
- }
+
+ secure_dns::UpdateDropdownHistograms(providers_, old_provider, new_provider);
}
void SecureDnsHandler::OnProbeComplete() {
bool success =
runner_->result() == chrome_browser_net::DnsProbeRunner::CORRECT;
runner_.reset();
- UMA_HISTOGRAM_BOOLEAN("Net.DNS.UI.ProbeAttemptSuccess", success);
+ secure_dns::UpdateProbeHistogram(success);
ResolveJavascriptCallback(base::Value(probe_callback_id_),
base::Value(success));
probe_callback_id_.clear();
@@ -284,4 +241,12 @@ void SecureDnsHandler::SendSecureDnsSettingUpdatesToJavascript() {
*CreateSecureDnsSettingDict());
}
+// static
+net::DohProviderEntry::List SecureDnsHandler::GetFilteredProviders() {
+ const auto local_providers = secure_dns::ProvidersForCountry(
+ net::DohProviderEntry::GetList(), country_codes::GetCurrentCountryID());
+ return secure_dns::RemoveDisabledProviders(
+ local_providers, secure_dns::GetDisabledProviders());
+}
+
} // 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
index 9f7622ae20d..dddaea2127a 100644
--- a/chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler.h
@@ -9,12 +9,13 @@
#include <string>
#include <vector>
+#include "base/bind.h"
#include "base/macros.h"
#include "base/values.h"
#include "chrome/browser/net/dns_probe_runner.h"
#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
#include "components/prefs/pref_change_registrar.h"
-#include "net/dns/public/doh_provider_list.h"
+#include "net/dns/public/doh_provider_entry.h"
#include "services/network/public/cpp/resolve_host_client_base.h"
#include "services/network/public/mojom/network_context.mojom.h"
@@ -35,13 +36,15 @@ class SecureDnsHandler : public SettingsPageUIHandler {
// 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);
+ base::Value GetSecureDnsResolverList();
void SetNetworkContextForTesting(
network::mojom::NetworkContext* network_context);
+ // DohProviderEntry cannot be copied, so the entries referenced in |providers|
+ // must be long-lived.
+ void SetProvidersForTesting(net::DohProviderEntry::List providers);
+
protected:
// Retrieves all pre-approved secure resolvers and returns them to WebUI.
void HandleGetSecureDnsResolverList(const base::ListValue* args);
@@ -66,10 +69,14 @@ class SecureDnsHandler : public SettingsPageUIHandler {
network::mojom::NetworkContext* GetNetworkContext();
void OnProbeComplete();
- std::map<std::string, net::DohProviderIdForHistogram> resolver_histogram_map_;
+ static net::DohProviderEntry::List GetFilteredProviders();
+
+ net::DohProviderEntry::List providers_ = GetFilteredProviders();
std::unique_ptr<chrome_browser_net::DnsProbeRunner> runner_;
chrome_browser_net::DnsProbeRunner::NetworkContextGetter
- network_context_getter_;
+ network_context_getter_ =
+ base::BindRepeating(&SecureDnsHandler::GetNetworkContext,
+ base::Unretained(this));
// ID of the Javascript callback for the current pending probe, or "" if
// there is no probe currently in progress.
std::string probe_callback_id_;
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
index 3ece9212741..81aa1024fc1 100644
--- 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
@@ -27,7 +27,6 @@
#include "base/win/win_util.h"
#endif
-using net::DohProviderEntry;
using testing::_;
using testing::IsEmpty;
using testing::Return;
@@ -43,47 +42,38 @@ 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;
+net::DohProviderEntry::List GetDohProviderListForTesting() {
+ static const auto global1 = net::DohProviderEntry::ConstructForTesting(
+ "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 */);
+ static const auto no_display = net::DohProviderEntry::ConstructForTesting(
+ "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 */);
+ static const auto ee_fr = net::DohProviderEntry::ConstructForTesting(
+ "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 */);
+ static const auto fr = net::DohProviderEntry::ConstructForTesting(
+ "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 */);
+ static const auto global2 = net::DohProviderEntry::ConstructForTesting(
+ "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 {&global1, &no_display, &ee_fr, &fr, &global2};
}
bool FindDropdownItem(const base::Value& resolvers,
@@ -315,116 +305,40 @@ IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, DropdownList) {
// 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());
+ EXPECT_TRUE(resolver_list[0].FindKey("value")->GetString().empty());
}
-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, DropdownListContents) {
+ const auto entries = GetDohProviderListForTesting();
+ handler_->SetProvidersForTesting(entries);
+ const base::Value resolver_list = handler_->GetSecureDnsResolverList();
+
+ EXPECT_EQ(entries.size() + 1, resolver_list.GetList().size());
+ EXPECT_TRUE(resolver_list.GetList()[0].FindKey("value")->GetString().empty());
+ for (const auto* entry : entries) {
+ EXPECT_TRUE(FindDropdownItem(resolver_list, entry->ui_name,
+ entry->dns_over_https_template,
+ entry->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());
+ handler_->SetProvidersForTesting(GetDohProviderListForTesting());
base::HistogramTester histograms;
base::ListValue args;
- args.AppendString("custom" /* old_provider */);
+ args.AppendString(std::string() /* 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);
+ const std::string kUmaBase = "Net.DNS.UI.DropdownSelectionEvent";
+ histograms.ExpectTotalCount(kUmaBase + ".Ignored", 4u);
+ histograms.ExpectTotalCount(kUmaBase + ".Selected", 1u);
+ histograms.ExpectTotalCount(kUmaBase + ".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) {
+IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, 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}";
@@ -433,6 +347,8 @@ IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTestWithDisabledProviders,
std::vector<std::string> secure_dns_templates;
int management_mode;
PrefService* local_state = g_browser_process->local_state();
+ local_state->SetString(prefs::kDnsOverHttpsMode,
+ SecureDnsConfig::kModeAutomatic);
local_state->SetString(prefs::kDnsOverHttpsTemplates, good_post_template);
EXPECT_TRUE(GetLastSettingsChangedMessage(
&secure_dns_mode, &secure_dns_templates, &management_mode));
@@ -458,15 +374,6 @@ IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTestWithDisabledProviders,
&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) {
diff --git a/chromium/chrome/browser/ui/webui/settings/settings_ui.cc b/chromium/chrome/browser/ui/webui/settings/settings_ui.cc
index 0462890255d..9e29823de46 100644
--- a/chromium/chrome/browser/ui/webui/settings/settings_ui.cc
+++ b/chromium/chrome/browser/ui/webui/settings/settings_ui.cc
@@ -285,11 +285,17 @@ SettingsUI::SettingsUI(content::WebUI* web_ui)
"syncSetupFriendlySettings",
base::FeatureList::IsEnabled(features::kSyncSetupFriendlySettings));
+#if defined(OS_WIN)
+ html_source->AddBoolean(
+ "safetyCheckChromeCleanerChildEnabled",
+ base::FeatureList::IsEnabled(features::kSafetyCheckChromeCleanerChild));
+#endif
+
#if defined(OS_CHROMEOS)
html_source->AddBoolean("splitSettingsSyncEnabled",
chromeos::features::IsSplitSettingsSyncEnabled());
- html_source->AddBoolean("splitSyncConsent",
- chromeos::features::IsSplitSyncConsentEnabled());
+ html_source->AddBoolean("useBrowserSyncConsent",
+ chromeos::features::ShouldUseBrowserSyncConsent());
html_source->AddBoolean(
"userCannotManuallyEnterPassword",
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
index 20abed8007e..ae20e5716f0 100644
--- 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
@@ -8,6 +8,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/system/sys_info.h"
#include "build/build_config.h"
+#include "chrome/browser/browser_features.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browser_process_platform_part.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
@@ -242,4 +243,15 @@ void AddSyncPageStrings(content::WebUIDataSource* html_source) {
}
}
+void AddNearbyShareData(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"nearbyShareTitle", IDS_SETTINGS_NEARBY_SHARE_TITLE},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddBoolean(
+ "nearbySharingFeatureFlag",
+ base::FeatureList::IsEnabled(features::kNearbySharing));
+}
+
} // 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
index 33dc5c453d4..73333c7fef5 100644
--- 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
@@ -31,6 +31,9 @@ void AddPasswordPromptDialogStrings(content::WebUIDataSource* html_source);
// Adds strings used by the <settings-sync-page> element.
void AddSyncPageStrings(content::WebUIDataSource* html_source);
+// Adds load time data used by the <settings-nearby-share-subpage>.
+void AddNearbyShareData(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 e195fcbd936..bcbafdd8e31 100644
--- a/chromium/chrome/browser/ui/webui/settings/site_settings_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/site_settings_handler.cc
@@ -95,14 +95,6 @@ constexpr char kPlaceholder[] = "placeholder";
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
-enum class AllSitesAction {
- kLoadPage = 0,
- kResetPermissions = 1,
- kClearData = 2,
- kEnterSiteDetails = 3,
- kMaxValue = kEnterSiteDetails,
-};
-
enum class AllSitesAction2 {
kLoadPage = 0,
kResetSiteGroupPermissions = 1,
@@ -418,11 +410,6 @@ 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,
@@ -817,34 +804,6 @@ void SiteSettingsHandler::HandleGetAllSites(const base::ListValue* args) {
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();
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 0b34a324727..90c8106441b 100644
--- a/chromium/chrome/browser/ui/webui/settings/site_settings_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/site_settings_handler.h
@@ -128,11 +128,13 @@ class SiteSettingsHandler
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);
+ FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, ExcludeWebUISchemesInLists);
+ FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest,
+ IncludeWebUISchemesInGetOriginPermissions);
// Creates the CookiesTreeModel if necessary.
void EnsureCookiesTreeModelCreated();
@@ -171,10 +173,6 @@ class SiteSettingsHandler
// 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);
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 ee654373208..95b114fb5dc 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
@@ -45,8 +45,6 @@
#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"
@@ -67,6 +65,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/text/bytes_formatting.h"
+#include "ui/webui/webui_allowlist.h"
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/login/users/mock_user_manager.h"
@@ -424,9 +423,10 @@ class SiteSettingsHandlerTest : public testing::Test {
}
virtual void DestroyIncognitoProfile() {
- profile_->SetOffTheRecordProfile(nullptr);
- ASSERT_FALSE(profile_->HasOffTheRecordProfile());
- incognito_profile_ = nullptr;
+ if (incognito_profile_) {
+ profile_->DestroyOffTheRecordProfile(incognito_profile_);
+ incognito_profile_ = nullptr;
+ }
}
// TODO(https://crbug.com/835712): Currently only set up the cookies and local
@@ -1877,6 +1877,133 @@ TEST_F(SiteSettingsHandlerTest, BlockAutoplay_Update) {
EXPECT_FALSE(profile()->GetPrefs()->GetBoolean(prefs::kBlockAutoplayEnabled));
}
+TEST_F(SiteSettingsHandlerTest, ExcludeWebUISchemesInLists) {
+ const ContentSettingsType content_settings_type =
+ ContentSettingsType::NOTIFICATIONS;
+ // Register WebUIAllowlist auto-granted permissions.
+ const url::Origin kWebUIOrigins[] = {
+ url::Origin::Create(GURL("chrome://test")),
+ url::Origin::Create(GURL("chrome-untrusted://test")),
+ url::Origin::Create(GURL("devtools://devtools")),
+ };
+
+ WebUIAllowlist* allowlist = WebUIAllowlist::GetOrCreate(profile());
+ for (const url::Origin& origin : kWebUIOrigins)
+ allowlist->RegisterAutoGrantedPermission(origin, content_settings_type);
+
+ // Verify the auto-granted permissions are registered, and they are indeed
+ // provided by WebUIAllowlist.
+ HostContentSettingsMap* map =
+ HostContentSettingsMapFactory::GetForProfile(profile());
+ content_settings::SettingInfo info;
+ std::unique_ptr<base::Value> value = map->GetWebsiteSetting(
+ kWebUIOrigins[0].GetURL(), kWebUIOrigins[0].GetURL(),
+ content_settings_type, std::string(), &info);
+ EXPECT_EQ(CONTENT_SETTING_ALLOW, value->GetInt());
+ EXPECT_EQ(content_settings::SETTING_SOURCE_ALLOWLIST, info.source);
+
+ // Register an ordinary website permission.
+ const GURL kWebUrl = GURL("https://example.com");
+ map->SetContentSettingDefaultScope(kWebUrl, kWebUrl, content_settings_type,
+ std::string(), CONTENT_SETTING_ALLOW);
+ EXPECT_EQ(CONTENT_SETTING_ALLOW,
+ map->GetContentSetting(kWebUrl, kWebUrl, content_settings_type,
+ std::string()));
+
+ // GetAllSites() only returns website exceptions.
+ {
+ base::ListValue get_all_sites_args;
+ get_all_sites_args.AppendString(kCallbackId);
+ base::Value category_list(base::Value::Type::LIST);
+ category_list.Append(kNotifications);
+ get_all_sites_args.Append(std::move(category_list));
+
+ handler()->HandleGetAllSites(&get_all_sites_args);
+
+ const content::TestWebUI::CallData& data = *web_ui()->call_data().back();
+ base::Value::ConstListView site_groups = data.arg3()->GetList();
+ EXPECT_EQ(1UL, site_groups.size());
+
+ const std::string etld_plus1_string =
+ site_groups[0].FindKey("etldPlus1")->GetString();
+ EXPECT_EQ("example.com", etld_plus1_string);
+ base::Value::ConstListView origin_list =
+ site_groups[0].FindKey("origins")->GetList();
+ EXPECT_EQ(1UL, origin_list.size());
+ EXPECT_EQ(kWebUrl.spec(), origin_list[0].FindKey("origin")->GetString());
+ }
+
+ // GetExceptionList() only returns website exceptions.
+ {
+ base::ListValue get_exception_list_args;
+ get_exception_list_args.AppendString(kCallbackId);
+ get_exception_list_args.AppendString(kNotifications);
+
+ handler()->HandleGetExceptionList(&get_exception_list_args);
+
+ const content::TestWebUI::CallData& data = *web_ui()->call_data().back();
+ base::Value::ConstListView exception_list = data.arg3()->GetList();
+ EXPECT_EQ(1UL, exception_list.size());
+ EXPECT_EQ("https://example.com:443",
+ exception_list[0].FindKey("origin")->GetString());
+ }
+
+ // GetRecentSitePermissions() only returns website exceptions.
+ {
+ base::ListValue get_recent_permissions_args;
+ get_recent_permissions_args.AppendString(kCallbackId);
+ base::Value category_list(base::Value::Type::LIST);
+ category_list.Append(kNotifications);
+ get_recent_permissions_args.Append(std::move(category_list));
+ get_recent_permissions_args.Append(3);
+
+ handler()->HandleGetRecentSitePermissions(&get_recent_permissions_args);
+
+ const content::TestWebUI::CallData& data = *web_ui()->call_data().back();
+ base::Value::ConstListView recent_permission_list = data.arg3()->GetList();
+ EXPECT_EQ(1UL, recent_permission_list.size());
+ EXPECT_EQ(kWebUrl.spec(),
+ recent_permission_list[0].FindKey("origin")->GetString());
+ }
+}
+
+// GetOriginPermissions() returns the allowlisted exception. We explicitly
+// return this, so developers can easily test things (e.g. by navigating to
+// chrome://settings/content/siteDetails?site=chrome://example).
+TEST_F(SiteSettingsHandlerTest, IncludeWebUISchemesInGetOriginPermissions) {
+ const ContentSettingsType content_settings_type =
+ ContentSettingsType::NOTIFICATIONS;
+
+ // Register WebUIAllowlist auto-granted permissions.
+ const url::Origin kWebUIOrigins[] = {
+ url::Origin::Create(GURL("chrome://test")),
+ url::Origin::Create(GURL("chrome-untrusted://test")),
+ url::Origin::Create(GURL("devtools://devtools")),
+ };
+
+ WebUIAllowlist* allowlist = WebUIAllowlist::GetOrCreate(profile());
+ for (const url::Origin& origin : kWebUIOrigins)
+ allowlist->RegisterAutoGrantedPermission(origin, content_settings_type);
+
+ for (const url::Origin& origin : kWebUIOrigins) {
+ base::ListValue get_origin_permissions_args;
+ get_origin_permissions_args.AppendString(kCallbackId);
+ get_origin_permissions_args.AppendString(origin.GetURL().spec());
+ auto category_list = std::make_unique<base::ListValue>();
+ category_list->AppendString(kNotifications);
+ get_origin_permissions_args.Append(std::move(category_list));
+
+ handler()->HandleGetOriginPermissions(&get_origin_permissions_args);
+ const content::TestWebUI::CallData& data = *web_ui()->call_data().back();
+ const base::Value::ConstListView exception_list = data.arg3()->GetList();
+ EXPECT_EQ(1UL, exception_list.size());
+
+ EXPECT_EQ(origin.GetURL().spec(),
+ exception_list[0].FindKey("origin")->GetString());
+ EXPECT_EQ("allowlist", exception_list[0].FindKey("source")->GetString());
+ }
+}
+
namespace {
constexpr char kUsbPolicySetting[] = R"(
@@ -1907,6 +2034,9 @@ GURL ChromiumUrl() {
GURL GoogleUrl() {
return GURL("https://google.com");
}
+GURL WebUIUrl() {
+ return GURL("chrome://test");
+}
} // namespace
@@ -1954,6 +2084,7 @@ class SiteSettingsHandlerChooserExceptionTest : public SiteSettingsHandlerTest {
const auto kAndroidOrigin = url::Origin::Create(AndroidUrl());
const auto kChromiumOrigin = url::Origin::Create(ChromiumUrl());
const auto kGoogleOrigin = url::Origin::Create(GoogleUrl());
+ const auto kWebUIOrigin = url::Origin::Create(WebUIUrl());
// Add the user granted permissions for testing.
// These two persistent device permissions should be lumped together with
@@ -1964,6 +2095,8 @@ class SiteSettingsHandlerChooserExceptionTest : public SiteSettingsHandlerTest {
*persistent_device_info_);
chooser_context->GrantDevicePermission(kAndroidOrigin, kChromiumOrigin,
*persistent_device_info_);
+ chooser_context->GrantDevicePermission(kWebUIOrigin, kWebUIOrigin,
+ *persistent_device_info_);
chooser_context->GrantDevicePermission(kAndroidOrigin, kAndroidOrigin,
*ephemeral_device_info_);
chooser_context->GrantDevicePermission(kAndroidOrigin, kAndroidOrigin,
@@ -2118,6 +2251,11 @@ TEST_F(SiteSettingsHandlerChooserExceptionTest,
const base::Value& exceptions = GetChooserExceptionListFromWebUiCallData(
kUsbChooserGroupName, /*expected_total_calls=*/1u);
EXPECT_EQ(exceptions.GetList().size(), 5u);
+
+ // Don't include WebUI schemes.
+ const std::string kWebUIOriginStr = WebUIUrl().GetOrigin().spec();
+ EXPECT_FALSE(ChooserExceptionContainsSiteException(
+ exceptions, "Gizmo", kWebUIOriginStr, kWebUIOriginStr));
}
TEST_F(SiteSettingsHandlerChooserExceptionTest,
@@ -2338,61 +2476,6 @@ 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(
diff --git a/chromium/chrome/browser/ui/webui/settings/site_settings_helper.cc b/chromium/chrome/browser/ui/webui/settings/site_settings_helper.cc
index 5dfef5ee030..28addc32434 100644
--- a/chromium/chrome/browser/ui/webui/settings/site_settings_helper.cc
+++ b/chromium/chrome/browser/ui/webui/settings/site_settings_helper.cc
@@ -10,8 +10,11 @@
#include <string>
#include "base/feature_list.h"
+#include "base/no_destructor.h"
#include "base/stl_util.h"
+#include "base/strings/strcat.h"
#include "base/strings/string16.h"
+#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/bluetooth/bluetooth_chooser_context.h"
@@ -26,12 +29,10 @@
#include "chrome/browser/usb/usb_chooser_context.h"
#include "chrome/browser/usb/usb_chooser_context_factory.h"
#include "chrome/common/pref_names.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_pattern.h"
#include "components/content_settings/core/common/content_settings_utils.h"
-#include "components/content_settings/core/common/pref_names.h"
#include "components/permissions/chooser_context_base.h"
#include "components/permissions/permission_decision_auto_blocker.h"
#include "components/permissions/permission_manager.h"
@@ -42,9 +43,11 @@
#include "components/subresource_filter/core/browser/subresource_filter_features.h"
#include "components/url_formatter/url_formatter.h"
#include "content/public/common/content_features.h"
+#include "content/public/common/url_utils.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/constants.h"
#include "url/origin.h"
+#include "url/url_constants.h"
namespace site_settings {
@@ -158,6 +161,7 @@ struct SiteSettingSourceStringMapping {
};
const SiteSettingSourceStringMapping kSiteSettingSourceStringMapping[] = {
+ {SiteSettingSource::kAllowlist, "allowlist"},
{SiteSettingSource::kAdsFilterBlacklist, "ads-filter-blacklist"},
{SiteSettingSource::kDefault, "default"},
{SiteSettingSource::kDrmDisabled, "drm-disabled"},
@@ -195,38 +199,49 @@ static_assert(base::size(kPolicyIndicatorTypeStringMapping) ==
"kPolicyIndicatorStringMapping should have "
"PolicyIndicatorType::kNumIndicators elements");
+const std::string& GetDevtoolsPatternPrefix() {
+ static const base::NoDestructor<std::string> kDevtoolsPatternPrefix(
+ base::StrCat({content_settings::kChromeDevToolsScheme,
+ url::kStandardSchemeSeparator}));
+ return *kDevtoolsPatternPrefix;
+}
+
// Retrieves the corresponding string, according to the following precedence
// order from highest to lowest priority:
-// 1. Kill-switch.
-// 2. Insecure origins (some permissions are denied to insecure origins).
-// 3. Enterprise policy.
-// 4. Extensions.
-// 5. Activated for ads filtering (for Ads ContentSettingsType only).
-// 6. DRM disabled (for CrOS's Protected Content ContentSettingsType only).
-// 7. User-set per-origin setting.
-// 8. Embargo.
-// 9. User-set patterns.
-// 10. User-set global default for a ContentSettingsType.
-// 11. Chrome's built-in default.
+// 1. Allowlisted WebUI content setting.
+// 2. Kill-switch.
+// 3. Insecure origins (some permissions are denied to insecure origins).
+// 4. Enterprise policy.
+// 5. Extensions.
+// 6. Activated for ads filtering (for Ads ContentSettingsType only).
+// 7. DRM disabled (for CrOS's Protected Content ContentSettingsType only).
+// 8. User-set per-origin setting.
+// 9. Embargo.
+// 10. User-set patterns.
+// 11. User-set global default for a ContentSettingsType.
+// 12. Chrome's built-in default.
SiteSettingSource CalculateSiteSettingSource(
Profile* profile,
const ContentSettingsType content_type,
const GURL& origin,
const content_settings::SettingInfo& info,
const permissions::PermissionResult result) {
+ if (info.source == content_settings::SETTING_SOURCE_ALLOWLIST)
+ return SiteSettingSource::kAllowlist; // Source #1.
+
if (result.source == permissions::PermissionStatusSource::KILL_SWITCH)
- return SiteSettingSource::kKillSwitch; // Source #1.
+ return SiteSettingSource::kKillSwitch; // Source #2.
if (result.source == permissions::PermissionStatusSource::INSECURE_ORIGIN)
- return SiteSettingSource::kInsecureOrigin; // Source #2.
+ return SiteSettingSource::kInsecureOrigin; // Source #3.
if (info.source == content_settings::SETTING_SOURCE_POLICY ||
info.source == content_settings::SETTING_SOURCE_SUPERVISED) {
- return SiteSettingSource::kPolicy; // Source #3.
+ return SiteSettingSource::kPolicy; // Source #4.
}
if (info.source == content_settings::SETTING_SOURCE_EXTENSION)
- return SiteSettingSource::kExtension; // Source #4.
+ return SiteSettingSource::kExtension; // Source #5.
if (content_type == ContentSettingsType::ADS &&
base::FeatureList::IsEnabled(
@@ -236,14 +251,14 @@ SiteSettingSource CalculateSiteSettingSource(
if (map->GetWebsiteSetting(origin, GURL(), ContentSettingsType::ADS_DATA,
/*resource_identifier=*/std::string(),
/*setting_info=*/nullptr) != nullptr) {
- return SiteSettingSource::kAdsFilterBlacklist; // Source #5.
+ return SiteSettingSource::kAdsFilterBlacklist; // Source #6.
}
}
// Protected Content will be blocked if the |kEnableDRM| pref is off.
if (content_type == ContentSettingsType::PROTECTED_MEDIA_IDENTIFIER &&
!profile->GetPrefs()->GetBoolean(prefs::kEnableDRM)) {
- return SiteSettingSource::kDrmDisabled; // Source #6.
+ return SiteSettingSource::kDrmDisabled; // Source #7.
}
DCHECK_NE(content_settings::SETTING_SOURCE_NONE, info.source);
@@ -252,18 +267,18 @@ SiteSettingSource CalculateSiteSettingSource(
permissions::PermissionStatusSource::MULTIPLE_DISMISSALS ||
result.source ==
permissions::PermissionStatusSource::MULTIPLE_IGNORES) {
- return SiteSettingSource::kEmbargo; // Source #8.
+ return SiteSettingSource::kEmbargo; // Source #9.
}
if (info.primary_pattern == ContentSettingsPattern::Wildcard() &&
info.secondary_pattern == ContentSettingsPattern::Wildcard()) {
- return SiteSettingSource::kDefault; // Source #10, #11.
+ return SiteSettingSource::kDefault; // Source #11, #12.
}
- // Source #7, #9. When #7 is the source, |result.source| won't
- // be set to any of the source #7 enum values, as PermissionManager is
- // aware of the difference between these two sources internally. The
- // subtlety here should go away when PermissionManager can handle all
- // content settings and all possible sources.
+ // Source #8, #10. When #8 is the source, |result.source| won't be set to
+ // any of the source #8 enum values, as PermissionManager is aware of the
+ // difference between these two sources internally. The subtlety here should
+ // go away when PermissionManager can handle all content settings and all
+ // possible sources.
return SiteSettingSource::kPreference;
}
@@ -286,6 +301,16 @@ bool PatternAppliesToSingleOrigin(const ContentSettingPatternSource& pattern) {
return true;
}
+bool PatternAppliesToWebUISchemes(const ContentSettingPatternSource& pattern) {
+ return pattern.primary_pattern.GetScheme() ==
+ ContentSettingsPattern::SchemeType::SCHEME_CHROME ||
+ pattern.primary_pattern.GetScheme() ==
+ ContentSettingsPattern::SchemeType::SCHEME_CHROMEUNTRUSTED ||
+ base::StartsWith(pattern.primary_pattern.ToString(),
+ GetDevtoolsPatternPrefix(),
+ base::CompareCase::INSENSITIVE_ASCII);
+}
+
// Retrieves the source of a chooser exception as a string. This method uses the
// CalculateSiteSettingSource method above to calculate the correct string to
// use.
@@ -344,31 +369,12 @@ const ChooserTypeNameEntry kChooserTypeGroupNames[] = {
{&GetHidChooserContext, kHidChooserDataGroupType},
{&GetBluetoothChooserContext, kBluetoothChooserDataGroupType}};
-PolicyIndicatorType GetPolicyIndicatorFromSettingSource(
- content_settings::SettingSource setting_source) {
- switch (setting_source) {
- case content_settings::SETTING_SOURCE_POLICY:
- return PolicyIndicatorType::kDevicePolicy;
- case content_settings::SETTING_SOURCE_SUPERVISED:
- return PolicyIndicatorType::kParent;
- case content_settings::SETTING_SOURCE_EXTENSION:
- return PolicyIndicatorType::kExtension;
- case content_settings::SETTING_SOURCE_USER:
- case content_settings::SETTING_SOURCE_ALLOWLIST:
- case content_settings::SETTING_SOURCE_NONE:
- return PolicyIndicatorType::kNone;
- case content_settings::SETTING_SOURCE_INSTALLED_WEBAPP:
- NOTREACHED();
- return PolicyIndicatorType::kNone;
- }
-}
-
} // namespace
bool HasRegisteredGroupName(ContentSettingsType type) {
for (size_t i = 0; i < base::size(kContentSettingsTypeGroupNames); ++i) {
if (type == kContentSettingsTypeGroupNames[i].type &&
- kContentSettingsTypeGroupNames[i].name != nullptr) {
+ kContentSettingsTypeGroupNames[i].name) {
return true;
}
}
@@ -389,7 +395,7 @@ std::string ContentSettingsTypeToGroupName(ContentSettingsType type) {
for (size_t i = 0; i < base::size(kContentSettingsTypeGroupNames); ++i) {
if (type == kContentSettingsTypeGroupNames[i].type) {
const char* name = kContentSettingsTypeGroupNames[i].name;
- if (name != nullptr)
+ if (name)
return name;
break;
}
@@ -455,7 +461,9 @@ std::unique_ptr<base::DictionaryValue> GetExceptionForPage(
const std::string& display_name,
const ContentSetting& setting,
const std::string& provider_name,
- bool incognito) {
+ bool incognito,
+ bool is_embargoed,
+ bool is_discarded) {
auto exception = std::make_unique<base::DictionaryValue>();
exception->SetString(kOrigin, pattern.ToString());
exception->SetString(kDisplayName, display_name);
@@ -471,6 +479,8 @@ std::unique_ptr<base::DictionaryValue> GetExceptionForPage(
exception->SetString(kSetting, setting_string);
exception->SetString(kSource, provider_name);
exception->SetBoolean(kIncognito, incognito);
+ exception->SetBoolean(kIsEmbargoed, is_embargoed);
+ exception->SetBoolean(kIsDiscarded, is_discarded);
return exception;
}
@@ -539,6 +549,11 @@ void GetExceptionsForContentType(
map->GetSettingsForOneType(type, std::string(), &all_settings);
+ // Will return only regular settings for a regular profile and only incognito
+ // settings for an incognito Profile.
+ ContentSettingsForOneType discarded_settings;
+ map->GetDiscardedSettingsForOneType(type, std::string(), &discarded_settings);
+
// Group settings by primary_pattern.
AllPatternsSettings all_patterns_settings;
for (const auto& setting : all_settings) {
@@ -556,6 +571,11 @@ void GetExceptionsForContentType(
if (map->IsOffTheRecord() && !setting.incognito)
continue;
+ // Don't add WebUI settings.
+ if (PatternAppliesToWebUISchemes(setting)) {
+ continue;
+ }
+
all_patterns_settings[std::make_pair(
setting.primary_pattern, setting.source)][setting.secondary_pattern] =
setting.GetContentSetting();
@@ -569,6 +589,8 @@ void GetExceptionsForContentType(
permissions::PermissionsClient::Get()->GetPermissionDecisionAutoBlocker(
profile);
+ std::set<ContentSettingsPattern> origins_under_embargo;
+
for (const auto& setting : embargo_settings) {
// Off-the-record HostContentSettingsMap contains incognito content
// settings as well as normal content settings. Here, we use the
@@ -582,6 +604,7 @@ void GetExceptionsForContentType(
if (auto_blocker
->GetEmbargoResult(GURL(setting.primary_pattern.ToString()), type)
.content_setting == CONTENT_SETTING_BLOCK) {
+ origins_under_embargo.insert(setting.primary_pattern);
all_patterns_settings[std::make_pair(
setting.primary_pattern, setting.source)][setting.secondary_pattern] =
CONTENT_SETTING_BLOCK;
@@ -620,9 +643,10 @@ void GetExceptionsForContentType(
parent == one_settings.end() ? CONTENT_SETTING_DEFAULT : parent->second;
const ContentSettingsPattern& secondary_pattern =
parent == one_settings.end() ? primary_pattern : parent->first;
- this_provider_exceptions.push_back(
- GetExceptionForPage(primary_pattern, secondary_pattern, display_name,
- parent_setting, source, incognito));
+ this_provider_exceptions.push_back(GetExceptionForPage(
+ primary_pattern, secondary_pattern, display_name, parent_setting,
+ source, incognito,
+ base::Contains(origins_under_embargo, primary_pattern)));
// Add the "children" for any embedded settings.
for (auto j = one_settings.begin(); j != one_settings.end(); ++j) {
@@ -631,9 +655,9 @@ void GetExceptionsForContentType(
continue;
ContentSetting content_setting = j->second;
- this_provider_exceptions.push_back(
- GetExceptionForPage(primary_pattern, j->first, display_name,
- content_setting, source, incognito));
+ this_provider_exceptions.push_back(GetExceptionForPage(
+ primary_pattern, j->first, display_name, content_setting, source,
+ incognito, base::Contains(origins_under_embargo, primary_pattern)));
}
}
@@ -653,6 +677,15 @@ void GetExceptionsForContentType(
for (auto& exception : one_provider_exceptions)
exceptions->Append(std::move(exception));
}
+
+ for (auto& discarded_rule : discarded_settings) {
+ exceptions->Append(GetExceptionForPage(
+ discarded_rule.primary_pattern, discarded_rule.secondary_pattern,
+ GetDisplayNameForPattern(discarded_rule.primary_pattern,
+ extension_registry),
+ discarded_rule.GetContentSetting(), discarded_rule.source, incognito,
+ false /*is_embargoed*/, true /*is_discarded*/));
+ }
}
void GetContentCategorySetting(const HostContentSettingsMap* map,
@@ -713,7 +746,8 @@ std::vector<ContentSettingPatternSource> GetSiteExceptionsForContentType(
map->GetSettingsForOneType(content_type, std::string(), &entries);
entries.erase(std::remove_if(entries.begin(), entries.end(),
[](const ContentSettingPatternSource& e) {
- return !PatternAppliesToSingleOrigin(e);
+ return !PatternAppliesToSingleOrigin(e) ||
+ PatternAppliesToWebUISchemes(e);
}),
entries.end());
return entries;
@@ -864,6 +898,10 @@ base::Value GetChooserExceptionListFromProfile(
std::map<std::pair<base::string16, base::Value>, ChooserExceptionDetails>
all_chooser_objects;
for (const auto& object : objects) {
+ // Don't include WebUI settings.
+ if (content::HasWebUIScheme(object->requesting_origin))
+ continue;
+
base::string16 name = chooser_context->GetObjectDisplayName(object->value);
auto& chooser_exception_details =
all_chooser_objects[std::make_pair(name, object->value.Clone())];
@@ -893,121 +931,6 @@ base::Value GetChooserExceptionListFromProfile(
return exceptions;
}
-CookieControlsManagedState GetCookieControlsManagedState(Profile* profile) {
- // Setup a default unmanaged state that is updated based on the actual
- // managed state.
- CookieControlsManagedState managed_state;
-
- HostContentSettingsMap* map =
- HostContentSettingsMapFactory::GetForProfile(profile);
- std::string content_setting_provider;
- auto content_setting = map->GetDefaultContentSetting(
- ContentSettingsType::COOKIES, &content_setting_provider);
- auto content_setting_source =
- HostContentSettingsMap::GetSettingSourceFromProviderName(
- content_setting_provider);
- bool content_setting_enforced =
- content_setting_source !=
- content_settings::SettingSource::SETTING_SOURCE_USER;
-
- // Both the content setting and the block_third_party preference can
- // be controlled via policy.
- const PrefService::Preference* block_third_party_pref =
- profile->GetPrefs()->FindPreference(prefs::kBlockThirdPartyCookies);
- bool block_third_party_on = block_third_party_pref->GetValue()->GetBool();
- bool block_third_party_enforced = !block_third_party_pref->IsUserModifiable();
- // IsRecommended() cannot be used as we care if a recommended value exists at
- // all, even if a user has overwritten it.
- bool block_third_party_recommended =
- (block_third_party_pref && block_third_party_pref->GetRecommendedValue());
- bool block_third_party_recommended_on =
- block_third_party_recommended &&
- block_third_party_pref->GetRecommendedValue()->GetBool();
-
- // kCookieControlsMode == kOn should imply block_third_party is on.
- auto control_mode = static_cast<content_settings::CookieControlsMode>(
- profile->GetPrefs()->GetInteger(prefs::kCookieControlsMode));
- DCHECK(control_mode !=
- content_settings::CookieControlsMode::kBlockThirdParty ||
- block_third_party_on);
-
- // Get indicators representing each settings source. These may or may not
- // be used depending on the determined managed state.
- auto content_setting_source_indicator =
- GetPolicyIndicatorFromSettingSource(content_setting_source);
- auto block_third_party_source_indicator =
- GetPolicyIndicatorFromPref(block_third_party_pref);
-
- if (!content_setting_enforced && !block_third_party_enforced &&
- !block_third_party_recommended) {
- // No cookie controls are managed or recommended.
- return managed_state;
- }
-
- if (content_setting_enforced) {
- // Block and session only managed state only depend on the content setting.
- managed_state.block_all = {/*disabled*/ true,
- content_setting_source_indicator};
- managed_state.session_only = {/*disabled*/ true,
- content_setting_source_indicator};
- }
-
- if (content_setting_enforced && content_setting == CONTENT_SETTING_BLOCK) {
- // All remaining controls are managed by the content setting source.
- managed_state.allow_all = {/*disabled*/ true,
- content_setting_source_indicator};
- managed_state.block_third_party_incognito = {
- /*disabled*/ true, content_setting_source_indicator};
- managed_state.block_third_party = {/*disabled*/ true,
- content_setting_source_indicator};
- return managed_state;
- }
- if (content_setting_enforced && block_third_party_enforced) {
- // All remaining controls are managed by the block_third_party source.
- managed_state.allow_all = {/*disabled*/ true,
- block_third_party_source_indicator};
- managed_state.block_third_party_incognito = {
- /*disabled*/ true, block_third_party_source_indicator};
- managed_state.block_third_party = {/*disabled*/ true,
- block_third_party_source_indicator};
- return managed_state;
- }
- DCHECK(!content_setting_enforced ||
- content_setting == CONTENT_SETTING_ALLOW ||
- content_setting == CONTENT_SETTING_SESSION_ONLY);
- DCHECK(!content_setting_enforced || !block_third_party_enforced);
- // At this stage the content setting is not enforcing a BLOCK state. Given
- // this, allow and block_third_party are still valid choices that do not
- // contradict the content setting. They can thus be controlled or recommended
- // by the block_third_party preference.
- if (block_third_party_enforced) {
- DCHECK(!content_setting_enforced);
- managed_state.block_third_party_incognito = {
- true, block_third_party_source_indicator};
- if (block_third_party_on) {
- managed_state.allow_all = {/*disabled*/ true,
- block_third_party_source_indicator};
- } else {
- managed_state.block_third_party = {/*disabled*/ true,
- block_third_party_source_indicator};
- }
- return managed_state;
- }
- if (block_third_party_recommended) {
- if (block_third_party_recommended_on) {
- managed_state.block_third_party = {/*disabled*/ false,
- block_third_party_source_indicator};
- } else {
- managed_state.allow_all = {/*disabled*/ false,
- block_third_party_source_indicator};
- }
- return managed_state;
- }
- DCHECK(content_setting_enforced && !block_third_party_enforced &&
- !block_third_party_recommended);
- return managed_state;
-}
-
std::string PolicyIndicatorTypeToString(const PolicyIndicatorType type) {
return kPolicyIndicatorTypeStringMapping[static_cast<int>(type)]
.indicator_str;
diff --git a/chromium/chrome/browser/ui/webui/settings/site_settings_helper.h b/chromium/chrome/browser/ui/webui/settings/site_settings_helper.h
index b018f7c63a3..8ac89c83c11 100644
--- a/chromium/chrome/browser/ui/webui/settings/site_settings_helper.h
+++ b/chromium/chrome/browser/ui/webui/settings/site_settings_helper.h
@@ -53,11 +53,6 @@ typedef std::map<std::pair<ContentSettingsPattern, std::string>,
using ChooserExceptionDetails =
std::map<std::pair<GURL, std::string>, std::set<std::pair<GURL, bool>>>;
-constexpr char kAllowAll[] = "allowAll";
-constexpr char kBlockThirdPartyIncognito[] = "blockThirdPartyIncognito";
-constexpr char kBlockThirdParty[] = "blockThirdParty";
-constexpr char kBlockAll[] = "blockAll";
-constexpr char kSessionOnly[] = "sessionOnly";
constexpr char kChooserType[] = "chooserType";
constexpr char kDisplayName[] = "displayName";
constexpr char kEmbeddingOrigin[] = "embeddingOrigin";
@@ -72,8 +67,11 @@ constexpr char kSites[] = "sites";
constexpr char kPolicyIndicator[] = "indicator";
constexpr char kSource[] = "source";
constexpr char kType[] = "type";
+constexpr char kIsEmbargoed[] = "isEmbargoed";
+constexpr char kIsDiscarded[] = "isDiscarded";
enum class SiteSettingSource {
+ kAllowlist,
kAdsFilterBlacklist,
kDefault,
kDrmDisabled,
@@ -108,15 +106,6 @@ struct ManagedState {
PolicyIndicatorType indicator = PolicyIndicatorType::kNone;
};
-// Represents the manage states for all of the cookie controls.
-struct CookieControlsManagedState {
- ManagedState allow_all;
- ManagedState block_third_party_incognito;
- ManagedState block_third_party;
- ManagedState block_all;
- ManagedState session_only;
-};
-
// Returns whether a group name has been registered for the given type.
bool HasRegisteredGroupName(ContentSettingsType type);
@@ -141,7 +130,9 @@ std::unique_ptr<base::DictionaryValue> GetExceptionForPage(
const std::string& display_name,
const ContentSetting& setting,
const std::string& provider_name,
- bool incognito);
+ bool incognito,
+ bool is_embargoed = false,
+ bool is_discarded = false);
// Helper function to construct a dictionary for a hosted app exception.
void AddExceptionForHostedApp(const std::string& url_pattern,
@@ -225,9 +216,6 @@ base::Value GetChooserExceptionListFromProfile(
Profile* profile,
const ChooserTypeNameEntry& chooser_type);
-// Returns the cookie controls manage state for a given profile.
-CookieControlsManagedState GetCookieControlsManagedState(Profile* profile);
-
// Concerts a PolicyIndicatorType to its string identifier.
std::string PolicyIndicatorTypeToString(const PolicyIndicatorType type);
diff --git a/chromium/chrome/browser/ui/webui/settings/site_settings_helper_unittest.cc b/chromium/chrome/browser/ui/webui/settings/site_settings_helper_unittest.cc
index 2a08d0797ee..6b11de46fbe 100644
--- a/chromium/chrome/browser/ui/webui/settings/site_settings_helper_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/site_settings_helper_unittest.cc
@@ -23,7 +23,6 @@
#include "components/permissions/chooser_context_base.h"
#include "components/permissions/permission_decision_auto_blocker.h"
#include "components/prefs/pref_service.h"
-#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "content/public/test/browser_task_environment.h"
#include "extensions/browser/extension_registry.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
@@ -75,6 +74,47 @@ class SiteSettingsHelperTest : public testing::Test {
content::BrowserTaskEnvironment task_environment_;
};
+TEST_F(SiteSettingsHelperTest, ExceptionListWithEmbargoedAndBlockedOrigins) {
+ TestingProfile profile;
+
+ constexpr char kOriginToEmbargo[] = "https://embargoed.co.uk:443";
+ auto* auto_blocker =
+ PermissionDecisionAutoBlockerFactory::GetForProfile(&profile);
+ for (size_t i = 0; i < 3; ++i) {
+ auto_blocker->RecordDismissAndEmbargo(GURL(kOriginToEmbargo),
+ kContentTypeNotifications, false);
+ }
+
+ constexpr char kOriginToBlock[] = "https://www.blocked.com:443";
+ auto* map = HostContentSettingsMapFactory::GetForProfile(&profile);
+ map->SetContentSettingDefaultScope(GURL(kOriginToBlock), GURL(kOriginToBlock),
+ kContentTypeNotifications, std::string(),
+ CONTENT_SETTING_BLOCK);
+
+ base::ListValue exceptions;
+ site_settings::GetExceptionsForContentType(kContentTypeNotifications,
+ &profile,
+ /*extension_registry=*/nullptr,
+ /*web_ui=*/nullptr,
+ /*incognito=*/false, &exceptions);
+
+ // |exceptions| size should be 2. One blocked and one embargoed origins.
+ ASSERT_EQ(2U, exceptions.GetSize());
+ base::Value* value = nullptr;
+ // Get last added origin.
+ exceptions.Get(0, &value);
+ base::Value* is_embargoed = value->FindKey(site_settings::kIsEmbargoed);
+ ASSERT_NE(nullptr, is_embargoed);
+ // Last added origin is blocked, |embargo| key should be false.
+ EXPECT_FALSE(is_embargoed->GetBool());
+
+ // Get embargoed origin.
+ exceptions.Get(1, &value);
+ is_embargoed = value->FindKey(site_settings::kIsEmbargoed);
+ ASSERT_NE(nullptr, is_embargoed);
+ EXPECT_TRUE(is_embargoed->GetBool());
+}
+
TEST_F(SiteSettingsHelperTest, ExceptionListShowsIncognitoEmbargoed) {
TestingProfile profile;
constexpr char kOriginToBlock[] = "https://www.blocked.com:443";
@@ -816,302 +856,4 @@ TEST_F(SiteSettingsHelperChooserExceptionTest,
}
}
-namespace {
-
-// All of the possible managed states for a boolean preference that can be
-// both enforced and recommended.
-enum class PrefSetting {
- kEnforcedOff,
- kEnforcedOn,
- kRecommendedOff,
- kRecommendedOn,
- kNotSet,
-};
-
-// Possible preference sources supported by TestingPrefService.
-// TODO(crbug.com/1063281): Extend TestingPrefService to support prefs set for
-// supervised users.
-enum class PrefSource {
- kExtension,
- kDevicePolicy,
- kRecommended,
- kNone,
-};
-
-// Represents a set of settings, preferences and the associated expected
-// CookieControlsManagedState.
-struct CookiesManagedStateTestCase {
- ContentSetting default_content_setting;
- content_settings::SettingSource default_content_setting_source;
- PrefSetting block_third_party;
- PrefSource block_third_party_source;
- CookieControlsManagedState expected_result;
-};
-
-const std::vector<CookiesManagedStateTestCase> test_cases = {
- {CONTENT_SETTING_DEFAULT,
- content_settings::SETTING_SOURCE_NONE,
- PrefSetting::kEnforcedOff,
- PrefSource::kExtension,
- {{false, PolicyIndicatorType::kNone},
- {true, PolicyIndicatorType::kExtension},
- {true, PolicyIndicatorType::kExtension},
- {false, PolicyIndicatorType::kNone},
- {false, PolicyIndicatorType::kNone}}},
- {CONTENT_SETTING_DEFAULT,
- content_settings::SETTING_SOURCE_NONE,
- PrefSetting::kEnforcedOn,
- PrefSource::kDevicePolicy,
- {{true, PolicyIndicatorType::kDevicePolicy},
- {true, PolicyIndicatorType::kDevicePolicy},
- {false, PolicyIndicatorType::kNone},
- {false, PolicyIndicatorType::kNone},
- {false, PolicyIndicatorType::kNone}}},
- {CONTENT_SETTING_DEFAULT,
- content_settings::SETTING_SOURCE_NONE,
- PrefSetting::kRecommendedOff,
- PrefSource::kRecommended,
- {{false, PolicyIndicatorType::kRecommended},
- {false, PolicyIndicatorType::kNone},
- {false, PolicyIndicatorType::kNone},
- {false, PolicyIndicatorType::kNone},
- {false, PolicyIndicatorType::kNone}}},
- {CONTENT_SETTING_DEFAULT,
- content_settings::SETTING_SOURCE_NONE,
- PrefSetting::kRecommendedOn,
- PrefSource::kRecommended,
- {{false, PolicyIndicatorType::kNone},
- {false, PolicyIndicatorType::kNone},
- {false, PolicyIndicatorType::kRecommended},
- {false, PolicyIndicatorType::kNone},
- {false, PolicyIndicatorType::kNone}}},
- {CONTENT_SETTING_DEFAULT,
- content_settings::SETTING_SOURCE_NONE,
- PrefSetting::kNotSet,
- PrefSource::kNone,
- {{false, PolicyIndicatorType::kNone},
- {false, PolicyIndicatorType::kNone},
- {false, PolicyIndicatorType::kNone},
- {false, PolicyIndicatorType::kNone},
- {false, PolicyIndicatorType::kNone}}},
- {CONTENT_SETTING_ALLOW,
- content_settings::SETTING_SOURCE_POLICY,
- PrefSetting::kEnforcedOff,
- PrefSource::kExtension,
- {{true, PolicyIndicatorType::kExtension},
- {true, PolicyIndicatorType::kExtension},
- {true, PolicyIndicatorType::kExtension},
- {true, PolicyIndicatorType::kDevicePolicy},
- {true, PolicyIndicatorType::kDevicePolicy}}},
- {CONTENT_SETTING_ALLOW,
- content_settings::SETTING_SOURCE_EXTENSION,
- PrefSetting::kEnforcedOn,
- PrefSource::kDevicePolicy,
- {{true, PolicyIndicatorType::kDevicePolicy},
- {true, PolicyIndicatorType::kDevicePolicy},
- {true, PolicyIndicatorType::kDevicePolicy},
- {true, PolicyIndicatorType::kExtension},
- {true, PolicyIndicatorType::kExtension}}},
- {CONTENT_SETTING_ALLOW,
- content_settings::SETTING_SOURCE_SUPERVISED,
- PrefSetting::kRecommendedOff,
- PrefSource::kRecommended,
- {{false, PolicyIndicatorType::kRecommended},
- {false, PolicyIndicatorType::kNone},
- {false, PolicyIndicatorType::kNone},
- {true, PolicyIndicatorType::kParent},
- {true, PolicyIndicatorType::kParent}}},
- {CONTENT_SETTING_ALLOW,
- content_settings::SETTING_SOURCE_POLICY,
- PrefSetting::kRecommendedOn,
- PrefSource::kRecommended,
- {{false, PolicyIndicatorType::kNone},
- {false, PolicyIndicatorType::kNone},
- {false, PolicyIndicatorType::kRecommended},
- {true, PolicyIndicatorType::kDevicePolicy},
- {true, PolicyIndicatorType::kDevicePolicy}}},
- {CONTENT_SETTING_ALLOW,
- content_settings::SETTING_SOURCE_EXTENSION,
- PrefSetting::kNotSet,
- PrefSource::kNone,
- {{false, PolicyIndicatorType::kNone},
- {false, PolicyIndicatorType::kNone},
- {false, PolicyIndicatorType::kNone},
- {true, PolicyIndicatorType::kExtension},
- {true, PolicyIndicatorType::kExtension}}},
- {CONTENT_SETTING_BLOCK,
- content_settings::SETTING_SOURCE_SUPERVISED,
- PrefSetting::kEnforcedOff,
- PrefSource::kDevicePolicy,
- {{true, PolicyIndicatorType::kParent},
- {true, PolicyIndicatorType::kParent},
- {true, PolicyIndicatorType::kParent},
- {true, PolicyIndicatorType::kParent},
- {true, PolicyIndicatorType::kParent}}},
- {CONTENT_SETTING_BLOCK,
- content_settings::SETTING_SOURCE_POLICY,
- PrefSetting::kEnforcedOn,
- PrefSource::kExtension,
- {{true, PolicyIndicatorType::kDevicePolicy},
- {true, PolicyIndicatorType::kDevicePolicy},
- {true, PolicyIndicatorType::kDevicePolicy},
- {true, PolicyIndicatorType::kDevicePolicy},
- {true, PolicyIndicatorType::kDevicePolicy}}},
- {CONTENT_SETTING_BLOCK,
- content_settings::SETTING_SOURCE_EXTENSION,
- PrefSetting::kRecommendedOff,
- PrefSource::kRecommended,
- {{true, PolicyIndicatorType::kExtension},
- {true, PolicyIndicatorType::kExtension},
- {true, PolicyIndicatorType::kExtension},
- {true, PolicyIndicatorType::kExtension},
- {true, PolicyIndicatorType::kExtension}}},
- {CONTENT_SETTING_BLOCK,
- content_settings::SETTING_SOURCE_SUPERVISED,
- PrefSetting::kRecommendedOn,
- PrefSource::kRecommended,
- {{true, PolicyIndicatorType::kParent},
- {true, PolicyIndicatorType::kParent},
- {true, PolicyIndicatorType::kParent},
- {true, PolicyIndicatorType::kParent},
- {true, PolicyIndicatorType::kParent}}},
- {CONTENT_SETTING_BLOCK,
- content_settings::SETTING_SOURCE_POLICY,
- PrefSetting::kNotSet,
- PrefSource::kNone,
- {{true, PolicyIndicatorType::kDevicePolicy},
- {true, PolicyIndicatorType::kDevicePolicy},
- {true, PolicyIndicatorType::kDevicePolicy},
- {true, PolicyIndicatorType::kDevicePolicy},
- {true, PolicyIndicatorType::kDevicePolicy}}},
- {CONTENT_SETTING_SESSION_ONLY,
- content_settings::SETTING_SOURCE_EXTENSION,
- PrefSetting::kEnforcedOff,
- PrefSource::kDevicePolicy,
- {{true, PolicyIndicatorType::kDevicePolicy},
- {true, PolicyIndicatorType::kDevicePolicy},
- {true, PolicyIndicatorType::kDevicePolicy},
- {true, PolicyIndicatorType::kExtension},
- {true, PolicyIndicatorType::kExtension}}},
- {CONTENT_SETTING_SESSION_ONLY,
- content_settings::SETTING_SOURCE_SUPERVISED,
- PrefSetting::kEnforcedOn,
- PrefSource::kExtension,
- {{true, PolicyIndicatorType::kExtension},
- {true, PolicyIndicatorType::kExtension},
- {true, PolicyIndicatorType::kExtension},
- {true, PolicyIndicatorType::kParent},
- {true, PolicyIndicatorType::kParent}}},
- {CONTENT_SETTING_SESSION_ONLY,
- content_settings::SETTING_SOURCE_POLICY,
- PrefSetting::kRecommendedOff,
- PrefSource::kRecommended,
- {{false, PolicyIndicatorType::kRecommended},
- {false, PolicyIndicatorType::kNone},
- {false, PolicyIndicatorType::kNone},
- {true, PolicyIndicatorType::kDevicePolicy},
- {true, PolicyIndicatorType::kDevicePolicy}}},
- {CONTENT_SETTING_SESSION_ONLY,
- content_settings::SETTING_SOURCE_EXTENSION,
- PrefSetting::kRecommendedOn,
- PrefSource::kRecommended,
- {{false, PolicyIndicatorType::kNone},
- {false, PolicyIndicatorType::kNone},
- {false, PolicyIndicatorType::kRecommended},
- {true, PolicyIndicatorType::kExtension},
- {true, PolicyIndicatorType::kExtension}}},
- {CONTENT_SETTING_SESSION_ONLY,
- content_settings::SETTING_SOURCE_SUPERVISED,
- PrefSetting::kNotSet,
- PrefSource::kNone,
- {{false, PolicyIndicatorType::kNone},
- {false, PolicyIndicatorType::kNone},
- {false, PolicyIndicatorType::kNone},
- {true, PolicyIndicatorType::kParent},
- {true, PolicyIndicatorType::kParent}}}};
-
-void SetupTestConditions(HostContentSettingsMap* map,
- sync_preferences::TestingPrefServiceSyncable* prefs,
- const CookiesManagedStateTestCase& test_case) {
- if (test_case.default_content_setting != CONTENT_SETTING_DEFAULT) {
- auto provider = std::make_unique<content_settings::MockProvider>();
- provider->SetWebsiteSetting(
- ContentSettingsPattern::Wildcard(), ContentSettingsPattern::Wildcard(),
- ContentSettingsType::COOKIES, std::string(),
- std::make_unique<base::Value>(test_case.default_content_setting));
- HostContentSettingsMap::ProviderType provider_type;
- switch (test_case.default_content_setting_source) {
- case content_settings::SETTING_SOURCE_POLICY:
- provider_type = HostContentSettingsMap::POLICY_PROVIDER;
- break;
- case content_settings::SETTING_SOURCE_EXTENSION:
- provider_type = HostContentSettingsMap::CUSTOM_EXTENSION_PROVIDER;
- break;
- case content_settings::SETTING_SOURCE_SUPERVISED:
- provider_type = HostContentSettingsMap::SUPERVISED_PROVIDER;
- break;
- case content_settings::SETTING_SOURCE_NONE:
- default:
- provider_type = HostContentSettingsMap::DEFAULT_PROVIDER;
- }
- content_settings::TestUtils::OverrideProvider(map, std::move(provider),
- provider_type);
- }
-
- if (test_case.block_third_party != PrefSetting::kNotSet) {
- bool third_party_value =
- test_case.block_third_party == PrefSetting::kRecommendedOn ||
- test_case.block_third_party == PrefSetting::kEnforcedOn;
- if (test_case.block_third_party_source == PrefSource::kExtension) {
- prefs->SetExtensionPref(prefs::kBlockThirdPartyCookies,
- std::make_unique<base::Value>(third_party_value));
- } else if (test_case.block_third_party_source ==
- PrefSource::kDevicePolicy) {
- prefs->SetManagedPref(prefs::kBlockThirdPartyCookies,
- std::make_unique<base::Value>(third_party_value));
- } else if (test_case.block_third_party_source == PrefSource::kRecommended) {
- prefs->SetRecommendedPref(
- prefs::kBlockThirdPartyCookies,
- std::make_unique<base::Value>(third_party_value));
- }
- }
-}
-
-void AssertManagedCookieStateEqual(const CookieControlsManagedState& a,
- const CookieControlsManagedState b) {
- ASSERT_EQ(a.allow_all.disabled, b.allow_all.disabled);
- ASSERT_EQ(a.allow_all.indicator, b.allow_all.indicator);
- ASSERT_EQ(a.block_third_party_incognito.disabled,
- b.block_third_party_incognito.disabled);
- ASSERT_EQ(a.block_third_party_incognito.indicator,
- b.block_third_party_incognito.indicator);
- ASSERT_EQ(a.block_third_party.disabled, b.block_third_party.disabled);
- ASSERT_EQ(a.block_third_party.indicator, b.block_third_party.indicator);
- ASSERT_EQ(a.block_all.disabled, b.block_all.disabled);
- ASSERT_EQ(a.block_all.indicator, b.block_all.indicator);
- ASSERT_EQ(a.session_only.disabled, b.session_only.disabled);
- ASSERT_EQ(a.session_only.indicator, b.session_only.indicator);
-}
-
-TEST_F(SiteSettingsHelperTest, CookiesManagedState) {
- for (auto test_case : test_cases) {
- TestingProfile profile;
- HostContentSettingsMap* map =
- HostContentSettingsMapFactory::GetForProfile(&profile);
- sync_preferences::TestingPrefServiceSyncable* prefs =
- profile.GetTestingPrefService();
- testing::Message scope_message;
- scope_message << "Content Setting:" << test_case.default_content_setting
- << " Block Third Party:"
- << static_cast<int>(test_case.block_third_party);
- SCOPED_TRACE(scope_message);
- SetupTestConditions(map, prefs, test_case);
- AssertManagedCookieStateEqual(
- site_settings::GetCookieControlsManagedState(&profile),
- test_case.expected_result);
- }
-}
-
-} // namespace
-
} // namespace site_settings
diff --git a/chromium/chrome/browser/ui/webui/settings/tts_handler.cc b/chromium/chrome/browser/ui/webui/settings/tts_handler.cc
index f17e4b3a742..abf485deba1 100644
--- a/chromium/chrome/browser/ui/webui/settings/tts_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/tts_handler.cc
@@ -28,7 +28,7 @@ namespace settings {
TtsHandler::TtsHandler() {}
TtsHandler::~TtsHandler() {
- content::TtsController::GetInstance()->RemoveVoicesChangedDelegate(this);
+ RemoveTtsControllerDelegates();
}
void TtsHandler::HandleGetAllTtsVoiceData(const base::ListValue* args) {
@@ -176,8 +176,7 @@ void TtsHandler::OnJavascriptAllowed() {
}
void TtsHandler::OnJavascriptDisallowed() {
- content::TtsController::GetInstance()->RemoveVoicesChangedDelegate(this);
- content::TtsController::GetInstance()->RemoveUtteranceEventDelegate(this);
+ RemoveTtsControllerDelegates();
}
int TtsHandler::GetVoiceLangMatchScore(const content::VoiceData* voice,
@@ -205,4 +204,9 @@ void TtsHandler::OnTtsEngineAwake(bool success) {
OnVoicesChanged();
}
+void TtsHandler::RemoveTtsControllerDelegates() {
+ content::TtsController::GetInstance()->RemoveVoicesChangedDelegate(this);
+ content::TtsController::GetInstance()->RemoveUtteranceEventDelegate(this);
+}
+
} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/tts_handler.h b/chromium/chrome/browser/ui/webui/settings/tts_handler.h
index a839dee3c0b..fa1820a32ba 100644
--- a/chromium/chrome/browser/ui/webui/settings/tts_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/tts_handler.h
@@ -45,6 +45,7 @@ class TtsHandler : public SettingsPageUIHandler,
void OnTtsEngineAwake(bool success);
int GetVoiceLangMatchScore(const content::VoiceData* voice,
const std::string& app_locale);
+ void RemoveTtsControllerDelegates();
base::WeakPtrFactory<TtsHandler> weak_factory_{this};