summaryrefslogtreecommitdiffstats
path: root/chromium/chrome/browser/ui/webui/settings
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2023-09-05 12:37:36 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2023-10-17 13:53:46 +0000
commit5a424f4a7b188b75da63eb697f63558af0b17f6f (patch)
tree54c427fcbc567dac8181ab5fd22d20e72cc51609 /chromium/chrome/browser/ui/webui/settings
parentacbcf08a6dffdfe90a6eaf661fcd6923f0de2447 (diff)
BASELINE: Update Chromium to 116.0.5845.183
Change-Id: Iaaf57e02c218c93993a5044c659b63674e2c8a12 Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/512320 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/chrome/browser/ui/webui/settings')
-rw-r--r--chromium/chrome/browser/ui/webui/settings/OWNERS6
-rw-r--r--chromium/chrome/browser/ui/webui/settings/about_handler.cc3
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/OWNERS2
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/about_section.cc2
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/accessibility_handler.cc15
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/accessibility_handler.h1
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/accessibility_handler_browsertest.cc53
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/accessibility_section.cc31
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/account_manager_ui_handler.cc2
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/app_management/app_management_uma.h3
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/apps_section.cc15
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/calculator/size_calculator.cc3
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/crostini_section.cc7
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/crostini_section_unittest.cc2
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/cups_printers_handler.cc97
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/cups_printers_handler.h11
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/cups_printers_handler_unittest.cc143
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/device_keyboard_handler.cc4
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/device_keyboard_handler_unittest.cc28
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/device_power_handler.cc11
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/device_power_handler.h2
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/device_power_handler_browsertest.cc3
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/device_section.cc549
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/device_section.h3
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/device_section_unittest.cc2
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/files_page/google_drive_handler_browsertest.cc28
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/files_page/google_drive_page_handler.cc38
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/files_page/google_drive_page_handler.h8
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/files_page/mojom/BUILD.gn5
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/files_page/mojom/one_drive_handler.mojom38
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/files_page/one_drive_page_handler.cc198
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/files_page/one_drive_page_handler.h59
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/files_page/one_drive_page_handler_factory.cc33
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/files_page/one_drive_page_handler_factory.h47
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/files_section.cc30
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.cc8
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.h1
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.mojom2
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider_unittest.cc25
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/internet_handler.cc2
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/internet_handler.h2
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/internet_section.cc47
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/kerberos_accounts_handler.cc8
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/languages_section.cc22
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/main_section.cc6
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/metrics_consent_handler_unittest.cc2
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/multidevice_handler.cc26
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/multidevice_handler.h7
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/multidevice_handler_unittest.cc2
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/os_settings_hats_manager_factory.cc7
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/os_settings_hats_manager_factory.h1
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/os_settings_manager.cc6
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/os_settings_manager.h5
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/os_settings_manager_factory.cc13
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/os_settings_manager_factory.h4
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/os_settings_manager_unittest.cc5
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/os_settings_metrics_provider.cc30
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/os_settings_metrics_provider.h29
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/os_settings_notification_settings_browsertest.cc42
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/os_settings_section.h5
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/os_settings_sections.cc8
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/os_settings_sections.h5
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/os_settings_ui.cc12
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/os_settings_ui.h7
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/parental_controls_handler.cc14
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/pdf_ocr_handler.cc2
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/pdf_ocr_handler.h2
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/pdf_ocr_handler_unittest.cc8
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/people_section.cc8
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/people_section.h6
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/printing_section.cc33
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/privacy_hub_handler_unittest.cc1
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/privacy_section.cc16
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/search/BUILD.gn2
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker.cc138
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker.h56
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker_unittest.cc528
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/settings_user_action_tracker.cc12
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/settings_user_action_tracker.h6
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/settings_user_action_tracker_unittest.cc32
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/tts_handler.cc32
-rw-r--r--chromium/chrome/browser/ui/webui/settings/ash/tts_handler.h2
-rw-r--r--chromium/chrome/browser/ui/webui/settings/captions_handler.cc15
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chrome_cleanup_handler_win.cc304
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chrome_cleanup_handler_win.h96
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/OWNERS2
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom20
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom5
-rw-r--r--chromium/chrome/browser/ui/webui/settings/downloads_handler_unittest.cc3
-rw-r--r--chromium/chrome/browser/ui/webui/settings/extensions_safety_check_handler.cc46
-rw-r--r--chromium/chrome/browser/ui/webui/settings/extensions_safety_check_handler.h43
-rw-r--r--chromium/chrome/browser/ui/webui/settings/extensions_safety_check_handler_unittest.cc36
-rw-r--r--chromium/chrome/browser/ui/webui/settings/hats_handler_unittest.cc5
-rw-r--r--chromium/chrome/browser/ui/webui/settings/metrics_reporting_handler.cc2
-rw-r--r--chromium/chrome/browser/ui/webui/settings/people_handler.cc48
-rw-r--r--chromium/chrome/browser/ui/webui/settings/people_handler.h6
-rw-r--r--chromium/chrome/browser/ui/webui/settings/people_handler_unittest.cc151
-rw-r--r--chromium/chrome/browser/ui/webui/settings/performance_handler.cc53
-rw-r--r--chromium/chrome/browser/ui/webui/settings/performance_handler.h9
-rw-r--r--chromium/chrome/browser/ui/webui/settings/performance_handler_unittest.cc112
-rw-r--r--chromium/chrome/browser/ui/webui/settings/performance_settings_interactive_uitest.cc90
-rw-r--r--chromium/chrome/browser/ui/webui/settings/privacy_sandbox_handler_unittest.cc18
-rw-r--r--chromium/chrome/browser/ui/webui/settings/protocol_handlers_handler.h8
-rw-r--r--chromium/chrome/browser/ui/webui/settings/recent_site_settings_helper.cc2
-rw-r--r--chromium/chrome/browser/ui/webui/settings/recent_site_settings_helper_unittest.cc2
-rw-r--r--chromium/chrome/browser/ui/webui/settings/safety_check_extensions_handler.cc112
-rw-r--r--chromium/chrome/browser/ui/webui/settings/safety_check_extensions_handler.h59
-rw-r--r--chromium/chrome/browser/ui/webui/settings/safety_check_extensions_handler_unittest.cc174
-rw-r--r--chromium/chrome/browser/ui/webui/settings/safety_check_handler.cc122
-rw-r--r--chromium/chrome/browser/ui/webui/settings/safety_check_handler.h3
-rw-r--r--chromium/chrome/browser/ui/webui/settings/safety_check_handler_unittest.cc180
-rw-r--r--chromium/chrome/browser/ui/webui/settings/safety_hub_handler.cc424
-rw-r--r--chromium/chrome/browser/ui/webui/settings/safety_hub_handler.h132
-rw-r--r--chromium/chrome/browser/ui/webui/settings/safety_hub_handler_unittest.cc390
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc3
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h2
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler_unittest.cc25
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc489
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc3
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler_browsertest.cc3
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_security_key_handler.cc9
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_security_key_handler_unittest.cc7
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc6
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_ui.cc61
-rw-r--r--chromium/chrome/browser/ui/webui/settings/settings_utils_mac.mm10
-rw-r--r--chromium/chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.cc15
-rw-r--r--chromium/chrome/browser/ui/webui/settings/site_settings_handler.cc564
-rw-r--r--chromium/chrome/browser/ui/webui/settings/site_settings_handler.h66
-rw-r--r--chromium/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc772
-rw-r--r--chromium/chrome/browser/ui/webui/settings/site_settings_helper.cc222
-rw-r--r--chromium/chrome/browser/ui/webui/settings/site_settings_helper.h54
-rw-r--r--chromium/chrome/browser/ui/webui/settings/site_settings_helper_unittest.cc197
-rw-r--r--chromium/chrome/browser/ui/webui/settings/site_settings_permissions_handler.cc266
-rw-r--r--chromium/chrome/browser/ui/webui/settings/site_settings_permissions_handler.h90
-rw-r--r--chromium/chrome/browser/ui/webui/settings/site_settings_permissions_handler_unittest.cc209
135 files changed, 5313 insertions, 3151 deletions
diff --git a/chromium/chrome/browser/ui/webui/settings/OWNERS b/chromium/chrome/browser/ui/webui/settings/OWNERS
index d9e345949fd..8c3434dc1a1 100644
--- a/chromium/chrome/browser/ui/webui/settings/OWNERS
+++ b/chromium/chrome/browser/ui/webui/settings/OWNERS
@@ -3,15 +3,15 @@ file://chrome/browser/resources/settings/OWNERS
per-file people_handler*=msalama@chromium.org
per-file people_handler*=treib@chromium.org
-per-file extensions_safety_check_handler*=psarouthakis@google.com
+per-file safety_check_extensions_handler*=psarouthakis@google.com
per-file hats_handler*=sauski@google.com
per-file privacy_sandbox_handler*=file://components/privacy_sandbox/OWNERS
per-file *site_settings*=msramek@chromium.org
per-file *site_settings*=sauski@google.com
-per-file site_settings_permissions_handler*=rainhard@chromium.org
+per-file safety_hub_handler*=sideyilmaz@chromium.org,rainhard@chromium.org
per-file safe_browsing_handler*=msramek@chromium.org
per-file safe_browsing_handler*=sauski@google.com
-per-file safety_check_handler*=andzaytsev@google.com,rainhard@chromium.org
+per-file safety_check_handler*=andzaytsev@google.com,rainhard@chromium.org,sideyilmaz@chromium.org
per-file settings_clear_browsing_data_handler*=sauski@google.com
per-file settings_localized_strings_provider*=sauski@google.com
per-file settings_security_key_handler*=file://device/fido/OWNERS
diff --git a/chromium/chrome/browser/ui/webui/settings/about_handler.cc b/chromium/chrome/browser/ui/webui/settings/about_handler.cc
index ab6b211b5b2..76ca56df5bc 100644
--- a/chromium/chrome/browser/ui/webui/settings/about_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/about_handler.cc
@@ -242,6 +242,9 @@ std::string UpdateStatusToString(VersionUpdater::Status status) {
case VersionUpdater::DISABLED_BY_ADMIN:
status_str = "disabled_by_admin";
break;
+ case VersionUpdater::UPDATE_TO_ROLLBACK_VERSION_DISALLOWED:
+ status_str = "update_to_rollback_version_disallowed";
+ break;
case VersionUpdater::NEED_PERMISSION_TO_UPDATE:
status_str = "need_permission_to_update";
break;
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/OWNERS b/chromium/chrome/browser/ui/webui/settings/ash/OWNERS
index 527ce0485c9..f7c4d143805 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/OWNERS
+++ b/chromium/chrome/browser/ui/webui/settings/ash/OWNERS
@@ -1,4 +1,4 @@
-file://chrome/browser/resources/settings/chromeos/OWNERS
+file://chrome/browser/resources/ash/settings/OWNERS
per-file account_manager_*=file://chromeos/ash/components/account_manager/OWNERS
per-file apps_section*=file://chrome/browser/ui/webui/app_management/OWNERS
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/about_section.cc b/chromium/chrome/browser/ui/webui/settings/ash/about_section.cc
index 761256b25a9..c4afddbbda0 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/about_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/about_section.cc
@@ -360,6 +360,8 @@ void AboutSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
{"aboutUpgradeTryAgain", IDS_SETTINGS_UPGRADE_TRY_AGAIN},
{"aboutUpgradeDownloadError", IDS_SETTINGS_UPGRADE_DOWNLOAD_ERROR},
{"aboutUpgradeAdministrator", IDS_SETTINGS_UPGRADE_ADMINISTRATOR_ERROR},
+ {"aboutUpdateToRollbackVersionDisallowed",
+ IDS_SETTINGS_UPDATE_TO_ROLLBACK_VERSION_DISALLOWED},
// About page auto update toggle.
{"aboutConsumerAutoUpdateToggleTitle",
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/accessibility_handler.cc b/chromium/chrome/browser/ui/webui/settings/ash/accessibility_handler.cc
index df10109b28e..5bd9a22184f 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/accessibility_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/accessibility_handler.cc
@@ -24,6 +24,7 @@
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/webui_url_constants.h"
#include "chrome/grit/generated_resources.h"
+#include "chromeos/components/kiosk/kiosk_utils.h"
#include "components/language/core/browser/pref_names.h"
#include "components/language/core/common/locale_util.h"
#include "components/prefs/pref_service.h"
@@ -96,6 +97,10 @@ void AccessibilityHandler::RegisterMessages() {
base::BindRepeating(
&AccessibilityHandler::HandleUpdateBluetoothBrailleDisplayAddress,
base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "getStartupSoundEnabled",
+ base::BindRepeating(&AccessibilityHandler::HandleGetStartupSoundEnabled,
+ base::Unretained(this)));
}
void AccessibilityHandler::HandleShowBrowserAppearanceSettings(
@@ -167,6 +172,14 @@ void AccessibilityHandler::HandleUpdateBluetoothBrailleDisplayAddress(
AccessibilityManager::Get()->UpdateBluetoothBrailleDisplayAddress(address);
}
+void AccessibilityHandler::HandleGetStartupSoundEnabled(
+ const base::Value::List& args) {
+ AllowJavascript();
+ FireWebUIListener(
+ "startup-sound-setting-retrieved",
+ base::Value(AccessibilityManager::Get()->GetStartupSoundEnabled()));
+}
+
void AccessibilityHandler::OpenExtensionOptionsPage(const char extension_id[]) {
const extensions::Extension* extension =
extensions::ExtensionRegistry::Get(profile_)->GetExtensionById(
@@ -180,7 +193,7 @@ void AccessibilityHandler::OpenExtensionOptionsPage(const char extension_id[]) {
// doesn't support SWA but already hide the navigation bar.
bool open_with_os_url_handler =
!crosapi::browser_util::IsAshWebBrowserEnabled() &&
- !profiles::IsKioskSession();
+ !chromeos::IsKioskSession();
if (open_with_os_url_handler) {
DCHECK(extensions::OptionsPageInfo::ShouldOpenInTab(extension));
GURL url = extensions::OptionsPageInfo::GetOptionsPage(extension);
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/accessibility_handler.h b/chromium/chrome/browser/ui/webui/settings/ash/accessibility_handler.h
index 62c349b9b02..15c03bb5844 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/accessibility_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/ash/accessibility_handler.h
@@ -45,6 +45,7 @@ class AccessibilityHandler : public ::settings::SettingsPageUIHandler,
void HandleSetStartupSoundEnabled(const base::Value::List& args);
void HandleUpdateBluetoothBrailleDisplayAddress(
const base::Value::List& args);
+ void HandleGetStartupSoundEnabled(const base::Value::List& args);
void OpenExtensionOptionsPage(const char extension_id[]);
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/accessibility_handler_browsertest.cc b/chromium/chrome/browser/ui/webui/settings/ash/accessibility_handler_browsertest.cc
index 7b32564c780..efe002668b2 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/accessibility_handler_browsertest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/accessibility_handler_browsertest.cc
@@ -10,12 +10,15 @@
#include "ash/constants/ash_features.h"
#include "ash/constants/ash_pref_names.h"
#include "base/containers/adapters.h"
+#include "chrome/browser/ash/accessibility/accessibility_manager.h"
#include "chrome/browser/ash/input_method/mock_input_method_engine.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/profiles/profile_test_util.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/testing_profile.h"
+#include "chromeos/ash/components/browser_context_helper/browser_context_helper.h"
#include "components/language/core/browser/pref_names.h"
#include "components/language/core/common/locale_util.h"
#include "components/prefs/pref_service.h"
@@ -32,6 +35,14 @@ using ::testing::Not;
namespace ash::settings {
+namespace {
+
+// Use a real domain to avoid policy loading problems.
+constexpr char kTestUserName[] = "owner@gmail.com";
+constexpr char kTestUserGaiaId[] = "9876543210";
+
+} // namespace
+
class TestAccessibilityHandler : public AccessibilityHandler {
public:
explicit TestAccessibilityHandler(Profile* profile)
@@ -124,15 +135,38 @@ class AccessibilityHandlerTest : public InProcessBrowserTest {
prefs::kAccessibilityDictationLocale, locale);
}
+ void CreateSession(const AccountId& account_id) {
+ auto* session_manager = session_manager::SessionManager::Get();
+ session_manager->CreateSession(account_id, account_id.GetUserEmail(),
+ false);
+ }
+
+ void StartUserSession(const AccountId& account_id) {
+ profiles::testing::CreateProfileSync(
+ g_browser_process->profile_manager(),
+ BrowserContextHelper::Get()->GetBrowserContextPathByUserIdHash(
+ user_manager::UserManager::Get()
+ ->FindUser(account_id)
+ ->username_hash()));
+
+ auto* session_manager = session_manager::SessionManager::Get();
+ session_manager->NotifyUserProfileLoaded(account_id);
+ session_manager->SessionStarted();
+ }
+
speech::SodaInstaller* soda_installer() {
return speech::SodaInstaller::GetInstance();
}
speech::LanguageCode en_us() { return speech::LanguageCode::kEnUs; }
speech::LanguageCode fr_fr() { return speech::LanguageCode::kFrFr; }
+ content::TestWebUI* web_ui() { return &web_ui_; }
std::unique_ptr<input_method::MockInputMethodEngine> mock_ime_engine_handler_;
+ const AccountId test_account_id_ =
+ AccountId::FromUserEmailGaiaId(kTestUserName, kTestUserGaiaId);
+
private:
std::unique_ptr<TestingProfile> profile_;
std::unique_ptr<TestAccessibilityHandler> handler_;
@@ -303,4 +337,23 @@ IN_PROC_BROWSER_TEST_F(AccessibilityHandlerTest,
}
}
+IN_PROC_BROWSER_TEST_F(AccessibilityHandlerTest, GetStartupSoundEnabled) {
+ CreateSession(test_account_id_);
+ StartUserSession(test_account_id_);
+ AccessibilityManager::Get()->SetStartupSoundEnabled(true);
+
+ size_t call_data_count_before_call = web_ui()->call_data().size();
+
+ base::Value::List empty_args;
+ web_ui()->HandleReceivedMessage("getStartupSoundEnabled", empty_args);
+
+ ASSERT_EQ(call_data_count_before_call + 1u, web_ui()->call_data().size());
+
+ const content::TestWebUI::CallData& call_data =
+ *(web_ui()->call_data()[call_data_count_before_call]);
+ EXPECT_EQ("cr.webUIListenerCallback", call_data.function_name());
+ EXPECT_EQ("startup-sound-setting-retrieved", call_data.arg1()->GetString());
+ EXPECT_TRUE(call_data.arg2()->GetBool());
+}
+
} // namespace ash::settings
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/accessibility_section.cc b/chromium/chrome/browser/ui/webui/settings/ash/accessibility_section.cc
index 5ab81754a76..766eff0c09c 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/accessibility_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/accessibility_section.cc
@@ -643,6 +643,12 @@ void AccessibilitySection::AddLoadTimeData(
IDS_SETTINGS_CHROMEVOX_BRAILLE_TABLE_DESCRIPTION},
{"chromeVoxBrailleTable6Dot", IDS_SETTINGS_CHROMEVOX_BRAILLE_TABLE_6_DOT},
{"chromeVoxBrailleTable8Dot", IDS_SETTINGS_CHROMEVOX_BRAILLE_TABLE_8_DOT},
+ {"chromeVoxBrailleTableNameWithGrade",
+ IDS_SETTINGS_CHROMEVOX_BRAILLE_TABLE_NAME_WITH_GRADE},
+ {"chromeVoxBrailleTableNameWithVariant",
+ IDS_SETTINGS_CHROMEVOX_BRAILLE_TABLE_NAME_WITH_VARIANT},
+ {"chromeVoxBrailleTableNameWithVariantAndGrade",
+ IDS_SETTINGS_CHROMEVOX_BRAILLE_TABLE_NAME_WITH_VARIANT_AND_GRADE},
{"chromeVoxTutorialLabel", IDS_SETTINGS_CHROMEVOX_TUTORIAL_LABEL},
{"clickOnStopDescription", IDS_SETTINGS_CLICK_ON_STOP_DESCRIPTION},
{"clickOnStopLabel", IDS_SETTINGS_CLICK_ON_STOP_LABEL},
@@ -727,15 +733,34 @@ void AccessibilitySection::AddLoadTimeData(
IDS_SETTINGS_ACCESSIBILITY_FOCUS_HIGHLIGHT_DESCRIPTION},
{"focusHighlightLabelSubtext",
IDS_SETTINGS_ACCESSIBILITY_FOCUS_HIGHLIGHT_DESCRIPTION_SUBTEXT},
+ {"focusHighlightDisabledByChromevoxTooltip",
+ IDS_SETTINGS_FOCUS_HIGHLIGHT_DISABLED_BY_CHROMEVOX_TOOLTIP},
{"greyscaleLabel", IDS_SETTINGS_GREYSCALE_LABEL},
{"highContrastDescription", IDS_SETTINGS_HIGH_CONTRAST_DESCRIPTION},
{"highContrastLabel", IDS_SETTINGS_HIGH_CONTRAST_LABEL},
- {"hueRotationLabel", IDS_SETTINGS_HUE_ROTATION_LABEL},
{"protanomalyFilter", IDS_SETTINGS_PROTANOMALY_FILTER},
{"tritanomalyFilter", IDS_SETTINGS_TRITANOMALY_FILTER},
{"deuteranomalyFilter", IDS_SETTINGS_DEUTERANOMALY_FILTER},
{"colorFilteringLabel", IDS_SETTINGS_COLOR_FILTERING_LABEL},
{"colorFilteringDescription", IDS_SETTINGS_COLOR_FILTERING_DESCRIPTION},
+ {"colorFilteringPreviewInstructions",
+ IDS_SETTINGS_COLOR_FILTERING_PREVIEW_INSTRUCTIONS},
+ {"colorFilteringPreviewColorRed",
+ IDS_SETTINGS_COLOR_FILTERING_PREVIEW_COLOR_RED},
+ {"colorFilteringPreviewColorOrange",
+ IDS_SETTINGS_COLOR_FILTERING_PREVIEW_COLOR_ORANGE},
+ {"colorFilteringPreviewColorYellow",
+ IDS_SETTINGS_COLOR_FILTERING_PREVIEW_COLOR_YELLOW},
+ {"colorFilteringPreviewColorGreen",
+ IDS_SETTINGS_COLOR_FILTERING_PREVIEW_COLOR_GREEN},
+ {"colorFilteringPreviewColorCyan",
+ IDS_SETTINGS_COLOR_FILTERING_PREVIEW_COLOR_CYAN},
+ {"colorFilteringPreviewColorBlue",
+ IDS_SETTINGS_COLOR_FILTERING_PREVIEW_COLOR_BLUE},
+ {"colorFilteringPreviewColorPurple",
+ IDS_SETTINGS_COLOR_FILTERING_PREVIEW_COLOR_PURPLE},
+ {"colorFilteringPreviewColorGray",
+ IDS_SETTINGS_COLOR_FILTERING_PREVIEW_COLOR_GRAY},
{"colorVisionDeficiencyTypeLabel",
IDS_SETTINGS_COLOR_VISION_DEFICIENCY_TYPE_LABEL},
{"colorVisionFilterIntensityLabel",
@@ -783,7 +808,6 @@ void AccessibilitySection::AddLoadTimeData(
{"pdfOcrSubtitle", IDS_SETTINGS_PDF_OCR_SUBTITLE},
{"pdfOcrTitle", IDS_SETTINGS_PDF_OCR_TITLE},
{"percentage", IDS_SETTINGS_PERCENTAGE},
- {"saturationLabel", IDS_SETTINGS_SATURATION_LABEL},
{"screenMagnifierDescriptionOff",
IDS_SETTINGS_SCREEN_MAGNIFIER_DESCRIPTION_OFF},
{"screenMagnifierDescriptionOn",
@@ -877,12 +901,13 @@ void AccessibilitySection::AddLoadTimeData(
{"selectToSpeakOptionsLabel",
IDS_SETTINGS_ACCESSIBILITY_SELECT_TO_SPEAK_OPTIONS_LABEL},
{"selectToSpeakTitle", IDS_SETTINGS_ACCESSIBILITY_SELECT_TO_SPEAK_TITLE},
- {"sepiaLabel", IDS_SETTINGS_SEPIA_LABEL},
{"settingsSliderRoleDescription",
IDS_SETTINGS_SLIDER_MIN_MAX_ARIA_ROLE_DESCRIPTION},
{"startupSoundLabel", IDS_SETTINGS_STARTUP_SOUND_LABEL},
{"stickyKeysDescription", IDS_SETTINGS_STICKY_KEYS_DESCRIPTION},
{"stickyKeysLabel", IDS_SETTINGS_STICKY_KEYS_LABEL},
+ {"stickyKeysDisabledByChromevoxTooltip",
+ IDS_SETTINGS_STICKY_KEYS_DISABLED_BY_CHROMEVOX_TOOLTIP},
{"switchAccessActionAssignmentAddAssignmentIconLabel",
IDS_SETTINGS_SWITCH_ACCESS_ACTION_ASSIGNMENT_ADD_ASSIGNMENT_ICON_LABEL},
{"switchAccessActionAssignmentAssignedIconLabel",
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/account_manager_ui_handler.cc b/chromium/chrome/browser/ui/webui/settings/ash/account_manager_ui_handler.cc
index d7c94924258..c27d4ade670 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/account_manager_ui_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/account_manager_ui_handler.cc
@@ -417,7 +417,7 @@ void AccountManagerUIHandler::HandleReauthenticateAccount(
->ShowReauthAccountDialog(
account_manager::AccountManagerFacade::AccountAdditionSource::
kSettingsReauthAccountButton,
- account_email, base::OnceClosure());
+ account_email, base::DoNothing());
}
void AccountManagerUIHandler::HandleMigrateAccount(
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/app_management/app_management_uma.h b/chromium/chrome/browser/ui/webui/settings/ash/app_management/app_management_uma.h
index bfe59801fcc..ef9f8c1ed03 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/app_management/app_management_uma.h
+++ b/chromium/chrome/browser/ui/webui/settings/ash/app_management/app_management_uma.h
@@ -28,7 +28,8 @@ enum class AppManagementEntryPoint {
kNotificationPluginVm = 12,
kAppManagementMainViewBorealis = 13,
kPageInfoView = 14,
- kMaxValue = kPageInfoView,
+ kPrivacyIndicatorsNotificationSettings = 15,
+ kMaxValue = kPrivacyIndicatorsNotificationSettings,
};
} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/apps_section.cc b/chromium/chrome/browser/ui/webui/settings/ash/apps_section.cc
index 50b16dbcb84..439a160a1fb 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/apps_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/apps_section.cc
@@ -197,6 +197,8 @@ const std::vector<SearchConcept>& GetOnStartupSearchConcepts() {
void AddAppManagementStrings(content::WebUIDataSource* html_source) {
static constexpr webui::LocalizedString kLocalizedStrings[] = {
{"appManagementAppDetailsTitle", IDS_APP_MANAGEMENT_APP_DETAILS_TITLE},
+ {"appManagementAppDetailsTooltipSystem",
+ IDS_APP_MANAGEMENT_APP_DETAILS_TOOLTIP_SYSTEM},
{"appManagementAppDetailsTypeAndroid",
IDS_APP_MANAGEMENT_APP_DETAILS_TYPE_ANDROID},
{"appManagementAppDetailsTypeChrome",
@@ -272,6 +274,11 @@ void AddAppManagementStrings(content::WebUIDataSource* html_source) {
{"appManagementNoPermissions",
IDS_APPLICATION_INFO_APP_NO_PERMISSIONS_TEXT},
{"appManagementNotificationsLabel", IDS_APP_MANAGEMENT_NOTIFICATIONS},
+ {"appManagementPermissionAllowed", IDS_APP_MANAGEMENT_PERMISSION_ALLOWED},
+ {"appManagementPermissionAllowedWithDetails",
+ IDS_APP_MANAGEMENT_PERMISSION_ALLOWED_WITH_DETAILS},
+ {"appManagementPermissionAsk", IDS_APP_MANAGEMENT_PERMISSION_ASK},
+ {"appManagementPermissionDenied", IDS_APP_MANAGEMENT_PERMISSION_DENIED},
{"appManagementPermissionsLabel", IDS_APP_MANAGEMENT_PERMISSIONS},
{"appManagementPinToShelfLabel", IDS_APP_MANAGEMENT_PIN_TO_SHELF},
{"appManagementPresetWindowSizesLabel",
@@ -281,6 +288,8 @@ void AddAppManagementStrings(content::WebUIDataSource* html_source) {
{"appManagementPrintingPermissionLabel", IDS_APP_MANAGEMENT_PRINTING},
{"appManagementSearchPrompt", IDS_APP_MANAGEMENT_SEARCH_PROMPT},
{"appManagementStoragePermissionLabel", IDS_APP_MANAGEMENT_STORAGE},
+ {"appManagementSubAppsListHeading",
+ IDS_APP_MANAGEMENT_SUB_APPS_LIST_HEADING},
{"appManagementUninstallLabel", IDS_APP_MANAGEMENT_UNINSTALL_APP},
{"close", IDS_CLOSE},
{"fileHandlingOverflowDialogTitle",
@@ -440,7 +449,7 @@ void AppsSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
// visible once settings app is registered.
html_source->AddBoolean("androidAppsVisible",
arc::IsArcAllowedForProfile(profile()));
- html_source->AddBoolean("havePlayStoreApp", arc::IsPlayStoreAvailable());
+ html_source->AddBoolean("isPlayStoreAvailable", arc::IsPlayStoreAvailable());
html_source->AddBoolean(
"showOsSettingsAppNotificationsRow",
@@ -448,7 +457,7 @@ void AppsSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
html_source->AddBoolean(
"showOsSettingsAppBadgingToggle",
base::FeatureList::IsEnabled(features::kOsSettingsAppBadgingToggle));
- html_source->AddBoolean("showArcvmManageUsb", arc::IsArcVmEnabled());
+ html_source->AddBoolean("isArcVmEnabled", arc::IsArcVmEnabled());
AddAppManagementStrings(html_source);
AddGuestOsStrings(html_source);
@@ -612,7 +621,7 @@ void AppsSection::AddPluginVmLoadTimeData(
};
html_source->AddLocalizedStrings(kLocalizedStrings);
- html_source->AddBoolean("showPluginVm",
+ html_source->AddBoolean("isPluginVmAvailable",
ShowPluginVm(profile(), *pref_service_));
html_source->AddString(
"pluginVmSharedPathsInstructionsLocate",
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/calculator/size_calculator.cc b/chromium/chrome/browser/ui/webui/settings/ash/calculator/size_calculator.cc
index b9e6412eec8..e6e69e8d676 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/calculator/size_calculator.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/calculator/size_calculator.cc
@@ -22,6 +22,7 @@
#include "chrome/browser/ash/crostini/crostini_features.h"
#include "chrome/browser/ash/crostini/crostini_pref_names.h"
#include "chrome/browser/ash/drive/drive_integration_service.h"
+#include "chrome/browser/ash/drive/file_system_util.h"
#include "chrome/browser/ash/file_manager/path_util.h"
#include "chrome/browser/ash/profiles/profile_helper.h"
#include "chrome/browser/browsing_data/browsing_data_file_system_util.h"
@@ -233,7 +234,7 @@ DriveOfflineSizeCalculator::DriveOfflineSizeCalculator(Profile* profile)
DriveOfflineSizeCalculator::~DriveOfflineSizeCalculator() = default;
void DriveOfflineSizeCalculator::PerformCalculation() {
- if (!base::FeatureList::IsEnabled(ash::features::kDriveFsBulkPinning)) {
+ if (!drive::util::IsDriveFsBulkPinningEnabled(profile_)) {
NotifySizeCalculated(0);
return;
}
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/crostini_section.cc b/chromium/chrome/browser/ui/webui/settings/ash/crostini_section.cc
index 64178734b84..b155552a5dc 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/crostini_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/crostini_section.cc
@@ -447,14 +447,15 @@ void CrostiniSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
html_source->AddString("crostiniContainerUpgradeSubtext", "");
}
- // Should the crostini section in settings be displayed?
+ // Crostini section in settings is always displayed.
+ // Should we show that Crostini is supported?
html_source->AddBoolean(
- "showCrostini",
+ "isCrostiniSupported",
crostini::CrostiniFeatures::Get()->CouldBeAllowed(profile_));
// Should we actually enable the button to install it?
html_source->AddBoolean(
- "allowCrostini",
+ "isCrostiniAllowed",
crostini::CrostiniFeatures::Get()->IsAllowedNow(profile_));
// Should Bruschetta be displayed in the settings at all?
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/crostini_section_unittest.cc b/chromium/chrome/browser/ui/webui/settings/ash/crostini_section_unittest.cc
index 0739cdbf817..cf024db68fe 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/crostini_section_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/crostini_section_unittest.cc
@@ -70,7 +70,7 @@ class CrostiniSectionTest : public testing::Test {
private:
content::BrowserTaskEnvironment task_environment_;
std::unique_ptr<TestingProfileManager> profile_manager_;
- base::raw_ptr<TestingProfile> profile_;
+ raw_ptr<TestingProfile, DanglingUntriaged> profile_;
};
// Test that Bruschetta doesn't show up when it's disabled by flags.
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/cups_printers_handler.cc b/chromium/chrome/browser/ui/webui/settings/ash/cups_printers_handler.cc
index eac6cf5dfbb..5342d50f8d5 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/cups_printers_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/cups_printers_handler.cc
@@ -7,6 +7,7 @@
#include <set>
#include <utility>
+#include "ash/constants/ash_features.h"
#include "ash/public/cpp/new_window_delegate.h"
#include "base/containers/flat_map.h"
#include "base/files/file_path.h"
@@ -26,7 +27,6 @@
#include "base/values.h"
#include "chrome/browser/ash/printing/cups_printers_manager.h"
#include "chrome/browser/ash/printing/ppd_provider_factory.h"
-#include "chrome/browser/ash/printing/printer_configurer.h"
#include "chrome/browser/ash/printing/printer_event_tracker.h"
#include "chrome/browser/ash/printing/printer_event_tracker_factory.h"
#include "chrome/browser/ash/printing/printer_info.h"
@@ -81,17 +81,8 @@ constexpr char kNearbyAutomaticPrintersHistogramName[] =
"Printing.CUPS.NearbyNetworkAutomaticPrintersCount";
constexpr char kNearbyDiscoveredPrintersHistogramName[] =
"Printing.CUPS.NearbyNetworkDiscoveredPrintersCount";
-
-void OnRemovedPrinter(const Printer::PrinterProtocol& protocol, bool success) {
- if (success) {
- PRINTER_LOG(DEBUG) << "Printer removal succeeded.";
- } else {
- PRINTER_LOG(DEBUG) << "Printer removal failed.";
- }
-
- UMA_HISTOGRAM_ENUMERATION("Printing.CUPS.PrinterRemoved", protocol,
- Printer::PrinterProtocol::kProtocolMax);
-}
+constexpr char kSavedPrintersCountHistogramName[] =
+ "Printing.CUPS.SavedPrintersCount";
// Log if the IPP attributes request was succesful.
void RecordIppQueryResult(const PrinterQueryResult& result) {
@@ -260,17 +251,14 @@ CupsPrintersHandler::CupsPrintersHandler(Profile* profile,
CupsPrintersManager* printers_manager)
: CupsPrintersHandler(profile,
CreatePpdProvider(profile),
- PrinterConfigurer::Create(profile),
printers_manager) {}
CupsPrintersHandler::CupsPrintersHandler(
Profile* profile,
scoped_refptr<PpdProvider> ppd_provider,
- std::unique_ptr<PrinterConfigurer> printer_configurer,
CupsPrintersManager* printers_manager)
: profile_(profile),
ppd_provider_(ppd_provider),
- printer_configurer_(std::move(printer_configurer)),
printers_manager_(printers_manager),
endpoint_resolver_(
std::make_unique<local_discovery::EndpointResolver>()) {}
@@ -279,11 +267,10 @@ CupsPrintersHandler::CupsPrintersHandler(
std::unique_ptr<CupsPrintersHandler> CupsPrintersHandler::CreateForTesting(
Profile* profile,
scoped_refptr<PpdProvider> ppd_provider,
- std::unique_ptr<PrinterConfigurer> printer_configurer,
CupsPrintersManager* printers_manager) {
// Using 'new' to access non-public constructor.
- return base::WrapUnique(new CupsPrintersHandler(
- profile, ppd_provider, std::move(printer_configurer), printers_manager));
+ return base::WrapUnique(
+ new CupsPrintersHandler(profile, ppd_provider, printers_manager));
}
CupsPrintersHandler::~CupsPrintersHandler() {
@@ -374,6 +361,10 @@ void CupsPrintersHandler::RegisterMessages() {
"openScanningApp",
base::BindRepeating(&CupsPrintersHandler::HandleOpenScanningApp,
base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "requestPrinterStatus",
+ base::BindRepeating(&CupsPrintersHandler::HandleRequestPrinterStatus,
+ base::Unretained(this)));
}
void CupsPrintersHandler::OnJavascriptAllowed() {
@@ -398,6 +389,8 @@ void CupsPrintersHandler::HandleGetCupsSavedPrintersList(
std::vector<Printer> printers =
printers_manager_->GetPrinters(PrinterClass::kSaved);
+ base::UmaHistogramCounts100(kSavedPrintersCountHistogramName,
+ printers.size());
ResolveJavascriptCallback(base::Value(callback_id),
BuildCupsPrintersList(printers));
@@ -467,7 +460,7 @@ void CupsPrintersHandler::HandleRetrieveCupsPrinterPpd(
}
ash::printing::SetUpPrinter(
- printers_manager_, printer_configurer_.get(), *printer,
+ printers_manager_, *printer,
base::BindOnce(&CupsPrintersHandler::OnSetUpPrinter,
weak_factory_.GetWeakPtr(), printer_id, printer_name,
eula));
@@ -599,13 +592,8 @@ void CupsPrintersHandler::HandleRemoveCupsPrinter(
PrinterEventTrackerFactory::GetForBrowserContext(profile_)
->RecordPrinterRemoved(*printer);
- Printer::PrinterProtocol protocol = printer->GetProtocol();
// Printer is deleted here. Do not access after this line.
printers_manager_->RemoveSavedPrinter(printer_id);
-
- DebugDaemonClient::Get()->CupsRemovePrinter(
- printer_id, base::BindOnce(&OnRemovedPrinter, protocol),
- base::DoNothing());
}
void CupsPrintersHandler::HandleGetPrinterInfo(const base::Value::List& args) {
@@ -698,7 +686,7 @@ void CupsPrintersHandler::OnAutoconfQueriedDiscovered(
if (ipp_everywhere) {
PRINTER_LOG(DEBUG) << "Performing autoconf setup";
printer.mutable_ppd_reference()->autoconf = true;
- printer_configurer_->SetUpPrinter(
+ printers_manager_->SetUpPrinter(
printer,
base::BindOnce(&CupsPrintersHandler::OnAddedDiscoveredPrinter,
weak_factory_.GetWeakPtr(), callback_id, printer));
@@ -730,7 +718,7 @@ void CupsPrintersHandler::OnAutoconfQueried(
PRINTER_LOG(DEBUG) << "Could not reach printer";
RejectJavascriptCallback(
base::Value(callback_id),
- base::Value(PrinterSetupResult::kPrinterUnreachable));
+ base::Value(static_cast<int>(PrinterSetupResult::kPrinterUnreachable)));
return;
}
@@ -738,8 +726,9 @@ void CupsPrintersHandler::OnAutoconfQueried(
PRINTER_LOG(DEBUG) << "Could not query printer";
base::Value::Dict reject;
reject.Set("message", "Querying printer failed");
- RejectJavascriptCallback(base::Value(callback_id),
- base::Value(PrinterSetupResult::kFatalError));
+ RejectJavascriptCallback(
+ base::Value(callback_id),
+ base::Value(static_cast<int>(PrinterSetupResult::kFatalError)));
return;
}
@@ -895,7 +884,7 @@ void CupsPrintersHandler::AddOrReconfigurePrinter(const base::Value::List& args,
<< "A configuration option must have been selected to add a printer";
}
- printer_configurer_->SetUpPrinter(
+ printers_manager_->SetUpPrinter(
*printer,
base::BindOnce(&CupsPrintersHandler::OnAddedOrEditedSpecifiedPrinter,
weak_factory_.GetWeakPtr(), callback_id, *printer,
@@ -948,10 +937,10 @@ void CupsPrintersHandler::OnAddedOrEditedPrinterCommon(
case PrinterSetupResult::kMemoryAllocationError:
case PrinterSetupResult::kFatalError:
case PrinterSetupResult::kManualSetupRequired:
+ case PrinterSetupResult::kPrinterRemoved:
PRINTER_LOG(ERROR) << ResultCodeToMessage(result_code);
break;
case PrinterSetupResult::kComponentUnavailable:
- case PrinterSetupResult::kMaxValue:
NOTREACHED() << ResultCodeToMessage(result_code);
break;
}
@@ -967,7 +956,7 @@ void CupsPrintersHandler::OnAddedDiscoveredPrinter(
OnAddedOrEditedPrinterCommon(printer, result_code, /*is_automatic=*/true);
if (result_code == PrinterSetupResult::kSuccess) {
ResolveJavascriptCallback(base::Value(callback_id),
- base::Value(result_code));
+ base::Value(static_cast<int>(result_code)));
} else {
PRINTER_LOG(EVENT) << "Automatic setup failed for discovered printer. "
"Fall back to manual.";
@@ -985,24 +974,28 @@ void CupsPrintersHandler::OnAddedOrEditedSpecifiedPrinter(
if (is_printer_edit && result_code == PrinterSetupResult::kSuccess) {
result_code = PrinterSetupResult::kEditSuccess;
}
- PRINTER_LOG(EVENT) << "Add/Update manual printer: " << result_code;
+ const int result_code_int = static_cast<int>(result_code);
+ PRINTER_LOG(EVENT) << "Add/Update manual printer: " << result_code_int;
OnAddedOrEditedPrinterCommon(printer, result_code, /*is_automatic=*/false);
if (result_code != PrinterSetupResult::kSuccess &&
result_code != PrinterSetupResult::kEditSuccess) {
RejectJavascriptCallback(base::Value(callback_id),
- base::Value(result_code));
+ base::Value(result_code_int));
return;
}
- ResolveJavascriptCallback(base::Value(callback_id), base::Value(result_code));
+ ResolveJavascriptCallback(base::Value(callback_id),
+ base::Value(result_code_int));
}
void CupsPrintersHandler::OnAddOrEditPrinterError(
const std::string& callback_id,
PrinterSetupResult result_code) {
- PRINTER_LOG(EVENT) << "Add printer error: " << result_code;
- RejectJavascriptCallback(base::Value(callback_id), base::Value(result_code));
+ const int result_code_int = static_cast<int>(result_code);
+ PRINTER_LOG(EVENT) << "Add printer error: " << result_code_int;
+ RejectJavascriptCallback(base::Value(callback_id),
+ base::Value(result_code_int));
}
void CupsPrintersHandler::HandleGetCupsPrinterManufacturers(
@@ -1058,7 +1051,7 @@ void CupsPrintersHandler::HandleSelectPPDFile(const base::Value::List& args) {
web_contents ? chrome::FindBrowserWithWebContents(web_contents)
->window()
->GetNativeWindow()
- : gfx::kNullNativeWindow;
+ : gfx::NativeWindow();
ui::SelectFileDialog::FileTypeInfo file_type_info;
file_type_info.extensions.push_back({"ppd"});
@@ -1238,7 +1231,7 @@ void CupsPrintersHandler::HandleAddDiscoveredPrinter(
// can't really do much. Fail the add.
ResolveJavascriptCallback(
base::Value(callback_id),
- base::Value(PrinterSetupResult::kPrinterUnreachable));
+ base::Value(static_cast<int>(PrinterSetupResult::kPrinterUnreachable)));
return;
}
@@ -1247,7 +1240,7 @@ void CupsPrintersHandler::HandleAddDiscoveredPrinter(
// The printer uri was not parsed successfully. Fail the add.
ResolveJavascriptCallback(
base::Value(callback_id),
- base::Value(PrinterSetupResult::kPrinterUnreachable));
+ base::Value(static_cast<int>(PrinterSetupResult::kPrinterUnreachable)));
return;
}
@@ -1257,7 +1250,7 @@ void CupsPrintersHandler::HandleAddDiscoveredPrinter(
PRINTER_LOG(EVENT) << "Start setup of discovered printer";
// If we have something that looks like a ppd reference for this printer,
// try to configure it.
- printer_configurer_->SetUpPrinter(
+ printers_manager_->SetUpPrinter(
*printer,
base::BindOnce(&CupsPrintersHandler::OnAddedDiscoveredPrinter,
weak_factory_.GetWeakPtr(), callback_id, *printer));
@@ -1492,4 +1485,28 @@ void CupsPrintersHandler::HandleOpenScanningApp(const base::Value::List& args) {
chrome::ShowScanningApp(profile_);
}
+void CupsPrintersHandler::HandleRequestPrinterStatus(
+ const base::Value::List& args) {
+ CHECK(features::IsPrinterSettingsPrinterStatusEnabled());
+ AllowJavascript();
+ CHECK_EQ(2U, args.size());
+ const std::string& callback_id = args[0].GetString();
+ const std::string& printer_id = args[1].GetString();
+
+ printers_manager_->FetchPrinterStatus(
+ printer_id, base::BindOnce(&CupsPrintersHandler::OnPrinterStatusReceived,
+ weak_factory_.GetWeakPtr(), callback_id));
+}
+
+void CupsPrintersHandler::OnPrinterStatusReceived(
+ const std::string& callback_id,
+ const chromeos::CupsPrinterStatus& printer_status) {
+ if (!IsJavascriptAllowed()) {
+ return;
+ }
+
+ ResolveJavascriptCallback(base::Value(callback_id),
+ printer_status.ConvertToValue());
+}
+
} // namespace ash::settings
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/cups_printers_handler.h b/chromium/chrome/browser/ui/webui/settings/ash/cups_printers_handler.h
index e993fccf8b1..fd69553f488 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/cups_printers_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/ash/cups_printers_handler.h
@@ -14,9 +14,9 @@
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "chrome/browser/ash/printing/cups_printers_manager.h"
-#include "chrome/browser/ash/printing/printer_configurer.h"
#include "chrome/browser/ash/printing/printer_event_tracker.h"
#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+#include "chromeos/printing/cups_printer_status.h"
#include "chromeos/printing/ppd_provider.h"
#include "chromeos/printing/printer_configuration.h"
#include "printing/printer_query_result.h"
@@ -55,7 +55,6 @@ class CupsPrintersHandler : public ::settings::SettingsPageUIHandler,
static std::unique_ptr<CupsPrintersHandler> CreateForTesting(
Profile* profile,
scoped_refptr<chromeos::PpdProvider> ppd_provider,
- std::unique_ptr<PrinterConfigurer> printer_configurer,
CupsPrintersManager* printers_manager);
CupsPrintersHandler(Profile* profile, CupsPrintersManager* printers_manager);
@@ -75,7 +74,6 @@ class CupsPrintersHandler : public ::settings::SettingsPageUIHandler,
private:
CupsPrintersHandler(Profile* profile,
scoped_refptr<chromeos::PpdProvider> ppd_provider,
- std::unique_ptr<PrinterConfigurer> printer_configurer,
CupsPrintersManager* printers_manager);
// Gets all CUPS printers and return it to WebUI.
@@ -264,6 +262,12 @@ class CupsPrintersHandler : public ::settings::SettingsPageUIHandler,
void HandleOpenScanningApp(const base::Value::List& args);
+ void HandleRequestPrinterStatus(const base::Value::List& args);
+
+ void OnPrinterStatusReceived(
+ const std::string& callback_id,
+ const chromeos::CupsPrinterStatus& printer_status);
+
raw_ptr<Profile, ExperimentalAsh> profile_;
// Discovery support. discovery_active_ tracks whether or not the UI
@@ -278,7 +282,6 @@ class CupsPrintersHandler : public ::settings::SettingsPageUIHandler,
//
// TODO(crbug/757887) - Remove this subtle initialization constraint.
scoped_refptr<chromeos::PpdProvider> ppd_provider_;
- std::unique_ptr<PrinterConfigurer> printer_configurer_;
// Cached list of {printer name, PpdReference} pairs for each manufacturer
// that has been resolved in the lifetime of this object.
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/cups_printers_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/ash/cups_printers_handler_unittest.cc
index 358b75f118b..a61d9b1d887 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/cups_printers_handler_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/cups_printers_handler_unittest.cc
@@ -7,6 +7,7 @@
#include <memory>
#include "ash/public/cpp/test/test_new_window_delegate.h"
+#include "base/containers/flat_set.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
@@ -14,10 +15,10 @@
#include "base/functional/callback_helpers.h"
#include "base/json/json_string_value_serializer.h"
#include "base/memory/raw_ptr.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/test/values_test_util.h"
#include "base/values.h"
-#include "chrome/browser/ash/printing/printing_stubs.h"
-#include "chrome/browser/ash/printing/test_printer_configurer.h"
+#include "chrome/browser/ash/printing/fake_cups_printers_manager.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"
@@ -38,6 +39,15 @@
namespace ash::settings {
+namespace {
+
+constexpr char kSavedPrintersCountHistogramName[] =
+ "Printing.CUPS.SavedPrintersCount";
+
+constexpr char kHandlerFunctionName[] = "handlerFunctionName";
+
+} // namespace
+
using ::chromeos::Printer;
class CupsPrintersHandlerTest;
@@ -55,24 +65,6 @@ void RemovedPrinter(base::OnceClosure quit_closure,
std::move(quit_closure).Run();
}
-class TestCupsPrintersManager : public StubCupsPrintersManager {
- public:
- absl::optional<Printer> GetPrinter(const std::string& id) const override {
- return printer_;
- }
- bool IsPrinterInstalled(const chromeos::Printer& printer) const override {
- return printer_installed_;
- }
-
- // Used to configured our test manager for specific tests.
- void SetPrinter(absl::optional<Printer> printer) { printer_ = printer; }
- void SetPrinterInstalled(bool installed) { printer_installed_ = installed; }
-
- private:
- absl::optional<Printer> printer_ = Printer();
- bool printer_installed_ = true;
-};
-
class FakePpdProvider : public chromeos::PpdProvider {
public:
FakePpdProvider() = default;
@@ -214,7 +206,7 @@ class CupsPrintersHandlerTest : public testing::Test {
void SetUp() override {
printers_handler_ = CupsPrintersHandler::CreateForTesting(
profile_.get(), base::MakeRefCounted<FakePpdProvider>(),
- std::make_unique<TestPrinterConfigurer>(), &printers_manager_);
+ &printers_manager_);
printers_handler_->SetWebUIForTest(&web_ui_);
printers_handler_->RegisterMessages();
printers_handler_->AllowJavascriptForTesting();
@@ -244,9 +236,10 @@ class CupsPrintersHandlerTest : public testing::Test {
printing::PrintBackend::SetPrintBackendForTesting(nullptr);
}
- void CallRetrieveCupsPpd(std::string license_url = "") {
+ void CallRetrieveCupsPpd(const std::string& printer_id,
+ const std::string& license_url = "") {
base::Value::List args;
- args.Append("printer_id");
+ args.Append(printer_id);
args.Append(kPpdPrinterName);
args.Append(license_url);
@@ -254,6 +247,12 @@ class CupsPrintersHandlerTest : public testing::Test {
run_loop_.Run();
}
+ void CallGetCupsSavedPrintersList() {
+ base::Value::List args;
+ args.Append(kHandlerFunctionName);
+ web_ui_.HandleReceivedMessage("getCupsSavedPrintersList", args);
+ }
+
// Get the contents of the file that was downloaded. Return true on success,
// false on error.
bool GetDownloadedPpdContents(std::string& contents) const {
@@ -271,13 +270,14 @@ class CupsPrintersHandlerTest : public testing::Test {
std::unique_ptr<TestingProfile> profile_;
content::TestWebUI web_ui_;
std::unique_ptr<CupsPrintersHandler> printers_handler_;
- TestCupsPrintersManager printers_manager_;
+ FakeCupsPrintersManager printers_manager_;
base::RunLoop run_loop_;
scoped_refptr<printing::TestPrintBackend> print_backend_ =
base::MakeRefCounted<printing::TestPrintBackend>();
raw_ptr<MockNewWindowDelegate, ExperimentalAsh> new_window_delegate_primary_;
std::unique_ptr<TestNewWindowDelegateProvider> new_window_provider_;
base::ScopedTempDir download_dir_;
+ base::HistogramTester histogram_tester_;
const std::string kPpdPrinterName = "printer_name";
const std::string kDefaultPpdData = "PPD data used for testing";
@@ -295,29 +295,21 @@ TEST_F(CupsPrintersHandlerTest, RemoveCorrectPrinter) {
ConciergeClient::InitializeFake(
/*fake_cicerone_client=*/nullptr);
- DebugDaemonClient* client = DebugDaemonClient::Get();
- client->CupsAddAutoConfiguredPrinter("testprinter1", "fakeuri",
- base::BindOnce(&AddedPrinter));
+ Printer printer("id");
+ printers_manager_.SavePrinter(printer);
+ printers_manager_.SetUpPrinter(printer, base::DoNothing());
+ printers_manager_.PrinterInstalled(printer, /*is_automatic=*/true);
const std::string remove_list = R"(
- ["testprinter1", "Test Printer 1"]
+ [")" + printer.id() + R"(", "Test Printer 1"]
)";
std::string error;
base::Value remove_printers = base::test::ParseJson(remove_list);
ASSERT_TRUE(remove_printers.is_list());
+ EXPECT_TRUE(printers_manager_.IsPrinterInstalled(printer));
web_ui_.HandleReceivedMessage("removeCupsPrinter", remove_printers.GetList());
-
- // We expect this printer removal to fail since the printer should have
- // already been removed by the previous call to 'removeCupsPrinter'.
- base::RunLoop run_loop;
- bool expected = true;
- client->CupsRemovePrinter(
- "testprinter1",
- base::BindOnce(&RemovedPrinter, run_loop.QuitClosure(), &expected),
- base::DoNothing());
- run_loop.Run();
- EXPECT_FALSE(expected);
+ EXPECT_FALSE(printers_manager_.IsPrinterInstalled(printer));
profile_.reset();
ConciergeClient::Shutdown();
@@ -329,7 +321,7 @@ TEST_F(CupsPrintersHandlerTest, VerifyOnlyPpdFilesAllowed) {
expected_file_type_info.extensions.push_back({"ppd"});
expected_file_type_info.extensions.push_back({"ppd.gz"});
ui::SelectFileDialog::SetFactory(
- new TestSelectFileDialogFactory(&expected_file_type_info));
+ std::make_unique<TestSelectFileDialogFactory>(&expected_file_type_info));
base::Value::List args;
args.Append("handleFunctionName");
@@ -342,10 +334,11 @@ TEST_F(CupsPrintersHandlerTest, ViewPPD) {
static_cast<FakeDebugDaemonClient*>(DebugDaemonClient::Get())
->SetPpdDataForTesting(kPpdData);
- absl::optional<Printer> printer = printers_manager_.GetPrinter("");
- ASSERT_TRUE(printer);
+ Printer printer("id");
+ printers_manager_.SavePrinter(printer);
+
print_backend_->AddValidPrinter(
- printer->id(),
+ printer.id(),
std::make_unique<printing::PrinterSemanticCapsAndDefaults>(), nullptr);
EXPECT_CALL(*new_window_delegate_primary_,
@@ -355,7 +348,7 @@ TEST_F(CupsPrintersHandlerTest, ViewPPD) {
ash::NewWindowDelegate::Disposition::kSwitchToTab))
.WillOnce(testing::InvokeWithoutArgs(&run_loop_, &base::RunLoop::Quit));
- CallRetrieveCupsPpd();
+ CallRetrieveCupsPpd(printer.id());
// Check for the downloaded PPD file.
std::string contents;
@@ -370,10 +363,11 @@ TEST_F(CupsPrintersHandlerTest, ViewPPDWithLicense) {
static_cast<FakeDebugDaemonClient*>(DebugDaemonClient::Get())
->SetPpdDataForTesting(kPpdDataWithHeader);
- absl::optional<Printer> printer = printers_manager_.GetPrinter("");
- ASSERT_TRUE(printer);
+ Printer printer("id");
+ printers_manager_.SavePrinter(printer);
+
print_backend_->AddValidPrinter(
- printer->id(),
+ printer.id(),
std::make_unique<printing::PrinterSemanticCapsAndDefaults>(), nullptr);
EXPECT_CALL(*new_window_delegate_primary_,
@@ -384,7 +378,7 @@ TEST_F(CupsPrintersHandlerTest, ViewPPDWithLicense) {
.WillOnce(testing::InvokeWithoutArgs(&run_loop_, &base::RunLoop::Quit));
const std::string license_url("chrome://os-credits/xerox-printing-license");
- CallRetrieveCupsPpd(license_url);
+ CallRetrieveCupsPpd(printer.id(), license_url);
// Check that the downloaded PPD file contains the license URL.
std::string contents;
@@ -401,10 +395,11 @@ TEST_F(CupsPrintersHandlerTest, ViewPPDWithLicenseBadPpd) {
static_cast<FakeDebugDaemonClient*>(DebugDaemonClient::Get())
->SetPpdDataForTesting(kPpdData);
- absl::optional<Printer> printer = printers_manager_.GetPrinter("");
- ASSERT_TRUE(printer);
+ Printer printer("id");
+ printers_manager_.SavePrinter(printer);
+
print_backend_->AddValidPrinter(
- printer->id(),
+ printer.id(),
std::make_unique<printing::PrinterSemanticCapsAndDefaults>(), nullptr);
EXPECT_CALL(*new_window_delegate_primary_,
@@ -415,7 +410,7 @@ TEST_F(CupsPrintersHandlerTest, ViewPPDWithLicenseBadPpd) {
.WillOnce(testing::InvokeWithoutArgs(&run_loop_, &base::RunLoop::Quit));
const std::string license_url("chrome://os-credits/xerox-printing-license");
- CallRetrieveCupsPpd(license_url);
+ CallRetrieveCupsPpd(printer.id(), license_url);
// Check that the downloaded PPD file contains the error message.
std::string contents;
@@ -425,9 +420,7 @@ TEST_F(CupsPrintersHandlerTest, ViewPPDWithLicenseBadPpd) {
TEST_F(CupsPrintersHandlerTest, ViewPPDPrinterNotFound) {
// Test the case where the printer is not known to the printer manager.
-
- // Set an empty printer to simluate not being able to find the printer.
- printers_manager_.SetPrinter(absl::optional<Printer>());
+ // No printers were added to CupsPrintersManager.
EXPECT_CALL(*new_window_delegate_primary_,
OpenUrl(testing::Property(&GURL::ExtractFileName,
@@ -436,7 +429,7 @@ TEST_F(CupsPrintersHandlerTest, ViewPPDPrinterNotFound) {
ash::NewWindowDelegate::Disposition::kSwitchToTab))
.WillOnce(testing::InvokeWithoutArgs(&run_loop_, &base::RunLoop::Quit));
- CallRetrieveCupsPpd();
+ CallRetrieveCupsPpd("printer_id");
// Check that the downloaded PPD file contains the error message.
std::string contents;
@@ -450,15 +443,13 @@ TEST_F(CupsPrintersHandlerTest, ViewPPDPrinterNotSetup) {
static_cast<FakeDebugDaemonClient*>(DebugDaemonClient::Get())
->SetPpdDataForTesting(kPpdData);
- absl::optional<Printer> printer = printers_manager_.GetPrinter("");
- ASSERT_TRUE(printer);
+ Printer printer("id");
+ printers_manager_.SavePrinter(printer);
+
print_backend_->AddValidPrinter(
- printer->id(),
+ printer.id(),
std::make_unique<printing::PrinterSemanticCapsAndDefaults>(), nullptr);
- // This will cause our printer to get set up.
- printers_manager_.SetPrinterInstalled(false);
-
EXPECT_CALL(*new_window_delegate_primary_,
OpenUrl(testing::Property(&GURL::ExtractFileName,
testing::StartsWith(kPpdPrinterName)),
@@ -466,7 +457,7 @@ TEST_F(CupsPrintersHandlerTest, ViewPPDPrinterNotSetup) {
ash::NewWindowDelegate::Disposition::kSwitchToTab))
.WillOnce(testing::InvokeWithoutArgs(&run_loop_, &base::RunLoop::Quit));
- CallRetrieveCupsPpd();
+ CallRetrieveCupsPpd(printer.id());
// Check for the downloaded PPD file.
std::string contents;
@@ -480,10 +471,11 @@ TEST_F(CupsPrintersHandlerTest, ViewPPDEmptyPPD) {
static_cast<FakeDebugDaemonClient*>(DebugDaemonClient::Get())
->SetPpdDataForTesting({});
- absl::optional<Printer> printer = printers_manager_.GetPrinter("");
- ASSERT_TRUE(printer);
+ Printer printer("id");
+ printers_manager_.SavePrinter(printer);
+
print_backend_->AddValidPrinter(
- printer->id(),
+ printer.id(),
std::make_unique<printing::PrinterSemanticCapsAndDefaults>(), nullptr);
EXPECT_CALL(*new_window_delegate_primary_,
@@ -493,7 +485,7 @@ TEST_F(CupsPrintersHandlerTest, ViewPPDEmptyPPD) {
ash::NewWindowDelegate::Disposition::kSwitchToTab))
.WillOnce(testing::InvokeWithoutArgs(&run_loop_, &base::RunLoop::Quit));
- CallRetrieveCupsPpd();
+ CallRetrieveCupsPpd(printer.id());
// Check that the downloaded PPD file contains the error message.
std::string contents;
@@ -501,4 +493,21 @@ TEST_F(CupsPrintersHandlerTest, ViewPPDEmptyPPD) {
EXPECT_THAT(contents, testing::HasSubstr(kPpdErrorString));
}
+TEST_F(CupsPrintersHandlerTest, GetSavedPrinters) {
+ Printer printer("id");
+ printer.SetUri("http://printer/uri");
+ printers_manager_.SavePrinter(printer);
+ Printer printer2("id2");
+ printer2.SetUri("http://printer/uri2");
+ printers_manager_.SavePrinter(printer2);
+
+ CallGetCupsSavedPrintersList();
+
+ // Expect 2 printers are recorded to the histogram from the `GetPrinters()`
+ // result.
+ histogram_tester_.ExpectBucketCount(kSavedPrintersCountHistogramName,
+ /*sample=*/2,
+ /*expected_count=*/1);
+}
+
} // namespace ash::settings
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/device_keyboard_handler.cc b/chromium/chrome/browser/ui/webui/settings/ash/device_keyboard_handler.cc
index 95d81ed142d..f688a4469b3 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/device_keyboard_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/device_keyboard_handler.cc
@@ -17,6 +17,7 @@
#include "content/public/browser/web_ui.h"
#include "ui/events/ash/keyboard_capability.h"
#include "ui/events/ash/keyboard_layout_util.h"
+#include "ui/events/devices/keyboard_device.h"
namespace {
@@ -29,10 +30,11 @@ struct KeyboardsStateResult {
KeyboardsStateResult GetKeyboardsState() {
KeyboardsStateResult result;
- for (const ui::InputDevice& keyboard :
+ for (const ui::KeyboardDevice& keyboard :
ui::DeviceDataManager::GetInstance()->GetKeyboardDevices()) {
switch (ash::Shell::Get()->keyboard_capability()->GetDeviceType(keyboard)) {
case ui::KeyboardCapability::DeviceType::kDeviceInternalKeyboard:
+ case ui::KeyboardCapability::DeviceType::kDeviceInternalRevenKeyboard:
result.has_launcher_key = true;
break;
case ui::KeyboardCapability::DeviceType::kDeviceExternalAppleKeyboard:
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/device_keyboard_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/ash/device_keyboard_handler_unittest.cc
index 0b646c941da..4846d198187 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/device_keyboard_handler_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/device_keyboard_handler_unittest.cc
@@ -192,7 +192,7 @@ TEST_F(KeyboardHandlerTest, ExternalKeyboard) {
auto fake_udev = std::make_unique<testing::FakeUdevLoader>();
// Standard internal keyboard on x86 device.
- const ui::InputDevice internal_kbd(
+ const ui::KeyboardDevice internal_kbd(
1, ui::INPUT_DEVICE_INTERNAL, "AT Translated Set 2 keyboard", "",
base::FilePath("/devices/platform/i8042/serio0/input/input1"), 1, 1,
0xab41);
@@ -201,7 +201,7 @@ TEST_F(KeyboardHandlerTest, ExternalKeyboard) {
/*devtype=*/absl::nullopt, /*sysattrs=*/{},
/*properties=*/{});
// Generic external USB keyboard.
- const ui::InputDevice external_generic_kbd(
+ const ui::KeyboardDevice external_generic_kbd(
2, ui::INPUT_DEVICE_USB, "Logitech USB Keyboard", "",
base::FilePath("/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1:1.0/"
"0003:046D:C31C.0007/"
@@ -213,7 +213,7 @@ TEST_F(KeyboardHandlerTest, ExternalKeyboard) {
/*devtype=*/absl::nullopt, /*sysattrs=*/{},
/*properties=*/{});
// Apple keyboard.
- const ui::InputDevice external_apple_kbd(
+ const ui::KeyboardDevice external_apple_kbd(
3, ui::INPUT_DEVICE_USB, "Apple Inc. Apple Keyboard", "",
base::FilePath("/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1:1.1/"
"0003:05AC:026C.000A/input/input3"),
@@ -224,7 +224,7 @@ TEST_F(KeyboardHandlerTest, ExternalKeyboard) {
/*devtype=*/absl::nullopt, /*sysattrs=*/{},
/*properties=*/{});
// Chrome OS external USB keyboard.
- const ui::InputDevice external_chromeos_kbd(
+ const ui::KeyboardDevice external_chromeos_kbd(
4, ui::INPUT_DEVICE_USB, "LG USB Keyboard", "",
base::FilePath("/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1:1.0/"
"0003:04CA:0082.000B/input/input4"),
@@ -236,7 +236,7 @@ TEST_F(KeyboardHandlerTest, ExternalKeyboard) {
/*properties=*/{{"CROS_KEYBOARD_TOP_ROW_LAYOUT", "1"}});
// Chrome OS external Bluetooth keyboard.
- const ui::InputDevice external_bt_chromeos_kbd(
+ const ui::KeyboardDevice external_bt_chromeos_kbd(
4, ui::INPUT_DEVICE_BLUETOOTH, "LG BT Keyboard", "",
base::FilePath("/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1:1.0/"
"0003:04CA:0082.000B/input/input5"),
@@ -261,7 +261,7 @@ TEST_F(KeyboardHandlerTest, ExternalKeyboard) {
// Simulate an external keyboard being connected. We should assume there's a
// Caps Lock and Meta keys now.
device_data_manager_test_api_.SetKeyboardDevices(
- std::vector<ui::InputDevice>{internal_kbd, external_generic_kbd});
+ std::vector<ui::KeyboardDevice>{internal_kbd, external_generic_kbd});
EXPECT_TRUE(HasLauncherKey());
EXPECT_TRUE(HasCapsLock());
EXPECT_TRUE(HasExternalMetaKey());
@@ -271,7 +271,7 @@ TEST_F(KeyboardHandlerTest, ExternalKeyboard) {
// However when connecting external ChromeOS-branded keyboard, we should not
// see neither CapsLock not meta keys.
device_data_manager_test_api_.SetKeyboardDevices(
- std::vector<ui::InputDevice>{internal_kbd, external_chromeos_kbd});
+ std::vector<ui::KeyboardDevice>{internal_kbd, external_chromeos_kbd});
EXPECT_TRUE(HasLauncherKey());
EXPECT_FALSE(HasCapsLock());
EXPECT_FALSE(HasExternalMetaKey());
@@ -281,7 +281,7 @@ TEST_F(KeyboardHandlerTest, ExternalKeyboard) {
// Connecting external Bluetooth ChromeOS-branded keyboard, we should not
// see neither CapsLock not meta keys.
device_data_manager_test_api_.SetKeyboardDevices(
- std::vector<ui::InputDevice>{external_bt_chromeos_kbd});
+ std::vector<ui::KeyboardDevice>{external_bt_chromeos_kbd});
EXPECT_TRUE(HasLauncherKey());
EXPECT_FALSE(HasCapsLock());
EXPECT_FALSE(HasExternalMetaKey());
@@ -291,7 +291,7 @@ TEST_F(KeyboardHandlerTest, ExternalKeyboard) {
// Simulate an external Apple keyboard being connected. Now users can remap
// the command key.
device_data_manager_test_api_.SetKeyboardDevices(
- std::vector<ui::InputDevice>{internal_kbd, external_apple_kbd});
+ std::vector<ui::KeyboardDevice>{internal_kbd, external_apple_kbd});
EXPECT_TRUE(HasLauncherKey());
EXPECT_TRUE(HasCapsLock());
EXPECT_FALSE(HasExternalMetaKey());
@@ -301,7 +301,8 @@ TEST_F(KeyboardHandlerTest, ExternalKeyboard) {
// Simulate two external keyboards (Apple and non-Apple) are connected at the
// same time.
device_data_manager_test_api_.SetKeyboardDevices(
- std::vector<ui::InputDevice>{external_generic_kbd, external_apple_kbd});
+ std::vector<ui::KeyboardDevice>{external_generic_kbd,
+ external_apple_kbd});
EXPECT_FALSE(HasLauncherKey());
EXPECT_TRUE(HasCapsLock());
EXPECT_TRUE(HasExternalMetaKey());
@@ -312,9 +313,10 @@ TEST_F(KeyboardHandlerTest, ExternalKeyboard) {
// device names. Those should also be detected as external keyboards, and
// should show the capslock and external meta remapping.
// https://crbug.com/834594.
- device_data_manager_test_api_.SetKeyboardDevices(std::vector<ui::InputDevice>{
- {6, ui::INPUT_DEVICE_USB, "Topre Corporation Realforce 87", "",
- external_generic_kbd.sys_path, 0x046d, 0xc31c, 0x0111}});
+ device_data_manager_test_api_.SetKeyboardDevices(
+ std::vector<ui::KeyboardDevice>{
+ {6, ui::INPUT_DEVICE_USB, "Topre Corporation Realforce 87", "",
+ external_generic_kbd.sys_path, 0x046d, 0xc31c, 0x0111}});
EXPECT_FALSE(HasLauncherKey());
EXPECT_TRUE(HasCapsLock());
EXPECT_TRUE(HasExternalMetaKey());
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/device_power_handler.cc b/chromium/chrome/browser/ui/webui/settings/ash/device_power_handler.cc
index 77624974e9a..ea31884acae 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/device_power_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/device_power_handler.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <utility>
+#include "ash/constants/ash_features.h"
#include "ash/constants/ash_pref_names.h"
#include "ash/public/cpp/power_utils.h"
#include "base/functional/bind.h"
@@ -115,6 +116,8 @@ const char PowerHandler::kHasLidKey[] = "hasLid";
const char PowerHandler::kAdaptiveChargingKey[] = "adaptiveCharging";
const char PowerHandler::kAdaptiveChargingManagedKey[] =
"adaptiveChargingManaged";
+const char PowerHandler::kBatterySaverFeatureEnabledKey[] =
+ "batterySaverFeatureEnabled";
PowerHandler::TestAPI::TestAPI(PowerHandler* handler) : handler_(handler) {}
@@ -401,7 +404,8 @@ void PowerHandler::SendPowerManagementSettings(bool force) {
prefs_->GetBoolean(ash::prefs::kPowerAdaptiveChargingEnabled);
const bool adaptive_charging_managed =
prefs_->IsManagedPreference(ash::prefs::kPowerAdaptiveChargingEnabled);
-
+ const bool battery_saver_feature_enabled =
+ ash::features::IsBatterySaverAvailable();
// Don't notify the UI if nothing changed.
if (!force && ac_idle_info == last_ac_idle_info_ &&
battery_idle_info == last_battery_idle_info_ &&
@@ -409,7 +413,8 @@ void PowerHandler::SendPowerManagementSettings(bool force) {
lid_closed_controlled == last_lid_closed_controlled_ &&
has_lid == last_has_lid_ &&
adaptive_charging == last_adaptive_charging_ &&
- adaptive_charging_managed == last_adaptive_charging_managed_) {
+ adaptive_charging_managed == last_adaptive_charging_managed_ &&
+ battery_saver_feature_enabled == last_battery_saver_feature_enabled_) {
return;
}
@@ -432,6 +437,7 @@ void PowerHandler::SendPowerManagementSettings(bool force) {
dict.Set(kHasLidKey, has_lid);
dict.Set(kAdaptiveChargingKey, adaptive_charging);
dict.Set(kAdaptiveChargingManagedKey, adaptive_charging_managed);
+ dict.Set(kBatterySaverFeatureEnabledKey, battery_saver_feature_enabled);
FireWebUIListener(kPowerManagementSettingsChangedName, dict);
last_ac_idle_info_ = ac_idle_info;
@@ -441,6 +447,7 @@ void PowerHandler::SendPowerManagementSettings(bool force) {
last_has_lid_ = has_lid;
last_adaptive_charging_ = adaptive_charging;
last_adaptive_charging_managed_ = adaptive_charging_managed;
+ last_battery_saver_feature_enabled_ = battery_saver_feature_enabled;
}
void PowerHandler::OnGotSwitchStates(
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/device_power_handler.h b/chromium/chrome/browser/ui/webui/settings/ash/device_power_handler.h
index 7a271c24898..4088dc9f74a 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/device_power_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/ash/device_power_handler.h
@@ -53,6 +53,7 @@ class PowerHandler : public ::settings::SettingsPageUIHandler,
static const char kHasLidKey[];
static const char kAdaptiveChargingKey[];
static const char kAdaptiveChargingManagedKey[];
+ static const char kBatterySaverFeatureEnabledKey[];
// Class used by tests to interact with PowerHandler internals.
class TestAPI {
@@ -186,6 +187,7 @@ class PowerHandler : public ::settings::SettingsPageUIHandler,
bool last_has_lid_ = true;
bool last_adaptive_charging_ = false;
bool last_adaptive_charging_managed_ = false;
+ bool last_battery_saver_feature_enabled_ = false;
base::WeakPtrFactory<PowerHandler> weak_ptr_factory_{this};
};
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/device_power_handler_browsertest.cc b/chromium/chrome/browser/ui/webui/settings/ash/device_power_handler_browsertest.cc
index 6c4c386b96b..2da9e6b7d58 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/device_power_handler_browsertest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/device_power_handler_browsertest.cc
@@ -78,6 +78,7 @@ class PowerHandlerTest : public InProcessBrowserTest {
bool has_lid = true;
bool adaptive_charging = true;
bool adaptive_charging_managed = false;
+ bool battery_saver_feature_enabled = false;
};
PowerHandlerTest() = default;
@@ -161,6 +162,8 @@ class PowerHandlerTest : public InProcessBrowserTest {
dict.Set(PowerHandler::kAdaptiveChargingKey, settings.adaptive_charging);
dict.Set(PowerHandler::kAdaptiveChargingManagedKey,
settings.adaptive_charging_managed);
+ dict.Set(PowerHandler::kBatterySaverFeatureEnabledKey,
+ settings.battery_saver_feature_enabled);
std::string out;
EXPECT_TRUE(base::JSONWriter::Write(dict, &out));
return out;
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/device_section.cc b/chromium/chrome/browser/ui/webui/settings/ash/device_section.cc
index 4f46daa07ff..fc0fb553b24 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/device_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/device_section.cc
@@ -17,6 +17,7 @@
#include "base/no_destructor.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/ash/drive/file_system_util.h"
#include "chrome/browser/ash/login/demo_mode/demo_session.h"
#include "chrome/browser/ui/webui/settings/ash/device_display_handler.h"
#include "chrome/browser/ui/webui/settings/ash/device_keyboard_handler.h"
@@ -33,6 +34,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 "media/base/media_switches.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/webui/web_ui_util.h"
#include "ui/display/display_features.h"
@@ -49,6 +51,7 @@ using ::chromeos::settings::mojom::kAudioSubpagePath;
using ::chromeos::settings::mojom::kDeviceSectionPath;
using ::chromeos::settings::mojom::kDisplaySubpagePath;
using ::chromeos::settings::mojom::kExternalStorageSubpagePath;
+using ::chromeos::settings::mojom::kGraphicsTabletSubpagePath;
using ::chromeos::settings::mojom::kKeyboardSubpagePath;
using ::chromeos::settings::mojom::kPerDeviceKeyboardRemapKeysSubpagePath;
using ::chromeos::settings::mojom::kPerDeviceKeyboardSubpagePath;
@@ -134,48 +137,57 @@ const std::vector<SearchConcept>& GetDeviceSearchConcepts() {
{.setting = mojom::Setting::kPowerIdleBehaviorWhileOnBattery},
{IDS_OS_SETTINGS_TAG_POWER_IDLE_WHILE_ON_BATTERY_ALT1,
SearchConcept::kAltTagEnd}},
+ {IDS_OS_SETTINGS_TAG_AUDIO_SETTINGS,
+ mojom::kAudioSubpagePath,
+ mojom::SearchResultIcon::kAudio,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSubpage,
+ {.subpage = mojom::Subpage::kAudio},
+ {IDS_OS_SETTINGS_TAG_AUDIO_SETTINGS_ALT1,
+ IDS_OS_SETTINGS_TAG_AUDIO_SETTINGS_ALT2,
+ IDS_OS_SETTINGS_TAG_AUDIO_SETTINGS_ALT3,
+ IDS_OS_SETTINGS_TAG_AUDIO_SETTINGS_ALT4, SearchConcept::kAltTagEnd}},
});
return *tags;
}
const std::vector<SearchConcept>& GetKeyboardSearchConcepts() {
- static const base::NoDestructor<std::vector<SearchConcept>> tags({
- {IDS_OS_SETTINGS_TAG_KEYBOARD,
- mojom::kKeyboardSubpagePath,
- mojom::SearchResultIcon::kKeyboard,
- mojom::SearchResultDefaultRank::kMedium,
- mojom::SearchResultType::kSubpage,
- {.subpage = mojom::Subpage::kKeyboard}},
- {IDS_OS_SETTINGS_TAG_KEYBOARD_AUTO_REPEAT,
- mojom::kKeyboardSubpagePath,
- mojom::SearchResultIcon::kKeyboard,
- mojom::SearchResultDefaultRank::kMedium,
- mojom::SearchResultType::kSetting,
- {.setting = mojom::Setting::kKeyboardAutoRepeat},
- {IDS_OS_SETTINGS_TAG_KEYBOARD_AUTO_REPEAT_ALT1,
- SearchConcept::kAltTagEnd}},
- {IDS_OS_SETTINGS_TAG_KEYBOARD_SHORTCUTS,
- mojom::kKeyboardSubpagePath,
- mojom::SearchResultIcon::kKeyboard,
- mojom::SearchResultDefaultRank::kMedium,
- mojom::SearchResultType::kSetting,
- {.setting = mojom::Setting::kKeyboardShortcuts}},
- {IDS_OS_SETTINGS_TAG_KEYBOARD_FUNCTION_KEYS,
- mojom::kKeyboardSubpagePath,
- mojom::SearchResultIcon::kKeyboard,
- mojom::SearchResultDefaultRank::kMedium,
- mojom::SearchResultType::kSetting,
- {.setting = mojom::Setting::kKeyboardFunctionKeys}},
- {IDS_OS_SETTINGS_TAG_KEYBOARD_DIACRITIC,
- mojom::kKeyboardSubpagePath,
- mojom::SearchResultIcon::kKeyboard,
- mojom::SearchResultDefaultRank::kMedium,
- mojom::SearchResultType::kSetting,
- {.setting = mojom::Setting::kShowDiacritic},
- {IDS_OS_SETTINGS_TAG_KEYBOARD_DIACRITIC1,
- IDS_OS_SETTINGS_TAG_KEYBOARD_DIACRITIC2,
- IDS_OS_SETTINGS_TAG_KEYBOARD_DIACRITIC3, SearchConcept::kAltTagEnd}}
- });
+ static const base::NoDestructor<std::vector<SearchConcept>> tags(
+ {{IDS_OS_SETTINGS_TAG_KEYBOARD,
+ mojom::kKeyboardSubpagePath,
+ mojom::SearchResultIcon::kKeyboard,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSubpage,
+ {.subpage = mojom::Subpage::kKeyboard}},
+ {IDS_OS_SETTINGS_TAG_KEYBOARD_AUTO_REPEAT,
+ mojom::kKeyboardSubpagePath,
+ mojom::SearchResultIcon::kKeyboard,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kKeyboardAutoRepeat},
+ {IDS_OS_SETTINGS_TAG_KEYBOARD_AUTO_REPEAT_ALT1,
+ SearchConcept::kAltTagEnd}},
+ {IDS_OS_SETTINGS_TAG_KEYBOARD_SHORTCUTS,
+ mojom::kKeyboardSubpagePath,
+ mojom::SearchResultIcon::kKeyboard,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kKeyboardShortcuts}},
+ {IDS_OS_SETTINGS_TAG_KEYBOARD_FUNCTION_KEYS,
+ mojom::kKeyboardSubpagePath,
+ mojom::SearchResultIcon::kKeyboard,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kKeyboardFunctionKeys}},
+ {IDS_OS_SETTINGS_TAG_KEYBOARD_DIACRITIC,
+ mojom::kKeyboardSubpagePath,
+ mojom::SearchResultIcon::kKeyboard,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kShowDiacritic},
+ {IDS_OS_SETTINGS_TAG_KEYBOARD_DIACRITIC1,
+ IDS_OS_SETTINGS_TAG_KEYBOARD_DIACRITIC2,
+ IDS_OS_SETTINGS_TAG_KEYBOARD_DIACRITIC3, SearchConcept::kAltTagEnd}}});
return *tags;
}
@@ -557,18 +569,24 @@ const std::vector<SearchConcept>& GetStylusSearchConcepts() {
return *tags;
}
-const std::vector<SearchConcept>& GetAudioSearchConcepts() {
+const std::vector<SearchConcept>& GetAudioPowerSoundsSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
- {IDS_OS_SETTINGS_TAG_AUDIO_SETTINGS,
- mojom::kAudioSubpagePath,
- mojom::SearchResultIcon::kAudio,
- mojom::SearchResultDefaultRank::kMedium,
- mojom::SearchResultType::kSubpage,
- {.subpage = mojom::Subpage::kAudio},
- {IDS_OS_SETTINGS_TAG_AUDIO_SETTINGS_ALT1,
- IDS_OS_SETTINGS_TAG_AUDIO_SETTINGS_ALT2,
- IDS_OS_SETTINGS_TAG_AUDIO_SETTINGS_ALT3,
- IDS_OS_SETTINGS_TAG_AUDIO_SETTINGS_ALT4, SearchConcept::kAltTagEnd}},
+ {
+ IDS_OS_SETTINGS_TAG_CHARGING_SOUNDS,
+ mojom::kAudioSubpagePath,
+ mojom::SearchResultIcon::kAudio,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kChargingSounds},
+ },
+ {
+ IDS_OS_SETTINGS_TAG_LOW_BATTERY_SOUND,
+ mojom::kAudioSubpagePath,
+ mojom::SearchResultIcon::kAudio,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::SearchResultType::kSetting,
+ {.setting = mojom::Setting::kLowBatterySound},
+ },
});
return *tags;
}
@@ -772,21 +790,21 @@ bool IsTouchCalibrationAvailable() {
display::HasExternalTouchscreenDevice();
}
-bool IsDriveFsBulkPinningEnabled() {
- return ash::features::IsDriveFsBulkPinningEnabled();
-}
-
bool IsListAllDisplayModesEnabled() {
return display::features::IsListAllDisplayModesEnabled();
}
+bool IsShowForceRespectUiGainsToggleEnabled() {
+ // No need to show the toggle if UI gains is not going to be ignored.
+ if (!base::FeatureList::IsEnabled(media::kIgnoreUiGains)) {
+ return false;
+ }
+ return base::FeatureList::IsEnabled(media::kShowForceRespectUiGainsToggle);
+}
+
void AddDeviceKeyboardStrings(content::WebUIDataSource* html_source) {
static constexpr webui::LocalizedString keyboard_strings[] = {
{"builtInKeyboardName", IDS_SETTINGS_BUILT_IN_KEYBOARD_NAME},
- {"keyboardBlockMetaFunctionKeyRewrites",
- IDS_SETTINGS_KEYBOARD_BLOCK_META_FUNCTION_KEY_REWRITES},
- {"keyboardBlockMetaFunctionKeyRewritesDescription",
- IDS_SETTINGS_KEYBOARD_BLOCK_META_FUNCTION_KEY_REWRITES_DESCRIPTION},
{"keyboardEnableAutoRepeat", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_ENABLE},
{"keyboardEnableAutoRepeatSubLabel",
IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_ENABLE_SUB_LABEL},
@@ -824,6 +842,8 @@ void AddDeviceKeyboardStrings(content::WebUIDataSource* html_source) {
IDS_SETTINGS_KEYBOARD_REMAP_KEYS_DESCRIPTION},
{"showKeyboardShortcutViewer",
IDS_SETTINGS_KEYBOARD_SHOW_SHORTCUT_VIEWER},
+ {"viewAndCustomizeKeyboardShortcut",
+ IDS_SETTINGS_KEYBOARD_VIEW_AND_CUSTOMIZE_SHORTCUTS},
{"keyboardKeyLauncher", IDS_SETTINGS_KEYBOARD_KEY_LAUNCHER},
{"keyboardKeySearch", IDS_SETTINGS_KEYBOARD_KEY_SEARCH},
{"keyboardRemapRestoreDefaultsLabel",
@@ -849,24 +869,41 @@ void AddDeviceKeyboardStrings(content::WebUIDataSource* html_source) {
IDS_SETTINGS_PER_DEVICE_KEYBOARD_KEY_DISABLED},
{"perDeviceKeyboardKeyEscape",
IDS_SETTINGS_PER_DEVICE_KEYBOARD_KEY_ESCAPE},
- {"perDeviceKeyboardKeyExternalMeta",
- IDS_SETTINGS_PER_DEVICE_KEYBOARD_KEY_EXTERNAL_META},
- {"perDeviceKeyboardKeySearch",
- IDS_SETTINGS_PER_DEVICE_KEYBOARD_KEY_SEARCH},
-
+ {"perDeviceKeyboardKeyMeta", IDS_SETTINGS_PER_DEVICE_KEYBOARD_KEY_META},
};
html_source->AddLocalizedStrings(keyboard_strings);
- html_source->AddLocalizedString(
- "keyboardKeySearch",
- Shell::Get()->keyboard_capability()->HasLauncherButton()
- ? IDS_SETTINGS_KEYBOARD_KEY_LAUNCHER
- : IDS_SETTINGS_KEYBOARD_KEY_SEARCH);
- html_source->AddLocalizedString(
- "keyboardSendFunctionKeysDescription",
- Shell::Get()->keyboard_capability()->HasLauncherButton()
- ? IDS_SETTINGS_KEYBOARD_SEND_FUNCTION_KEYS_LAYOUT2_DESCRIPTION
- : IDS_SETTINGS_KEYBOARD_SEND_FUNCTION_KEYS_DESCRIPTION);
+ if (Shell::Get()->keyboard_capability()->HasLauncherButtonOnAnyKeyboard()) {
+ html_source->AddLocalizedString(
+ "keyboardBlockMetaFunctionKeyRewrites",
+ IDS_SETTINGS_KEYBOARD_BLOCK_META_FUNCTION_KEY_REWRITES_LAUNCHER);
+ html_source->AddLocalizedString(
+ "keyboardBlockMetaFunctionKeyRewritesDescription",
+ IDS_SETTINGS_KEYBOARD_BLOCK_META_FUNCTION_KEY_REWRITES_DESCRIPTION_LAUNCHER);
+ html_source->AddLocalizedString(
+ "perDeviceKeyboardKeySearch",
+ IDS_SETTINGS_PER_DEVICE_KEYBOARD_KEY_LAUNCHER);
+ html_source->AddLocalizedString("keyboardKeySearch",
+ IDS_SETTINGS_KEYBOARD_KEY_LAUNCHER);
+ html_source->AddLocalizedString(
+ "keyboardSendFunctionKeysDescription",
+ IDS_SETTINGS_KEYBOARD_SEND_FUNCTION_KEYS_LAYOUT2_DESCRIPTION);
+ } else {
+ html_source->AddLocalizedString(
+ "keyboardBlockMetaFunctionKeyRewrites",
+ IDS_SETTINGS_KEYBOARD_BLOCK_META_FUNCTION_KEY_REWRITES_SEARCH);
+ html_source->AddLocalizedString(
+ "keyboardBlockMetaFunctionKeyRewritesDescription",
+ IDS_SETTINGS_KEYBOARD_BLOCK_META_FUNCTION_KEY_REWRITES_DESCRIPTION_SEARCH);
+ html_source->AddLocalizedString(
+ "perDeviceKeyboardKeySearch",
+ IDS_SETTINGS_PER_DEVICE_KEYBOARD_KEY_SEARCH);
+ html_source->AddLocalizedString("keyboardKeySearch",
+ IDS_SETTINGS_KEYBOARD_KEY_SEARCH);
+ html_source->AddLocalizedString(
+ "keyboardSendFunctionKeysDescription",
+ IDS_SETTINGS_KEYBOARD_SEND_FUNCTION_KEYS_DESCRIPTION);
+ }
}
void AddDeviceStylusStrings(content::WebUIDataSource* html_source) {
@@ -894,120 +931,6 @@ void AddDeviceStylusStrings(content::WebUIDataSource* html_source) {
stylus_utils::HasInternalStylus());
}
-void AddDeviceDisplayStrings(content::WebUIDataSource* html_source) {
- static constexpr webui::LocalizedString kDisplayStrings[] = {
- {"displayAmbientColorTitle", IDS_SETTINGS_DISPLAY_AMBIENT_COLOR_TITLE},
- {"displayAmbientColorSubtitle",
- IDS_SETTINGS_DISPLAY_AMBIENT_COLOR_SUBTITLE},
- {"displayArrangementTitle", IDS_SETTINGS_DISPLAY_ARRANGEMENT_TITLE},
- {"displayMirror", IDS_SETTINGS_DISPLAY_MIRROR},
- {"displayMirrorDisplayName", IDS_SETTINGS_DISPLAY_MIRROR_DISPLAY_NAME},
- {"displayNightLightLabel", IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_LABEL},
- {"displayNightLightOnAtSunset",
- IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_ON_AT_SUNSET},
- {"displayNightLightOffAtSunrise",
- IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_OFF_AT_SUNRISE},
- {"displayNightLightScheduleCustom",
- IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_CUSTOM},
- {"displayNightLightScheduleLabel",
- IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_LABEL},
- {"displayNightLightScheduleNever",
- IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_NEVER},
- {"displayNightLightScheduleSunsetToSunRise",
- IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_SUNSET_TO_SUNRISE},
- {"displayNightLightTemperatureLabel",
- IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEMPERATURE_LABEL},
- {"displayNightLightTempSliderMaxLabel",
- IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEMP_SLIDER_MAX_LABEL},
- {"displayNightLightTempSliderMinLabel",
- IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEMP_SLIDER_MIN_LABEL},
- {"displayNightLightText", IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEXT},
- {"displayOrientation", IDS_SETTINGS_DISPLAY_ORIENTATION},
- {"displayOrientationAutoRotate",
- IDS_SETTINGS_DISPLAY_ORIENTATION_AUTO_ROTATE},
- {"displayOrientationStandard", IDS_SETTINGS_DISPLAY_ORIENTATION_STANDARD},
- {"displayOverscanInstructions",
- IDS_SETTINGS_DISPLAY_OVERSCAN_INSTRUCTIONS},
- {"displayOverscanPageText", IDS_SETTINGS_DISPLAY_OVERSCAN_TEXT},
- {"displayOverscanPageTitle", IDS_SETTINGS_DISPLAY_OVERSCAN_TITLE},
- {"displayOverscanPosition", IDS_SETTINGS_DISPLAY_OVERSCAN_POSITION},
- {"displayOverscanResize", IDS_SETTINGS_DISPLAY_OVERSCAN_RESIZE},
- {"displayOverscanReset", IDS_SETTINGS_DISPLAY_OVERSCAN_RESET},
- {"displayOverscanSubtitle", IDS_SETTINGS_DISPLAY_OVERSCAN_SUBTITLE},
- {"displayRefreshRateInterlacedMenuItem",
- IDS_SETTINGS_DISPLAY_REFRESH_RATE_INTERLACED_MENU_ITEM},
- {"displayRefreshRateMenuItem",
- IDS_SETTINGS_DISPLAY_REFRESH_RATE_MENU_ITEM},
- {"displayRefreshRateSublabel",
- IDS_SETTINGS_DISPLAY_REFRESH_RATE_SUBLABEL},
- {"displayRefreshRateTitle", IDS_SETTINGS_DISPLAY_REFRESH_RATE_TITLE},
- {"displayResolutionInterlacedMenuItem",
- IDS_SETTINGS_DISPLAY_RESOLUTION_INTERLACED_MENU_ITEM},
- {"displayResolutionMenuItem", IDS_SETTINGS_DISPLAY_RESOLUTION_MENU_ITEM},
- {"displayResolutionOnlyMenuItem",
- IDS_SETTINGS_DISPLAY_RESOLUTION_ONLY_MENU_ITEM},
- {"displayResolutionSublabel", IDS_SETTINGS_DISPLAY_RESOLUTION_SUBLABEL},
- {"displayResolutionText", IDS_SETTINGS_DISPLAY_RESOLUTION_TEXT},
- {"displayResolutionTextBest", IDS_SETTINGS_DISPLAY_RESOLUTION_TEXT_BEST},
- {"displayResolutionTextNative",
- IDS_SETTINGS_DISPLAY_RESOLUTION_TEXT_NATIVE},
- {"displayResolutionTitle", IDS_SETTINGS_DISPLAY_RESOLUTION_TITLE},
- {"displayScreenExtended", IDS_SETTINGS_DISPLAY_SCREEN_EXTENDED},
- {"displayScreenPrimary", IDS_SETTINGS_DISPLAY_SCREEN_PRIMARY},
- {"displayScreenTitle", IDS_SETTINGS_DISPLAY_SCREEN},
- {"displaySizeSliderMaxLabel", IDS_SETTINGS_DISPLAY_ZOOM_SLIDER_MAXIMUM},
- {"displaySizeSliderMinLabel", IDS_SETTINGS_DISPLAY_ZOOM_SLIDER_MINIMUM},
- {"displayTitle", IDS_SETTINGS_DISPLAY_TITLE},
- {"displayTouchCalibrationText",
- IDS_SETTINGS_DISPLAY_TOUCH_CALIBRATION_TEXT},
- {"displayTouchCalibrationTitle",
- IDS_SETTINGS_DISPLAY_TOUCH_CALIBRATION_TITLE},
- {"displayUnifiedDesktop", IDS_SETTINGS_DISPLAY_UNIFIED_DESKTOP},
- {"displayUnifiedDesktopOff", IDS_SETTINGS_DISPLAY_UNIFIED_DESKTOP_OFF},
- {"displayUnifiedDesktopOn", IDS_SETTINGS_DISPLAY_UNIFIED_DESKTOP_ON},
- {"displayZoomLogicalResolutionDefaultText",
- IDS_SETTINGS_DISPLAY_ZOOM_LOGICAL_RESOLUTION_DEFAULT_TEXT},
- {"displayZoomLogicalResolutionText",
- IDS_SETTINGS_DISPLAY_ZOOM_LOGICAL_RESOLUTION_TEXT},
- {"displayZoomNativeLogicalResolutionNativeText",
- IDS_SETTINGS_DISPLAY_ZOOM_LOGICAL_RESOLUTION_NATIVE_TEXT},
- {"displayZoomSublabel", IDS_SETTINGS_DISPLAY_ZOOM_SUBLABEL},
- {"displayZoomTitle", IDS_SETTINGS_DISPLAY_ZOOM_TITLE},
- {"displayZoomValue", IDS_SETTINGS_DISPLAY_ZOOM_VALUE},
- };
- html_source->AddLocalizedStrings(kDisplayStrings);
-
- html_source->AddLocalizedString(
- "displayArrangementText",
- IDS_SETTINGS_DISPLAY_ARRANGEMENT_WITH_KEYBOARD_TEXT);
-
- html_source->AddBoolean(
- "isCryptohomeDataEphemeral",
- user_manager::UserManager::Get()->IsCurrentUserCryptohomeDataEphemeral());
-
- html_source->AddBoolean("unifiedDesktopAvailable",
- IsUnifiedDesktopAvailable());
-
- html_source->AddBoolean("listAllDisplayModes",
- IsListAllDisplayModesEnabled());
-
- html_source->AddBoolean("deviceSupportsAmbientColor",
- DoesDeviceSupportAmbientColor());
-
- html_source->AddBoolean("enableTouchCalibrationSetting",
- IsTouchCalibrationAvailable());
-
- html_source->AddBoolean("enableDriveFsBulkPinning",
- IsDriveFsBulkPinningEnabled());
-
- html_source->AddString("invalidDisplayId",
- base::NumberToString(display::kInvalidDisplayId));
-
- html_source->AddBoolean(
- "allowDisplayAlignmentApi",
- base::FeatureList::IsEnabled(ash::features::kDisplayAlignAssist));
-}
-
void AddDeviceStorageStrings(content::WebUIDataSource* html_source,
bool is_external_storage_page_available) {
static constexpr webui::LocalizedString kStorageStrings[] = {
@@ -1067,6 +990,7 @@ void AddDeviceAudioStrings(content::WebUIDataSource* html_source) {
{"audioDeviceRearMicLabel", IDS_SETTINGS_AUDIO_DEVICE_REAR_MIC_LABEL},
{"audioDeviceUsbLabel", IDS_SETTINGS_AUDIO_DEVICE_USB_LABEL},
{"audioInputDeviceTitle", IDS_SETTINGS_AUDIO_INPUT_DEVICE_TITLE},
+ {"audioInputAllowAGCTitle", IDS_SETTINGS_AUDIO_INPUT_ALLOW_AGC_TITLE},
{"audioInputGainTitle", IDS_SETTINGS_AUDIO_INPUT_GAIN_TITLE},
{"audioInputMuteButtonAriaLabelMuted",
IDS_SETTINGS_AUDIO_INPUT_MUTE_BUTTON_ARIA_LABEL_MUTED},
@@ -1091,9 +1015,19 @@ void AddDeviceAudioStrings(content::WebUIDataSource* html_source) {
{"audioToggleToUnmuteTooltip",
IDS_SETTINGS_AUDIO_TOGGLE_TO_UNMUTE_TOOLTIP},
{"audioVolumeTitle", IDS_SETTINGS_AUDIO_VOLUME_TITLE},
+ {"chargingSoundsLabel",
+ IDS_SETTINGS_AUDIO_DEVICE_SOUNDS_CHARGING_SOUNDS_LABEL},
+ {"deviceStartupSoundLabel",
+ IDS_SETTINGS_AUDIO_DEVICE_SOUNDS_STARTUP_SOUND_LABEL},
+ {"deviceSoundsTitle", IDS_SETTINGS_AUDIO_DEVICE_SOUNDS_TITLE},
+ {"lowBatterySoundLabel",
+ IDS_SETTINGS_AUDIO_DEVICE_SOUNDS_LOW_BATTERY_SOUND_LABEL},
};
html_source->AddLocalizedStrings(kAudioStrings);
+
+ html_source->AddBoolean("areSystemSoundsEnabled",
+ ash::features::AreSystemSoundsEnabled());
}
void AddDevicePowerStrings(content::WebUIDataSource* html_source) {
@@ -1126,11 +1060,17 @@ void AddDevicePowerStrings(content::WebUIDataSource* html_source) {
{"powerSourceLowPowerCharger",
IDS_SETTINGS_POWER_SOURCE_LOW_POWER_CHARGER},
{"powerTitle", IDS_SETTINGS_POWER_TITLE},
+ {"powerBatterySaverLabel", IDS_SETTINGS_POWER_BATTERY_SAVER_LABEL},
+ {"powerBatterySaverSubtext", IDS_SETTINGS_POWER_BATTERY_SAVER_SUBTEXT},
};
html_source->AddLocalizedStrings(kPowerStrings);
- // TODO(b:216035280): create and link to real "learn more" webpage.
- html_source->AddString("powerAdaptiveChargingLearnMoreUrl", u"about://blank");
+ html_source->AddString(
+ "powerAdaptiveChargingLearnMoreUrl",
+ u"https://support.google.com/chromebook/?p=settings_adaptive_charging");
+
+ // TODO(b:278957245): create and link to real "learn more" webpage.
+ html_source->AddString("powerBatterySaverLearnMoreUrl", "about://blank");
}
// Mirrors enum of the same name in enums.xml.
@@ -1159,11 +1099,14 @@ DeviceSection::DeviceSection(Profile* profile,
} else {
updater.AddSearchTags(GetKeyboardSearchConcepts());
}
- if (ShouldShowExternalStorageSettings(profile))
+ if (ShouldShowExternalStorageSettings(profile)) {
updater.AddSearchTags(GetExternalStorageSearchConcepts());
+ }
- if (ash::features::IsAudioSettingsPageEnabled()) {
- updater.AddSearchTags(GetAudioSearchConcepts());
+ // Only when the feature is enabled, the toggle buttons for charging sounds
+ // and the low battery sound will be shown up.
+ if (ash::features::AreSystemSoundsEnabled()) {
+ updater.AddSearchTags(GetAudioPowerSoundsSearchConcepts());
}
chromeos::PowerManagerClient* power_manager_client =
@@ -1173,8 +1116,9 @@ DeviceSection::DeviceSection(Profile* profile,
const absl::optional<power_manager::PowerSupplyProperties>& last_status =
power_manager_client->GetLastStatus();
- if (last_status)
+ if (last_status) {
PowerChanged(*last_status);
+ }
// Determine whether to show laptop lid power settings.
power_manager_client->GetSwitchStates(base::BindOnce(
@@ -1224,13 +1168,15 @@ DeviceSection::~DeviceSection() {
chromeos::PowerManagerClient* power_manager_client =
chromeos::PowerManagerClient::Get();
- if (power_manager_client)
+ if (power_manager_client) {
power_manager_client->RemoveObserver(this);
+ }
NightLightController* night_light_controller =
NightLightController::GetInstance();
- if (night_light_controller)
+ if (night_light_controller) {
night_light_controller->RemoveObserver(this);
+ }
}
void DeviceSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
@@ -1242,7 +1188,20 @@ void DeviceSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
html_source->AddBoolean("isDemoSession", DemoSession::IsDeviceInDemoMode());
+ html_source->AddBoolean(
+ "enableInputDeviceSettingsSplit",
+ base::FeatureList::IsEnabled(ash::features::kInputDeviceSettingsSplit));
+
+ html_source->AddBoolean(
+ "enablePeripheralCustomization",
+ base::FeatureList::IsEnabled(ash::features::kPeripheralCustomization));
+
+ html_source->AddBoolean("enableAltClickAndSixPackCustomization",
+ base::FeatureList::IsEnabled(
+ ash::features::kAltClickAndSixPackCustomization));
+
AddDevicePointersStrings(html_source);
+ AddDeviceGraphicsTabletStrings(html_source);
AddDeviceKeyboardStrings(html_source);
AddDeviceStylusStrings(html_source);
AddDeviceDisplayStrings(html_source);
@@ -1373,6 +1332,16 @@ void DeviceSection::RegisterHierarchy(HierarchyGenerator* generator) const {
mojom::kPerDevicePointingStickSubpagePath);
}
+ if (base::FeatureList::IsEnabled(ash::features::kPeripheralCustomization)) {
+ // TODO(yyhyyh@): Add icon for graphics tablet to replace the temporary
+ // stylus icon.
+ generator->RegisterTopLevelSubpage(IDS_SETTINGS_GRAPHICS_TABLET_TITLE,
+ mojom::Subpage::kGraphicsTablet,
+ mojom::SearchResultIcon::kStylus,
+ mojom::SearchResultDefaultRank::kMedium,
+ mojom::kGraphicsTabletSubpagePath);
+ }
+
// Keyboard.
generator->RegisterTopLevelSubpage(
IDS_SETTINGS_KEYBOARD_TITLE, mojom::Subpage::kKeyboard,
@@ -1439,6 +1408,10 @@ void DeviceSection::RegisterHierarchy(HierarchyGenerator* generator) const {
IDS_SETTINGS_AUDIO_TITLE, mojom::Subpage::kAudio,
mojom::SearchResultIcon::kAudio, mojom::SearchResultDefaultRank::kMedium,
mojom::kAudioSubpagePath);
+ generator->RegisterNestedSetting(mojom::Setting::kChargingSounds,
+ mojom::Subpage::kAudio);
+ generator->RegisterNestedSetting(mojom::Setting::kLowBatterySound,
+ mojom::Subpage::kAudio);
// Power.
generator->RegisterTopLevelSubpage(
@@ -1451,6 +1424,7 @@ void DeviceSection::RegisterHierarchy(HierarchyGenerator* generator) const {
mojom::Setting::kPowerSource,
mojom::Setting::kSleepWhenLaptopLidClosed,
mojom::Setting::kAdaptiveCharging,
+ mojom::Setting::kBatterySaver,
};
RegisterNestedSettingBulk(mojom::Subpage::kPower, kPowerSettings, generator);
}
@@ -1607,16 +1581,18 @@ void DeviceSection::OnGetDisplayLayoutInfo(
SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
// Arrangement UI.
- if (has_multiple_displays || is_mirrored)
+ if (has_multiple_displays || is_mirrored) {
updater.AddSearchTags(GetDisplayArrangementSearchConcepts());
- else
+ } else {
updater.RemoveSearchTags(GetDisplayArrangementSearchConcepts());
+ }
// Mirror toggle.
- if (is_mirrored || (!unified_desktop_mode && has_multiple_displays))
+ if (is_mirrored || (!unified_desktop_mode && has_multiple_displays)) {
updater.AddSearchTags(GetDisplayMirrorSearchConcepts());
- else
+ } else {
updater.RemoveSearchTags(GetDisplayMirrorSearchConcepts());
+ }
// Unified Desktop toggle.
if (unified_desktop_mode ||
@@ -1627,65 +1603,74 @@ void DeviceSection::OnGetDisplayLayoutInfo(
}
// External display settings.
- if (has_external_display)
+ if (has_external_display) {
updater.AddSearchTags(GetDisplayExternalSearchConcepts());
- else
+ } else {
updater.RemoveSearchTags(GetDisplayExternalSearchConcepts());
+ }
// Refresh Rate dropdown.
- if (has_external_display && IsListAllDisplayModesEnabled())
+ if (has_external_display && IsListAllDisplayModesEnabled()) {
updater.AddSearchTags(GetDisplayExternalWithRefreshSearchConcepts());
- else
+ } else {
updater.RemoveSearchTags(GetDisplayExternalWithRefreshSearchConcepts());
+ }
// Orientation settings.
- if (!unified_desktop_mode)
+ if (!unified_desktop_mode) {
updater.AddSearchTags(GetDisplayOrientationSearchConcepts());
- else
+ } else {
updater.RemoveSearchTags(GetDisplayOrientationSearchConcepts());
+ }
// Ambient color settings.
- if (DoesDeviceSupportAmbientColor() && has_internal_display)
+ if (DoesDeviceSupportAmbientColor() && has_internal_display) {
updater.AddSearchTags(GetDisplayAmbientSearchConcepts());
- else
+ } else {
updater.RemoveSearchTags(GetDisplayAmbientSearchConcepts());
+ }
// Touch calibration settings.
- if (IsTouchCalibrationAvailable())
+ if (IsTouchCalibrationAvailable()) {
updater.AddSearchTags(GetDisplayTouchCalibrationSearchConcepts());
- else
+ } else {
updater.RemoveSearchTags(GetDisplayTouchCalibrationSearchConcepts());
+ }
// Night Light on settings.
- if (NightLightController::GetInstance()->GetEnabled())
+ if (NightLightController::GetInstance()->GetEnabled()) {
updater.AddSearchTags(GetDisplayNightLightOnSearchConcepts());
- else
+ } else {
updater.RemoveSearchTags(GetDisplayNightLightOnSearchConcepts());
+ }
}
void DeviceSection::OnGotSwitchStates(
absl::optional<chromeos::PowerManagerClient::SwitchStates> result) {
SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
- if (result &&
- result->lid_state != chromeos::PowerManagerClient::LidState::NOT_PRESENT)
+ if (result && result->lid_state !=
+ chromeos::PowerManagerClient::LidState::NOT_PRESENT) {
updater.AddSearchTags(GetPowerWithLaptopLidSearchConcepts());
+ }
}
void DeviceSection::UpdateStylusSearchTags() {
// If not yet complete, wait for OnDeviceListsComplete() callback.
- if (!ui::DeviceDataManager::GetInstance()->AreDeviceListsComplete())
+ 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 (stylus_utils::HasStylusInput())
+ if (stylus_utils::HasStylusInput()) {
updater.AddSearchTags(GetStylusSearchConcepts());
- else
+ } else {
updater.RemoveSearchTags(GetStylusSearchConcepts());
+ }
}
void DeviceSection::AddDevicePointersStrings(
@@ -1731,7 +1716,17 @@ void DeviceSection::AddDevicePointersStrings(
{"touchpadScrollAccelerationLabel",
IDS_SETTINGS_TOUCHPAD_SCROLL_ACCELERATION_LABEL},
{"touchpadScrollSpeed", IDS_SETTINGS_TOUCHPAD_SCROLL_SPEED_LABEL},
+ {"touchpadSimulateRightClickLabel",
+ IDS_SETTINGS_TOUCHPAD_SIMULATE_RIGHT_CLICK_LABEL},
+ {"touchpadSimulateRightClickOptionAlt",
+ IDS_SETTINGS_TOUCHPAD_SIMULATE_RIGHT_CLICK_OPTION_ALT},
+ {"touchpadSimulateRightClickOptionOff",
+ IDS_SETTINGS_TOUCHPAD_SIMULATE_RIGHT_CLICK_OPTION_OFF},
+ {"touchpadSimulateRightClickOptionSearch",
+ IDS_SETTINGS_TOUCHPAD_SIMULATE_RIGHT_CLICK_OPTION_SEARCH},
{"learnMoreLabel", IDS_SETTINGS_LEARN_MORE_LABEL},
+ {"modifierKeysLabel", IDS_SETTINGS_MODIFIER_KEYS_LABEL},
+ {"otherKeysLabel", IDS_SETTINGS_OTHER_KEYS_LABEL},
};
html_source->AddLocalizedStrings(kPointersStrings);
@@ -1741,14 +1736,132 @@ void DeviceSection::AddDevicePointersStrings(
GetHelpUrlWithBoard(chrome::kHapticFeedbackHelpURL));
html_source->AddBoolean("allowScrollSettings", AreScrollSettingsAllowed());
+}
+
+void DeviceSection::AddDeviceGraphicsTabletStrings(
+ content::WebUIDataSource* html_source) const {
+ static constexpr webui::LocalizedString kGraphicsTabletStrings[] = {
+ {"tabletTitle", IDS_SETTINGS_GRAPHICS_TABLET_TITLE},
+ };
+ html_source->AddLocalizedStrings(kGraphicsTabletStrings);
+}
+
+void DeviceSection::AddDeviceDisplayStrings(
+ content::WebUIDataSource* html_source) const {
+ static constexpr webui::LocalizedString kDisplayStrings[] = {
+ {"displayAmbientColorTitle", IDS_SETTINGS_DISPLAY_AMBIENT_COLOR_TITLE},
+ {"displayAmbientColorSubtitle",
+ IDS_SETTINGS_DISPLAY_AMBIENT_COLOR_SUBTITLE},
+ {"displayArrangementTitle", IDS_SETTINGS_DISPLAY_ARRANGEMENT_TITLE},
+ {"displayMirror", IDS_SETTINGS_DISPLAY_MIRROR},
+ {"displayMirrorDisplayName", IDS_SETTINGS_DISPLAY_MIRROR_DISPLAY_NAME},
+ {"displayNightLightLabel", IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_LABEL},
+ {"displayNightLightOnAtSunset",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_ON_AT_SUNSET},
+ {"displayNightLightOffAtSunrise",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_OFF_AT_SUNRISE},
+ {"displayNightLightScheduleCustom",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_CUSTOM},
+ {"displayNightLightScheduleLabel",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_LABEL},
+ {"displayNightLightScheduleNever",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_NEVER},
+ {"displayNightLightScheduleSunsetToSunRise",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_SUNSET_TO_SUNRISE},
+ {"displayNightLightTemperatureLabel",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEMPERATURE_LABEL},
+ {"displayNightLightTempSliderMaxLabel",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEMP_SLIDER_MAX_LABEL},
+ {"displayNightLightTempSliderMinLabel",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEMP_SLIDER_MIN_LABEL},
+ {"displayNightLightText", IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEXT},
+ {"displayOrientation", IDS_SETTINGS_DISPLAY_ORIENTATION},
+ {"displayOrientationAutoRotate",
+ IDS_SETTINGS_DISPLAY_ORIENTATION_AUTO_ROTATE},
+ {"displayOrientationStandard", IDS_SETTINGS_DISPLAY_ORIENTATION_STANDARD},
+ {"displayOverscanInstructions",
+ IDS_SETTINGS_DISPLAY_OVERSCAN_INSTRUCTIONS},
+ {"displayOverscanPageText", IDS_SETTINGS_DISPLAY_OVERSCAN_TEXT},
+ {"displayOverscanPageTitle", IDS_SETTINGS_DISPLAY_OVERSCAN_TITLE},
+ {"displayOverscanPosition", IDS_SETTINGS_DISPLAY_OVERSCAN_POSITION},
+ {"displayOverscanResize", IDS_SETTINGS_DISPLAY_OVERSCAN_RESIZE},
+ {"displayOverscanReset", IDS_SETTINGS_DISPLAY_OVERSCAN_RESET},
+ {"displayOverscanSubtitle", IDS_SETTINGS_DISPLAY_OVERSCAN_SUBTITLE},
+ {"displayRefreshRateInterlacedMenuItem",
+ IDS_SETTINGS_DISPLAY_REFRESH_RATE_INTERLACED_MENU_ITEM},
+ {"displayRefreshRateMenuItem",
+ IDS_SETTINGS_DISPLAY_REFRESH_RATE_MENU_ITEM},
+ {"displayRefreshRateSublabel",
+ IDS_SETTINGS_DISPLAY_REFRESH_RATE_SUBLABEL},
+ {"displayRefreshRateTitle", IDS_SETTINGS_DISPLAY_REFRESH_RATE_TITLE},
+ {"displayResolutionInterlacedMenuItem",
+ IDS_SETTINGS_DISPLAY_RESOLUTION_INTERLACED_MENU_ITEM},
+ {"displayResolutionMenuItem", IDS_SETTINGS_DISPLAY_RESOLUTION_MENU_ITEM},
+ {"displayResolutionOnlyMenuItem",
+ IDS_SETTINGS_DISPLAY_RESOLUTION_ONLY_MENU_ITEM},
+ {"displayResolutionSublabel", IDS_SETTINGS_DISPLAY_RESOLUTION_SUBLABEL},
+ {"displayResolutionText", IDS_SETTINGS_DISPLAY_RESOLUTION_TEXT},
+ {"displayResolutionTextBest", IDS_SETTINGS_DISPLAY_RESOLUTION_TEXT_BEST},
+ {"displayResolutionTextNative",
+ IDS_SETTINGS_DISPLAY_RESOLUTION_TEXT_NATIVE},
+ {"displayResolutionTitle", IDS_SETTINGS_DISPLAY_RESOLUTION_TITLE},
+ {"displayScreenExtended", IDS_SETTINGS_DISPLAY_SCREEN_EXTENDED},
+ {"displayScreenPrimary", IDS_SETTINGS_DISPLAY_SCREEN_PRIMARY},
+ {"displayScreenTitle", IDS_SETTINGS_DISPLAY_SCREEN},
+ {"displaySizeSliderMaxLabel", IDS_SETTINGS_DISPLAY_ZOOM_SLIDER_MAXIMUM},
+ {"displaySizeSliderMinLabel", IDS_SETTINGS_DISPLAY_ZOOM_SLIDER_MINIMUM},
+ {"displayTitle", IDS_SETTINGS_DISPLAY_TITLE},
+ {"displayTouchCalibrationText",
+ IDS_SETTINGS_DISPLAY_TOUCH_CALIBRATION_TEXT},
+ {"displayTouchCalibrationTitle",
+ IDS_SETTINGS_DISPLAY_TOUCH_CALIBRATION_TITLE},
+ {"displayUnifiedDesktop", IDS_SETTINGS_DISPLAY_UNIFIED_DESKTOP},
+ {"displayUnifiedDesktopOff", IDS_SETTINGS_DISPLAY_UNIFIED_DESKTOP_OFF},
+ {"displayUnifiedDesktopOn", IDS_SETTINGS_DISPLAY_UNIFIED_DESKTOP_ON},
+ {"displayZoomLogicalResolutionDefaultText",
+ IDS_SETTINGS_DISPLAY_ZOOM_LOGICAL_RESOLUTION_DEFAULT_TEXT},
+ {"displayZoomLogicalResolutionText",
+ IDS_SETTINGS_DISPLAY_ZOOM_LOGICAL_RESOLUTION_TEXT},
+ {"displayZoomNativeLogicalResolutionNativeText",
+ IDS_SETTINGS_DISPLAY_ZOOM_LOGICAL_RESOLUTION_NATIVE_TEXT},
+ {"displayZoomSublabel", IDS_SETTINGS_DISPLAY_ZOOM_SUBLABEL},
+ {"displayZoomTitle", IDS_SETTINGS_DISPLAY_ZOOM_TITLE},
+ {"displayZoomValue", IDS_SETTINGS_DISPLAY_ZOOM_VALUE},
+ };
+ html_source->AddLocalizedStrings(kDisplayStrings);
+
+ html_source->AddLocalizedString(
+ "displayArrangementText",
+ IDS_SETTINGS_DISPLAY_ARRANGEMENT_WITH_KEYBOARD_TEXT);
html_source->AddBoolean(
- "enableAudioSettingsPage",
- base::FeatureList::IsEnabled(ash::features::kAudioSettingsPage));
+ "isCryptohomeDataEphemeral",
+ user_manager::UserManager::Get()->IsCurrentUserCryptohomeDataEphemeral());
+
+ html_source->AddBoolean("unifiedDesktopAvailable",
+ IsUnifiedDesktopAvailable());
+
+ html_source->AddBoolean("listAllDisplayModes",
+ IsListAllDisplayModesEnabled());
+
+ html_source->AddBoolean("deviceSupportsAmbientColor",
+ DoesDeviceSupportAmbientColor());
+
+ html_source->AddBoolean("enableForceRespectUiGainsToggle",
+ IsShowForceRespectUiGainsToggleEnabled());
+
+ html_source->AddBoolean("enableTouchCalibrationSetting",
+ IsTouchCalibrationAvailable());
+
+ html_source->AddString("invalidDisplayId",
+ base::NumberToString(display::kInvalidDisplayId));
+
+ html_source->AddBoolean("enableDriveFsBulkPinning",
+ drive::util::IsDriveFsBulkPinningEnabled(profile()));
html_source->AddBoolean(
- "enableInputDeviceSettingsSplit",
- base::FeatureList::IsEnabled(ash::features::kInputDeviceSettingsSplit));
+ "allowDisplayAlignmentApi",
+ base::FeatureList::IsEnabled(ash::features::kDisplayAlignAssist));
}
} // namespace ash::settings
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/device_section.h b/chromium/chrome/browser/ui/webui/settings/ash/device_section.h
index 161fa7b443b..ac36287fddb 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/device_section.h
+++ b/chromium/chrome/browser/ui/webui/settings/ash/device_section.h
@@ -85,6 +85,9 @@ class DeviceSection : public OsSettingsSection,
crosapi::mojom::DisplayLayoutInfoPtr display_layout_info);
void AddDevicePointersStrings(content::WebUIDataSource* html_source);
+ void AddDeviceGraphicsTabletStrings(
+ content::WebUIDataSource* html_source) const;
+ void AddDeviceDisplayStrings(content::WebUIDataSource* html_source) const;
raw_ptr<PrefService, ExperimentalAsh> pref_service_;
system::PointerDeviceObserver pointer_device_observer_;
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/device_section_unittest.cc b/chromium/chrome/browser/ui/webui/settings/ash/device_section_unittest.cc
index 2ab0fb3ec14..b0738305488 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/device_section_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/device_section_unittest.cc
@@ -128,7 +128,7 @@ TEST_F(DeviceSectionTest, SearchResultChangeToSettingsSplitWithFlag) {
// Verify registry updated with regular settings search tags when flag is
// disabled.
TEST_F(DeviceSectionTest, SearchResultChangeBackWithoutFlag) {
- feature_list_.Reset();
+ feature_list_.InitAndDisableFeature(features::kInputDeviceSettingsSplit);
device_section_ = std::make_unique<DeviceSection>(
profile(), search_tag_registry(), pref_service());
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/files_page/google_drive_handler_browsertest.cc b/chromium/chrome/browser/ui/webui/settings/ash/files_page/google_drive_handler_browsertest.cc
index fec2174b837..c9ed2bf30cc 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/files_page/google_drive_handler_browsertest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/files_page/google_drive_handler_browsertest.cc
@@ -182,6 +182,34 @@ IN_PROC_BROWSER_TEST_F(GoogleDriveHandlerTest,
}
IN_PROC_BROWSER_TEST_F(GoogleDriveHandlerTest,
+ NegativeRemainingSpaceReturnsEmptyStrings) {
+ SetUpSearchResultExpectations();
+
+ auto* fake_drivefs = GetFakeDriveFsForProfile(browser()->profile());
+ EXPECT_CALL(*fake_drivefs, GetOfflineFilesSpaceUsage(_))
+ .WillOnce(RunOnceCallback<0>(drive::FILE_ERROR_OK, 1));
+
+ // Each item is 250 MB in size, total required space should be 1 GB.
+ int64_t file_size = 250 << 20;
+ fake_search_query_.SetSearchResults(
+ {{.size = file_size}, {.size = file_size}});
+ fake_search_query_.SetSearchResults(
+ {{.size = file_size}, {.size = file_size}});
+ fake_search_query_.SetSearchResults({});
+
+ // Mock negative remaining space, the required space is 1 GB and the free
+ // space is 500 MB, so the remaining space ends up being -500MB. This is
+ // indicated by a -1 on the UI layer.
+ int64_t free_space = 500 << 20;
+ ash::FakeSpacedClient::Get()->set_free_disk_space(free_space);
+
+ auto google_drive_settings = OpenGoogleDriveSettings();
+ google_drive_settings.AssertBulkPinningSpace(
+ FormatBytesToString(file_size * 4),
+ /*remaining_space=*/"-1");
+}
+
+IN_PROC_BROWSER_TEST_F(GoogleDriveHandlerTest,
TotalPinnedSizeUpdatesValueOnElement) {
SetUpSearchResultExpectations();
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/files_page/google_drive_page_handler.cc b/chromium/chrome/browser/ui/webui/settings/ash/files_page/google_drive_page_handler.cc
index 011bf80aba2..a1b42eb4526 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/files_page/google_drive_page_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/files_page/google_drive_page_handler.cc
@@ -20,9 +20,15 @@ namespace {
google_drive::mojom::StatusPtr CreateStatusPtr(const Progress& progress) {
auto status = google_drive::mojom::Status::New();
status->required_space =
- base::UTF16ToUTF8(ui::FormatBytes(progress.required_space));
- status->remaining_space = base::UTF16ToUTF8(
- ui::FormatBytes(progress.free_space - progress.required_space));
+ (progress.required_space >= 0)
+ ? base::UTF16ToUTF8(ui::FormatBytes(progress.required_space))
+ : "";
+ int64_t remaining_space = progress.free_space - progress.required_space;
+ status->remaining_space =
+ (remaining_space >= 0)
+ ? base::UTF16ToUTF8(
+ ui::FormatBytes(progress.free_space - progress.required_space))
+ : "";
status->stage = progress.stage;
status->is_error = progress.IsError();
return status;
@@ -36,27 +42,25 @@ GoogleDrivePageHandler::GoogleDrivePageHandler(
Profile* profile)
: profile_(profile),
page_(std::move(page)),
- receiver_(this, std::move(receiver)) {}
+ receiver_(this, std::move(receiver)) {
+ if (drive::DriveIntegrationService* const drive_service = GetDriveService()) {
+ drive_service->AddObserver(this);
+ }
+}
GoogleDrivePageHandler::~GoogleDrivePageHandler() {
- auto* const pin_manager = GetPinManager();
- if (!pin_manager || !pin_manager->HasObserver(this)) {
- return;
+ if (drive::DriveIntegrationService* const drive_service = GetDriveService()) {
+ drive_service->RemoveObserver(this);
}
- pin_manager->RemoveObserver(this);
}
void GoogleDrivePageHandler::CalculateRequiredSpace() {
- auto* pin_manager = GetPinManager();
+ auto* const pin_manager = GetPinManager();
if (!pin_manager) {
page_->OnServiceUnavailable();
return;
}
-
NotifyProgress(pin_manager->GetProgress());
- if (!pin_manager->HasObserver(this)) {
- pin_manager->AddObserver(this);
- }
pin_manager->CalculateRequiredSpace();
}
@@ -81,8 +85,8 @@ drivefs::pinning::PinManager* GoogleDrivePageHandler::GetPinManager() {
return service->GetPinManager();
}
-void GoogleDrivePageHandler::OnProgress(const Progress& progress) {
- auto* pin_manager = GetPinManager();
+void GoogleDrivePageHandler::OnBulkPinProgress(const Progress& progress) {
+ auto* const pin_manager = GetPinManager();
if (!pin_manager) {
page_->OnServiceUnavailable();
return;
@@ -91,10 +95,6 @@ void GoogleDrivePageHandler::OnProgress(const Progress& progress) {
NotifyProgress(progress);
}
-void GoogleDrivePageHandler::OnDrop() {
- page_->OnServiceUnavailable();
-}
-
void GoogleDrivePageHandler::GetTotalPinnedSize(
GetTotalPinnedSizeCallback callback) {
if (!GetDriveService()) {
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/files_page/google_drive_page_handler.h b/chromium/chrome/browser/ui/webui/settings/ash/files_page/google_drive_page_handler.h
index f3dfae9bd7b..41d8903873e 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/files_page/google_drive_page_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/ash/files_page/google_drive_page_handler.h
@@ -9,7 +9,6 @@
#include "base/memory/weak_ptr.h"
#include "chrome/browser/ash/drive/drive_integration_service.h"
#include "chrome/browser/ui/webui/settings/ash/files_page/mojom/google_drive_handler.mojom.h"
-#include "chromeos/ash/components/drivefs/drivefs_pin_manager.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
@@ -21,7 +20,7 @@ namespace ash::settings {
// ChromeOS "Google Drive" settings page UI handler.
class GoogleDrivePageHandler : public google_drive::mojom::PageHandler,
- drivefs::pinning::PinManager::Observer {
+ public drive::DriveIntegrationServiceObserver {
public:
GoogleDrivePageHandler(
mojo::PendingReceiver<google_drive::mojom::PageHandler> receiver,
@@ -39,9 +38,8 @@ class GoogleDrivePageHandler : public google_drive::mojom::PageHandler,
void GetTotalPinnedSize(GetTotalPinnedSizeCallback callback) override;
void ClearPinnedFiles(ClearPinnedFilesCallback callback) override;
- // drivefs::pinning::PinManager::Observer
- void OnProgress(const drivefs::pinning::Progress& progress) override;
- void OnDrop() override;
+ // drive::DriveIntegrationServiceObserver
+ void OnBulkPinProgress(const drivefs::pinning::Progress& progress) override;
void NotifyServiceUnavailable();
void NotifyProgress(const drivefs::pinning::Progress& progress);
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/files_page/mojom/BUILD.gn b/chromium/chrome/browser/ui/webui/settings/ash/files_page/mojom/BUILD.gn
index 4e77d3d6c8b..e140c15e5ea 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/files_page/mojom/BUILD.gn
+++ b/chromium/chrome/browser/ui/webui/settings/ash/files_page/mojom/BUILD.gn
@@ -8,7 +8,10 @@ import("//mojo/public/tools/bindings/mojom.gni")
assert(is_chromeos_ash)
mojom("mojom") {
- sources = [ "google_drive_handler.mojom" ]
+ sources = [
+ "google_drive_handler.mojom",
+ "one_drive_handler.mojom",
+ ]
webui_module_path = "/"
use_typescript_sources = true
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/files_page/mojom/one_drive_handler.mojom b/chromium/chrome/browser/ui/webui/settings/ash/files_page/mojom/one_drive_handler.mojom
new file mode 100644
index 00000000000..1f0fb68d1d5
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/ash/files_page/mojom/one_drive_handler.mojom
@@ -0,0 +1,38 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module ash.settings.one_drive.mojom;
+
+// Lives in the browser process. A renderer uses this to create a page handler
+// that enables communication between a renderer and the browser process.
+interface PageHandlerFactory {
+ // Creates a PageHandler and connects it up to the Page.
+ CreatePageHandler(pending_remote<Page> page,
+ pending_receiver<PageHandler> handler);
+};
+
+// Lives in the browser process. A renderer uses this to invoke methods that
+// are implemented in the browser process.
+interface PageHandler {
+ // Returns the email address associated with the currently connected OneDrive
+ // account.
+ GetUserEmailAddress() => (string? email);
+
+ // Emits a OneDrive mount request and returns whether the request succeeded.
+ ConnectToOneDrive() => (bool success);
+
+ // Emits a OneDrive unmount request and returns whether the request succeeded.
+ DisconnectFromOneDrive() => (bool success);
+
+ // Opens Files app on OneDrive folder location.
+ OpenOneDriveFolder() => (bool success);
+};
+
+// Interface for the OneDrive settings. Implemented in Javascript and
+// used by the page handler to send asynchronous updates.
+interface Page {
+ // Invoked on ODFS mount or unmount, indicating that the user has signed in
+ // or out of OneDrive.
+ OnODFSMountOrUnmount();
+};
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/files_page/one_drive_page_handler.cc b/chromium/chrome/browser/ui/webui/settings/ash/files_page/one_drive_page_handler.cc
new file mode 100644
index 00000000000..ca6121c228f
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/ash/files_page/one_drive_page_handler.cc
@@ -0,0 +1,198 @@
+// Copyright 2023 The Chromium Authors
+// 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/ash/files_page/one_drive_page_handler.h"
+
+#include "ash/webui/system_apps/public/system_web_app_type.h"
+#include "chrome/browser/ash/file_manager/open_util.h"
+#include "chrome/browser/ash/file_system_provider/mount_path_util.h"
+#include "chrome/browser/ash/file_system_provider/provided_file_system_info.h"
+#include "chrome/browser/ash/file_system_provider/provided_file_system_interface.h"
+#include "chrome/browser/ash/file_system_provider/service.h"
+#include "chrome/browser/platform_util.h"
+#include "chrome/browser/ui/ash/system_web_apps/system_web_app_ui_utils.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog.h"
+#include "chrome/browser/ui/webui/settings/ash/files_page/mojom/one_drive_handler.mojom.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace ash::settings {
+
+namespace {
+void OnGetEmailAddress(
+ OneDrivePageHandler::GetUserEmailAddressCallback callback,
+ const ash::file_system_provider::Actions& actions,
+ base::File::Error result) {
+ if (result != base::File::Error::FILE_OK) {
+ LOG(ERROR) << "Failed to get actions: " << result;
+ std::move(callback).Run(absl::nullopt);
+ return;
+ }
+ for (const file_system_provider::Action& action : actions) {
+ if (action.id == cloud_upload::kUserEmailActionId) {
+ std::move(callback).Run(action.title);
+ return;
+ }
+ }
+ std::move(callback).Run(absl::nullopt);
+}
+
+void OnShowItemInFolder(
+ OneDrivePageHandler::OpenOneDriveFolderCallback callback,
+ platform_util::OpenOperationResult result) {
+ std::move(callback).Run(result ==
+ platform_util::OpenOperationResult::OPEN_SUCCEEDED);
+}
+} // namespace
+
+OneDrivePageHandler::OneDrivePageHandler(
+ mojo::PendingReceiver<one_drive::mojom::PageHandler> receiver,
+ mojo::PendingRemote<one_drive::mojom::Page> page,
+ Profile* profile)
+ : profile_(profile),
+ page_(std::move(page)),
+ receiver_(this, std::move(receiver)) {
+ file_system_provider::Service* service =
+ file_system_provider::Service::Get(profile_);
+ if (service) {
+ service->AddObserver(this);
+ }
+}
+
+OneDrivePageHandler::~OneDrivePageHandler() {
+ file_system_provider::Service* service =
+ file_system_provider::Service::Get(profile_);
+ if (service) {
+ service->RemoveObserver(this);
+ }
+}
+
+void OneDrivePageHandler::GetUserEmailAddress(
+ GetUserEmailAddressCallback callback) {
+ file_system_provider::Service* service =
+ file_system_provider::Service::Get(profile_);
+ file_system_provider::ProviderId provider_id =
+ file_system_provider::ProviderId::CreateFromExtensionId(
+ file_manager::file_tasks::GetODFSExtensionId(profile_));
+ std::vector<file_system_provider::ProvidedFileSystemInfo>
+ odfs_file_system_infos =
+ service->GetProvidedFileSystemInfoList(provider_id);
+ if (odfs_file_system_infos.size() == 0) {
+ // ODFS is not mounted.
+ std::move(callback).Run(absl::nullopt);
+ return;
+ }
+ if (odfs_file_system_infos.size() != 1u) {
+ LOG(ERROR) << "One and only one filesystem should be mounted for the ODFS "
+ "extension";
+ std::move(callback).Run(absl::nullopt);
+ return;
+ }
+ auto* file_system = service->GetProvidedFileSystem(
+ provider_id, odfs_file_system_infos[0].file_system_id());
+ file_system->GetActions(
+ {base::FilePath("/")},
+ base::BindOnce(&OnGetEmailAddress, std::move(callback)));
+}
+
+void OneDrivePageHandler::ConnectToOneDrive(
+ ConnectToOneDriveCallback callback) {
+ file_system_provider::Service* service =
+ file_system_provider::Service::Get(profile_);
+ // First check if OneDrive is already mounted.
+ CHECK(service);
+ file_system_provider::ProviderId provider_id =
+ file_system_provider::ProviderId::CreateFromExtensionId(
+ file_manager::file_tasks::GetODFSExtensionId(profile_));
+ std::vector<file_system_provider::ProvidedFileSystemInfo>
+ odfs_file_system_infos =
+ service->GetProvidedFileSystemInfoList(provider_id);
+ if (odfs_file_system_infos.size() > 0) {
+ // ODFS is already mounted.
+ std::move(callback).Run(false);
+ return;
+ }
+ // Show connect OneDrive dialog. This method's callback is called before the
+ // user tries to sign in. The connection status is detected separately by
+ // listening to provided file system mount events.
+ Browser* browser =
+ FindSystemWebAppBrowser(profile_, ash::SystemWebAppType::FILE_MANAGER);
+ gfx::NativeWindow modal_parent =
+ browser ? browser->window()->GetNativeWindow() : nullptr;
+ std::move(callback).Run(
+ ash::cloud_upload::ShowConnectOneDriveDialog(modal_parent));
+}
+
+void OneDrivePageHandler::DisconnectFromOneDrive(
+ DisconnectFromOneDriveCallback callback) {
+ file_system_provider::Service* service =
+ file_system_provider::Service::Get(profile_);
+ CHECK(service);
+ file_system_provider::ProviderId provider_id =
+ file_system_provider::ProviderId::CreateFromExtensionId(
+ file_manager::file_tasks::GetODFSExtensionId(profile_));
+ std::vector<file_system_provider::ProvidedFileSystemInfo>
+ odfs_file_system_infos =
+ service->GetProvidedFileSystemInfoList(provider_id);
+ if (odfs_file_system_infos.size() == 0) {
+ // ODFS is not mounted.
+ std::move(callback).Run(false);
+ return;
+ }
+ std::move(callback).Run(
+ service->RequestUnmount(odfs_file_system_infos[0].provider_id(),
+ odfs_file_system_infos[0].file_system_id()));
+}
+
+void OneDrivePageHandler::OpenOneDriveFolder(
+ OpenOneDriveFolderCallback callback) {
+ file_system_provider::Service* service =
+ file_system_provider::Service::Get(profile_);
+ CHECK(service);
+ file_system_provider::ProviderId provider_id =
+ file_system_provider::ProviderId::CreateFromExtensionId(
+ file_manager::file_tasks::GetODFSExtensionId(profile_));
+ std::vector<file_system_provider::ProvidedFileSystemInfo>
+ odfs_file_system_infos =
+ service->GetProvidedFileSystemInfoList(provider_id);
+ if (odfs_file_system_infos.size() == 0) {
+ // ODFS is not mounted.
+ std::move(callback).Run(false);
+ return;
+ }
+ file_manager::util::ShowItemInFolder(
+ profile_, odfs_file_system_infos[0].mount_path(),
+ base::BindOnce(&OnShowItemInFolder, std::move(callback)));
+}
+
+void OneDrivePageHandler::OnProvidedFileSystemMount(
+ const ash::file_system_provider::ProvidedFileSystemInfo& file_system_info,
+ ash::file_system_provider::MountContext context,
+ base::File::Error error) {
+ file_system_provider::ProviderId odfs_provider_id =
+ file_system_provider::ProviderId::CreateFromExtensionId(
+ file_manager::file_tasks::GetODFSExtensionId(profile_));
+ // Only observe successful mount events for ODFS.
+ if (file_system_info.provider_id() != odfs_provider_id ||
+ error != base::File::FILE_OK) {
+ return;
+ }
+ page_->OnODFSMountOrUnmount();
+}
+
+void OneDrivePageHandler::OnProvidedFileSystemUnmount(
+ const ash::file_system_provider::ProvidedFileSystemInfo& file_system_info,
+ base::File::Error error) {
+ file_system_provider::ProviderId odfs_provider_id =
+ file_system_provider::ProviderId::CreateFromExtensionId(
+ file_manager::file_tasks::GetODFSExtensionId(profile_));
+ // Only observe successful unmount events for ODFS.
+ if (file_system_info.provider_id() != odfs_provider_id ||
+ error != base::File::FILE_OK) {
+ return;
+ }
+ page_->OnODFSMountOrUnmount();
+}
+
+} // namespace ash::settings
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/files_page/one_drive_page_handler.h b/chromium/chrome/browser/ui/webui/settings/ash/files_page/one_drive_page_handler.h
new file mode 100644
index 00000000000..371a39e5c1d
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/ash/files_page/one_drive_page_handler.h
@@ -0,0 +1,59 @@
+// Copyright 2023 The Chromium Authors
+// 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_ASH_FILES_PAGE_ONE_DRIVE_PAGE_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_FILES_PAGE_ONE_DRIVE_PAGE_HANDLER_H_
+
+#include "base/memory/raw_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/ash/file_system_provider/observer.h"
+#include "chrome/browser/ui/webui/settings/ash/files_page/mojom/one_drive_handler.mojom.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/bindings/remote.h"
+
+class Profile;
+
+namespace ash::settings {
+
+// Page handler for settings related to OneDrive.
+class OneDrivePageHandler : public one_drive::mojom::PageHandler,
+ public ash::file_system_provider::Observer {
+ public:
+ OneDrivePageHandler(
+ mojo::PendingReceiver<one_drive::mojom::PageHandler> receiver,
+ mojo::PendingRemote<one_drive::mojom::Page> page,
+ Profile* profile);
+
+ OneDrivePageHandler(const OneDrivePageHandler&) = delete;
+ OneDrivePageHandler& operator=(const OneDrivePageHandler&) = delete;
+
+ ~OneDrivePageHandler() override;
+
+ private:
+ // one_drive::mojom::PageHandler:
+ void GetUserEmailAddress(GetUserEmailAddressCallback callback) override;
+ void ConnectToOneDrive(ConnectToOneDriveCallback callback) override;
+ void DisconnectFromOneDrive(DisconnectFromOneDriveCallback callback) override;
+ void OpenOneDriveFolder(OpenOneDriveFolderCallback callback) override;
+
+ // ash::file_system_provider::Observer overrides.
+ void OnProvidedFileSystemMount(
+ const ash::file_system_provider::ProvidedFileSystemInfo& file_system_info,
+ ash::file_system_provider::MountContext context,
+ base::File::Error error) override;
+ void OnProvidedFileSystemUnmount(
+ const ash::file_system_provider::ProvidedFileSystemInfo& file_system_info,
+ base::File::Error error) override;
+
+ raw_ptr<Profile> profile_;
+ mojo::Remote<one_drive::mojom::Page> page_;
+ mojo::Receiver<one_drive::mojom::PageHandler> receiver_{this};
+ base::WeakPtrFactory<OneDrivePageHandler> weak_ptr_factory_{this};
+};
+
+} // namespace ash::settings
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_FILES_PAGE_ONE_DRIVE_PAGE_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/files_page/one_drive_page_handler_factory.cc b/chromium/chrome/browser/ui/webui/settings/ash/files_page/one_drive_page_handler_factory.cc
new file mode 100644
index 00000000000..381da58d31b
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/ash/files_page/one_drive_page_handler_factory.cc
@@ -0,0 +1,33 @@
+// Copyright 2023 The Chromium Authors
+// 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/ash/files_page/one_drive_page_handler_factory.h"
+
+#include <memory>
+#include <utility>
+
+#include "chrome/browser/ui/webui/settings/ash/files_page/mojom/one_drive_handler.mojom.h"
+
+namespace ash::settings {
+
+OneDrivePageHandlerFactory::OneDrivePageHandlerFactory(
+ Profile* profile,
+ mojo::PendingReceiver<one_drive::mojom::PageHandlerFactory> receiver)
+ : profile_(profile) {
+ page_factory_receiver_.Bind(std::move(receiver));
+}
+
+OneDrivePageHandlerFactory::~OneDrivePageHandlerFactory() = default;
+
+void OneDrivePageHandlerFactory::CreatePageHandler(
+ mojo::PendingRemote<one_drive::mojom::Page> page,
+ mojo::PendingReceiver<one_drive::mojom::PageHandler> receiver) {
+ DCHECK(page);
+ DCHECK(!page_handler_);
+
+ page_handler_ = std::make_unique<OneDrivePageHandler>(
+ std::move(receiver), std::move(page), profile_);
+}
+
+} // namespace ash::settings
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/files_page/one_drive_page_handler_factory.h b/chromium/chrome/browser/ui/webui/settings/ash/files_page/one_drive_page_handler_factory.h
new file mode 100644
index 00000000000..36e8d57310e
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/ash/files_page/one_drive_page_handler_factory.h
@@ -0,0 +1,47 @@
+// Copyright 2023 The Chromium Authors
+// 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_ASH_FILES_PAGE_ONE_DRIVE_PAGE_HANDLER_FACTORY_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_FILES_PAGE_ONE_DRIVE_PAGE_HANDLER_FACTORY_H_
+
+#include <memory>
+
+#include "chrome/browser/ui/webui/settings/ash/files_page/mojom/one_drive_handler.mojom.h"
+#include "chrome/browser/ui/webui/settings/ash/files_page/one_drive_page_handler.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+
+class Profile;
+
+namespace ash::settings {
+
+class OneDrivePageHandlerFactory : public one_drive::mojom::PageHandlerFactory {
+ public:
+ OneDrivePageHandlerFactory(
+ Profile* profile,
+ mojo::PendingReceiver<one_drive::mojom::PageHandlerFactory> receiver);
+
+ OneDrivePageHandlerFactory(const OneDrivePageHandlerFactory&) = delete;
+ OneDrivePageHandlerFactory& operator=(const OneDrivePageHandlerFactory&) =
+ delete;
+
+ ~OneDrivePageHandlerFactory() override;
+
+ private:
+ // one_drive::mojom::PageHandlerFactory:
+ void CreatePageHandler(
+ mojo::PendingRemote<one_drive::mojom::Page> page,
+ mojo::PendingReceiver<one_drive::mojom::PageHandler> receiver) override;
+
+ raw_ptr<Profile> profile_;
+
+ std::unique_ptr<OneDrivePageHandler> page_handler_;
+ mojo::Receiver<one_drive::mojom::PageHandlerFactory> page_factory_receiver_{
+ this};
+};
+
+} // namespace ash::settings
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_FILES_PAGE_ONE_DRIVE_PAGE_HANDLER_FACTORY_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/files_section.cc b/chromium/chrome/browser/ui/webui/settings/ash/files_section.cc
index 77df4c5e74f..e24667a82d9 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/files_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/files_section.cc
@@ -8,6 +8,7 @@
#include "base/functional/callback_helpers.h"
#include "base/no_destructor.h"
#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/ash/drive/file_system_util.h"
#include "chrome/browser/ash/profiles/profile_helper.h"
#include "chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog.h"
#include "chrome/browser/ui/webui/ash/smb_shares/smb_handler.h"
@@ -28,6 +29,7 @@ using ::chromeos::settings::mojom::kFilesSectionPath;
using ::chromeos::settings::mojom::kGoogleDriveSubpagePath;
using ::chromeos::settings::mojom::kNetworkFileSharesSubpagePath;
using ::chromeos::settings::mojom::kOfficeFilesSubpagePath;
+using ::chromeos::settings::mojom::kOneDriveSubpagePath;
using ::chromeos::settings::mojom::Section;
using ::chromeos::settings::mojom::Setting;
using ::chromeos::settings::mojom::Subpage;
@@ -76,7 +78,7 @@ const std::vector<SearchConcept>& GetFilesGoogleDriveSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags(
{{IDS_OS_SETTINGS_TAG_FILES_GOOGLE_DRIVE,
mojom::kGoogleDriveSubpagePath,
- mojom::SearchResultIcon::kFolder,
+ mojom::SearchResultIcon::kDrive,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
{.subpage = mojom::Subpage::kGoogleDrive}}});
@@ -90,10 +92,10 @@ FilesSection::FilesSection(Profile* profile,
: OsSettingsSection(profile, search_tag_registry) {
SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
updater.AddSearchTags(GetFilesSearchConcepts());
- if (cloud_upload::IsEligibleAndEnabledUploadOfficeToCloud()) {
+ if (cloud_upload::IsEligibleAndEnabledUploadOfficeToCloud(profile)) {
updater.AddSearchTags(GetFilesOfficeSearchConcepts());
}
- if (ash::features::IsDriveFsBulkPinningEnabled()) {
+ if (drive::util::IsDriveFsBulkPinningEnabled(profile)) {
updater.AddSearchTags(GetFilesGoogleDriveSearchConcepts());
}
}
@@ -104,7 +106,6 @@ void FilesSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
static constexpr webui::LocalizedString kLocalizedStrings[] = {
{"disconnectGoogleDriveAccount", IDS_SETTINGS_DISCONNECT_GOOGLE_DRIVE},
{"googleDriveLabel", IDS_SETTINGS_GOOGLE_DRIVE},
- {"googleDriveEnabledLabel", IDS_SETTINGS_GOOGLE_DRIVE_ENABLED},
{"googleDriveDisabledLabel", IDS_SETTINGS_GOOGLE_DRIVE_DISABLED},
{"googleDriveDisconnectLabel", IDS_SETTINGS_GOOGLE_DRIVE_DISCONNECT},
{"googleDriveConnectLabel", IDS_SETTINGS_GOOGLE_DRIVE_CONNECT},
@@ -125,6 +126,8 @@ void FilesSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
IDS_SETTINGS_GOOGLE_DRIVE_OFFLINE_CLEAR_DIALOG_TITLE},
{"googleDriveOfflineClearDialogBody",
IDS_SETTINGS_GOOGLE_DRIVE_OFFLINE_CLEAR_DIALOG_BODY},
+ {"googleDriveClearStorageDisabledTooltip",
+ IDS_SETTINGS_GOOGLE_DRIVE_OFFLINE_CLEAR_DISABLED_TOOLTIP},
{"googleDriveTurnOffLabel",
IDS_SETTINGS_GOOGLE_DRIVE_TURN_OFF_BUTTON_LABEL},
{"googleDriveTurnOffTitle",
@@ -161,7 +164,14 @@ void FilesSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_MOUNT_INVALID_URL_MESSAGE},
{"smbShareAddedInvalidSSOURLMessage",
IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_MOUNT_INVALID_SSO_URL_MESSAGE},
+ {"oneDriveLabel", IDS_SETTINGS_ONE_DRIVE_LABEL},
+ {"oneDriveSignedInAs", IDS_SETTINGS_ONE_DRIVE_SIGNED_IN_AS},
+ {"oneDriveDisconnected", IDS_SETTINGS_ONE_DRIVE_DISCONNECTED},
+ {"oneDriveConnect", IDS_SETTINGS_ONE_DRIVE_CONNECT},
+ {"oneDriveDisconnect", IDS_SETTINGS_ONE_DRIVE_DISCONNECT},
+ {"openOneDriveFolder", IDS_SETTINGS_OPEN_ONE_DRIVE_FOLDER},
{"officeLabel", IDS_SETTINGS_OFFICE_LABEL},
+ {"officeSublabel", IDS_SETTINGS_OFFICE_SUBLABEL},
{"officeSubpageTitle", IDS_SETTINGS_OFFICE_SUBPAGE_TITLE},
{"alwaysMoveToDrivePreferenceLabel",
IDS_SETTINGS_ALWAYS_MOVE_OFFICE_TO_DRIVE_PREFERENCE_LABEL},
@@ -177,7 +187,7 @@ void FilesSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
html_source->AddBoolean(
"showOfficeSettings",
- cloud_upload::IsEligibleAndEnabledUploadOfficeToCloud());
+ cloud_upload::IsEligibleAndEnabledUploadOfficeToCloud(profile()));
const user_manager::User* user =
ProfileHelper::Get()->GetUserByProfile(profile());
@@ -198,7 +208,7 @@ void FilesSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
}
html_source->AddBoolean("enableDriveFsBulkPinning",
- features::IsDriveFsBulkPinningEnabled());
+ drive::util::IsDriveFsBulkPinningEnabled(profile()));
}
void FilesSection::AddHandlers(content::WebUI* web_ui) {
@@ -237,9 +247,8 @@ void FilesSection::RegisterHierarchy(HierarchyGenerator* generator) const {
mojom::kNetworkFileSharesSubpagePath);
// Office.
- // TODO(b:264314789): Correct string (not smb).
generator->RegisterTopLevelSubpage(
- IDS_SETTINGS_DOWNLOADS_SMB_SHARES, mojom::Subpage::kOfficeFiles,
+ IDS_SETTINGS_OFFICE_LABEL, mojom::Subpage::kOfficeFiles,
mojom::SearchResultIcon::kFolder, mojom::SearchResultDefaultRank::kMedium,
mojom::kNetworkFileSharesSubpagePath);
@@ -247,6 +256,11 @@ void FilesSection::RegisterHierarchy(HierarchyGenerator* generator) const {
IDS_SETTINGS_GOOGLE_DRIVE, mojom::Subpage::kGoogleDrive,
mojom::SearchResultIcon::kFolder, mojom::SearchResultDefaultRank::kMedium,
mojom::kGoogleDriveSubpagePath);
+
+ generator->RegisterTopLevelSubpage(
+ IDS_SETTINGS_ONE_DRIVE_LABEL, mojom::Subpage::kOneDrive,
+ mojom::SearchResultIcon::kFolder, mojom::SearchResultDefaultRank::kMedium,
+ mojom::kOneDriveSubpagePath);
}
} // namespace ash::settings
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.cc b/chromium/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.cc
index 9f0706645fe..070f4c98e5a 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.cc
@@ -69,6 +69,14 @@ void InputDeviceSettingsProvider::BindInterface(
receiver_.Bind(std::move(receiver));
}
+void InputDeviceSettingsProvider::RestoreDefaultKeyboardRemappings(
+ uint32_t device_id) {
+ DCHECK(features::IsInputDeviceSettingsSplitEnabled());
+ DCHECK(InputDeviceSettingsController::Get());
+ InputDeviceSettingsController::Get()->RestoreDefaultKeyboardRemappings(
+ device_id);
+}
+
void InputDeviceSettingsProvider::SetKeyboardSettings(
uint32_t device_id,
::ash::mojom::KeyboardSettingsPtr settings) {
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.h b/chromium/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.h
index 8e97fe3aed0..c2b1bb47c7e 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.h
+++ b/chromium/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.h
@@ -38,6 +38,7 @@ class InputDeviceSettingsProvider
override;
void ObserveMouseSettings(
mojo::PendingRemote<mojom::MouseSettingsObserver> observer) override;
+ void RestoreDefaultKeyboardRemappings(uint32_t device_id) override;
void SetKeyboardSettings(uint32_t device_id,
::ash::mojom::KeyboardSettingsPtr settings) override;
void SetPointingStickSettings(
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.mojom b/chromium/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.mojom
index f75ae9fdbe1..fd904a3e513 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.mojom
+++ b/chromium/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.mojom
@@ -63,6 +63,8 @@ interface InputDeviceSettingsProvider {
// The observer which is registered is immediately informed
// of the current state via its ObserveMouseSettings function.
ObserveMouseSettings(pending_remote<MouseSettingsObserver> observer);
+ // Restore the keyboard remappings to default base on its id.
+ RestoreDefaultKeyboardRemappings(uint32 device_id);
// Sets the keyboard settings based on its id.
SetKeyboardSettings(uint32 device_id, ash.mojom.KeyboardSettings settings);
// Sets the point stick settings based on its id.
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider_unittest.cc b/chromium/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider_unittest.cc
index 5db798999c5..d0a9fe7b83c 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider_unittest.cc
@@ -54,12 +54,14 @@ const ::ash::mojom::Touchpad kTouchpad1 =
/*is_external=*/false,
/*id=*/3,
/*device_key=*/"fake-device-key3",
+ /*is_haptic=*/true,
::ash::mojom::TouchpadSettings::New());
const ::ash::mojom::Touchpad kTouchpad2 =
::ash::mojom::Touchpad(/*name=*/"Logitech T650",
/*is_external=*/true,
/*id=*/4,
/*device_key=*/"fake-device-key4",
+ /*is_haptic=*/false,
::ash::mojom::TouchpadSettings::New());
const ::ash::mojom::PointingStick kPointingStick1 =
::ash::mojom::PointingStick(/*name=*/"test pointing stick",
@@ -242,6 +244,9 @@ class FakeInputDeviceSettingsController : public InputDeviceSettingsController {
const ::ash::mojom::MousePolicies& GetMousePolicies() override {
return *mouse_policies_;
}
+ void RestoreDefaultKeyboardRemappings(DeviceId id) override {
+ ++num_times_restore_default_keyboard_remappings_called_;
+ }
void SetKeyboardSettings(
DeviceId id,
::ash::mojom::KeyboardSettingsPtr settings) override {
@@ -337,6 +342,9 @@ class FakeInputDeviceSettingsController : public InputDeviceSettingsController {
pointing_sticks_.erase(iter);
observer_->OnPointingStickDisconnected(*temp_pointing_stick);
}
+ int num_times_restore_default_keyboard_remappings_called() {
+ return num_times_restore_default_keyboard_remappings_called_;
+ }
int num_times_set_keyboard_settings_called() {
return num_times_set_keyboard_settings_called_;
}
@@ -361,6 +369,7 @@ class FakeInputDeviceSettingsController : public InputDeviceSettingsController {
::ash::mojom::MousePolicies::New();
raw_ptr<InputDeviceSettingsController::Observer> observer_ = nullptr;
+ int num_times_restore_default_keyboard_remappings_called_ = 0;
int num_times_set_keyboard_settings_called_ = 0;
int num_times_set_pointing_stick_settings_called_ = 0;
int num_times_set_mouse_settings_called_ = 0;
@@ -409,6 +418,22 @@ TEST_F(InputDeviceSettingsProviderTest, TestSetKeyboardSettings) {
EXPECT_EQ(2, controller_->num_times_set_keyboard_settings_called());
}
+TEST_F(InputDeviceSettingsProviderTest, TestRestoreDefaultKeyboardRemappings) {
+ controller_->AddKeyboard(kKeyboard1.Clone());
+ provider_->RestoreDefaultKeyboardRemappings(kKeyboard1.id);
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(
+ 1, controller_->num_times_restore_default_keyboard_remappings_called());
+
+ controller_->AddKeyboard(kKeyboard2.Clone());
+ provider_->RestoreDefaultKeyboardRemappings(kKeyboard2.id);
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(
+ 2, controller_->num_times_restore_default_keyboard_remappings_called());
+}
+
TEST_F(InputDeviceSettingsProviderTest, TestSetPointingStickSettings) {
controller_->AddPointingStick(kPointingStick1.Clone());
provider_->SetPointingStickSettings(kPointingStick1.id,
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/internet_handler.cc b/chromium/chrome/browser/ui/webui/settings/ash/internet_handler.cc
index 2025ce61f86..2c995206993 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/internet_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/internet_handler.cc
@@ -249,7 +249,7 @@ void InternetHandler::SetGmsCoreNotificationsDisabledDeviceNames() {
gms_core_notifications_state_tracker_
->GetGmsCoreNotificationsDisabledDeviceNames();
for (const auto& device_name : device_names) {
- device_names_without_notifications_.emplace_back(base::Value(device_name));
+ device_names_without_notifications_.Append(base::Value(device_name));
}
SendGmsCoreNotificationsDisabledDeviceNames();
}
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/internet_handler.h b/chromium/chrome/browser/ui/webui/settings/ash/internet_handler.h
index f622405636b..f638cadc99d 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/internet_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/ash/internet_handler.h
@@ -61,7 +61,7 @@ class InternetHandler
tether::GmsCoreNotificationsStateTracker*
gms_core_notifications_state_tracker);
- std::vector<base::Value> device_names_without_notifications_;
+ base::Value::List device_names_without_notifications_;
const raw_ptr<Profile, ExperimentalAsh> profile_;
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/internet_section.cc b/chromium/chrome/browser/ui/webui/settings/ash/internet_section.cc
index 5ecaa33e55e..f9b48cd10ab 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/internet_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/internet_section.cc
@@ -15,6 +15,7 @@
#include "base/no_destructor.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/ui/webui/ash/cellular_setup/cellular_setup_localized_strings_provider.h"
+#include "chrome/browser/ui/webui/extension_control_handler.h"
#include "chrome/browser/ui/webui/settings/ash/internet_handler.h"
#include "chrome/browser/ui/webui/settings/ash/search/search_tag_registry.h"
#include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h"
@@ -49,6 +50,7 @@ using ::chromeos::settings::mojom::kHotspotSubpagePath;
using ::chromeos::settings::mojom::kKnownNetworksSubpagePath;
using ::chromeos::settings::mojom::kMobileDataNetworksSubpagePath;
using ::chromeos::settings::mojom::kNetworkSectionPath;
+using ::chromeos::settings::mojom::kPasspointDetailSubpagePath;
using ::chromeos::settings::mojom::kTetherDetailsSubpagePath;
using ::chromeos::settings::mojom::kVpnDetailsSubpagePath;
using ::chromeos::settings::mojom::kWifiDetailsSubpagePath;
@@ -823,6 +825,16 @@ void InternetSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
IDS_SETTINGS_INTERNET_NETWORK_SECTION_PASSPOINT_REMOVAL_TITLE},
{"networkSectionPasspointRemovalDescription",
IDS_SETTINGS_INTERNET_NETWORK_SECTION_PASSPOINT_REMOVAL_DESCRIPTION},
+ {"networkSectionPasspointRemovalInformation",
+ IDS_SETTINGS_INTERNET_NETWORK_SECTION_PASSPOINT_REMOVAL_INFORMATION},
+ {"networkSectionPasspointGoToSubscriptionTitle",
+ IDS_SETTINGS_INTERNET_NETWORK_SECTION_PASSPOINT_GO_TO_SUBSCRIPTION_TITLE},
+ {"networkSectionPasspointGoToSubscriptionInformation",
+ IDS_SETTINGS_INTERNET_NETWORK_SECTION_PASSPOINT_GO_TO_SUBSCRIPTION_INFORMATION},
+ {"networkSectionPasspointGoToSubscriptionButtonLabel",
+ IDS_SETTINGS_INTERNET_NETWORK_SECTION_PASSPOINT_GO_TO_SUBSCRIPTION_BUTTON},
+ {"passpointRemoveGoToSubscriptionButtonA11yLabel",
+ IDS_SETTINGS_INTERNET_NETWORK_SECTION_PASSPOINT_GO_TO_SUBSCRIPTION_BUTTON_A11Y_LABEL},
{"networkSectionProxy", IDS_SETTINGS_INTERNET_NETWORK_SECTION_PROXY},
{"networkSectionProxyExpandA11yLabel",
IDS_SETTINGS_INTERNET_NETWORK_SECTION_PROXY_ACCESSIBILITY_LABEL},
@@ -994,6 +1006,31 @@ void InternetSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
IDS_SETTINGS_INTERNET_HOTSPOT_CONFIG_INVALID_CONFIGURATION_ERROR_MESSAGE},
{"hotspotConfigNotLoginErrorMessage",
IDS_SETTINGS_INTERNET_HOTSPOT_CONFIG_NOT_LOGIN_ERROR_MESSAGE},
+ {"passpointProviderLabel",
+ IDS_SETTINGS_INTERNET_PASSPOINT_PROVIDER_LABEL},
+ {"passpointRemoveButton",
+ IDS_SETTINGS_INTERNET_PASSPOINT_REMOVE_SUBSCRIPTION},
+ {"passpointSectionLabel", IDS_SETTINGS_INTERNET_PASSPOINT_SECTION_LABEL},
+ {"passpointHeadlineText", IDS_SETTINGS_INTERNET_PASSPOINT_HEADLINE},
+ {"passpointSubscriptionExpirationLabel",
+ IDS_SETTINGS_INTERNET_PASSPOINT_SUBSCRIPTION_EXPIRATION},
+ {"passpointSourceLabel", IDS_SETTINGS_INTERNET_PASSPOINT_SOURCE},
+ {"passpointTrustedCALabel", IDS_SETTINGS_INTERNET_PASSPOINT_TRUSTED_CA},
+ {"passpointSystemCALabel", IDS_SETTINGS_INTERNET_PASSPOINT_SYSTEM_CA},
+ {"passpointAssociatedWifiNetworks",
+ IDS_SETTINGS_INTERNET_PASSPOINT_ASSOCIATED_WIFI_NETWORKS},
+ {"passpointDomainsLabel", IDS_SETTINGS_INTERNET_PASSPOINT_DOMAINS},
+ {"passpointDomainsA11yLabel",
+ IDS_SETTINGS_INTERNET_PASSPOINT_DOMAINS_A11Y_LABEL},
+ {"passpointRemovalTitle", IDS_SETTINGS_INTERNET_PASSPOINT_REMOVAL_TITLE},
+ {"passpointRemovalDescription",
+ IDS_SETTINGS_INTERNET_PASSPOINT_REMOVAL_DESCRIPTION},
+ {"passpointLearnMoreA11yLabel",
+ IDS_SETTINGS_INTERNET_PASSPOINT_LEARN_MORE_A11Y},
+ {"passpointRemoveCancelA11yLabel",
+ IDS_SETTINGS_INTERNET_PASSPOINT_REMOVE_CANCEL_A11Y},
+ {"passpointRemoveConfirmA11yLabel",
+ IDS_SETTINGS_INTERNET_PASSPOINT_REMOVE_CONFIRM_A11Y},
};
html_source->AddLocalizedStrings(kLocalizedStrings);
@@ -1019,6 +1056,8 @@ void InternetSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
html_source->AddBoolean(
"showHiddenToggle",
base::FeatureList::IsEnabled(::features::kShowHiddenNetworkToggle));
+ html_source->AddBoolean("isSmdsSupportEnabled",
+ ash::features::IsSmdsSupportEnabled());
html_source->AddBoolean("isHotspotEnabled",
ash::features::IsHotspotEnabled());
html_source->AddBoolean("isPasspointEnabled",
@@ -1088,6 +1127,7 @@ void InternetSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
void InternetSection::AddHandlers(content::WebUI* web_ui) {
web_ui->AddMessageHandler(std::make_unique<InternetHandler>(profile()));
+ web_ui->AddMessageHandler(std::make_unique<ExtensionControlHandler>());
}
int InternetSection::GetSectionNameMessageId() const {
@@ -1180,6 +1220,13 @@ void InternetSection::RegisterHierarchy(HierarchyGenerator* generator) const {
kMobileDataNetworksSettings, generator);
generator->RegisterTopLevelAltSetting(mojom::Setting::kMobileOnOff);
+ // Passpoint details.
+ generator->RegisterNestedSubpage(
+ IDS_SETTINGS_INTERNET_PASSPOINT_DETAILS,
+ mojom::Subpage::kPasspointDetails, mojom::Subpage::kKnownNetworks,
+ mojom::SearchResultIcon::kWifi, mojom::SearchResultDefaultRank::kMedium,
+ mojom::kPasspointDetailSubpagePath);
+
// 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
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/kerberos_accounts_handler.cc b/chromium/chrome/browser/ui/webui/settings/ash/kerberos_accounts_handler.cc
index 8741f77b0e5..36617c957ad 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/kerberos_accounts_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/kerberos_accounts_handler.cc
@@ -7,6 +7,7 @@
#include <string>
#include <utility>
+#include "ash/constants/ash_features.h"
#include "base/functional/bind.h"
#include "base/memory/ptr_util.h"
#include "base/strings/string_util.h"
@@ -107,6 +108,8 @@ void AddKerberosAddAccountDialogStrings(content::WebUIDataSource* html_source) {
IDS_SETTINGS_KERBEROS_CONFIG_ERROR_KRB5_FAILED_TO_PARSE},
{"kerberosConfigErrorTooManyNestedGroups",
IDS_SETTINGS_KERBEROS_CONFIG_ERROR_TOO_MANY_NESTED_GROUPS},
+ {"kerberosConfigErrorLineTooLong",
+ IDS_SETTINGS_KERBEROS_CONFIG_ERROR_LINE_TOO_LONG},
{"addKerberosAccountRefreshButtonLabel",
IDS_SETTINGS_ADD_KERBEROS_ACCOUNT_REFRESH_BUTTON_LABEL},
{"addKerberosAccount", IDS_SETTINGS_ADD_KERBEROS_ACCOUNT},
@@ -121,6 +124,11 @@ void AddKerberosAddAccountDialogStrings(content::WebUIDataSource* html_source) {
"kerberosRememberPasswordEnabled",
local_state->GetBoolean(::prefs::kKerberosRememberPasswordEnabled));
+ // Whether the 'Remember password' checkbox should be checked by default.
+ html_source->AddBoolean(
+ "kerberosRememberPasswordByDefault",
+ features::IsKerberosRememberPasswordByDefaultEnabled());
+
// Prefilled domain if policy is enabled. Note that Kerberos
// domains should be in all uppercase.
html_source->AddString("kerberosDomainAutocomplete",
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/languages_section.cc b/chromium/chrome/browser/ui/webui/settings/ash/languages_section.cc
index cec3161ac19..268503a4b93 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/languages_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/languages_section.cc
@@ -157,10 +157,6 @@ const std::vector<SearchConcept>& GetEmojiSuggestionSearchConcepts() {
return *tags;
}
-bool IsPredictiveWritingAllowed() {
- return features::IsAssistiveMultiWordEnabled();
-}
-
// TODO(crbug/1113611): As Smart Inputs page is renamed to Suggestions.
// All related strings, function names and filenames should be renamed as well.
void AddSmartInputsStrings(content::WebUIDataSource* html_source,
@@ -176,7 +172,10 @@ void AddSmartInputsStrings(content::WebUIDataSource* html_source,
html_source->AddBoolean("allowEmojiSuggestion", is_emoji_suggestion_allowed);
}
-void AddInputMethodOptionsStrings(content::WebUIDataSource* html_source) {
+void AddInputMethodOptionsStrings(
+ content::WebUIDataSource* html_source,
+ bool is_physical_keyboard_autocorrect_allowed,
+ bool is_physical_keyboard_predictive_writing_allowed) {
static constexpr webui::LocalizedString kLocalizedStrings[] = {
{"inputMethodOptionsBasicSectionTitle",
IDS_SETTINGS_INPUT_METHOD_OPTIONS_BASIC},
@@ -342,8 +341,12 @@ void AddInputMethodOptionsStrings(content::WebUIDataSource* html_source) {
IDS_SETTINGS_INPUT_METHOD_OPTIONS_KEYBOARD_COLEMAK},
};
html_source->AddLocalizedStrings(kLocalizedStrings);
- html_source->AddBoolean("allowPredictiveWriting",
- IsPredictiveWritingAllowed());
+ html_source->AddBoolean("isPhysicalKeyboardAutocorrectAllowed",
+ is_physical_keyboard_autocorrect_allowed);
+ html_source->AddBoolean(
+ "isPhysicalKeyboardPredictiveWritingAllowed",
+ base::FeatureList::IsEnabled(features::kAssistMultiWord) &&
+ is_physical_keyboard_predictive_writing_allowed);
html_source->AddBoolean(
"allowDiacriticsOnPhysicalKeyboardLongpress",
base::FeatureList::IsEnabled(
@@ -547,7 +550,10 @@ void LanguagesSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
IDS_SETTINGS_LANGUAGES_LANGUAGE_PACKS_NOTICE,
base::ASCIIToUTF16(chrome::kLanguagePacksLearnMoreURL)));
AddSmartInputsStrings(html_source, IsEmojiSuggestionAllowed());
- AddInputMethodOptionsStrings(html_source);
+ AddInputMethodOptionsStrings(
+ html_source,
+ input_method::IsPhysicalKeyboardAutocorrectAllowed(*pref_service_),
+ input_method::IsPhysicalKeyboardPredictiveWritingAllowed(*pref_service_));
AddLanguagesPageStringsV2(html_source);
AddInputPageStringsV2(html_source);
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/main_section.cc b/chromium/chrome/browser/ui/webui/settings/ash/main_section.cc
index 35887bca2c1..16eb1028c62 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/main_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/main_section.cc
@@ -176,8 +176,10 @@ void MainSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
// This handler is for chrome://os-settings.
html_source->AddBoolean("isOSSettings", true);
- html_source->AddBoolean("searchFeedbackEnabled",
- ash::features::IsOsSettingsSearchFeedbackEnabled());
+
+ // Add app-wide feature flags
+ html_source->AddBoolean("isRevampWayfindingEnabled",
+ ash::features::IsOsSettingsRevampWayfindingEnabled());
html_source->AddBoolean("isGuest", IsGuestModeActive());
html_source->AddBoolean(
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/metrics_consent_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/ash/metrics_consent_handler_unittest.cc
index 113263d0859..01c08a5d5c6 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/metrics_consent_handler_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/metrics_consent_handler_unittest.cc
@@ -130,7 +130,7 @@ class MetricsConsentHandlerTest : public testing::Test {
test_user_manager_->SetOwnerId(account_id);
EXPECT_THAT(DeviceSettingsService::Get()->GetOwnershipStatus(),
- Eq(DeviceSettingsService::OWNERSHIP_TAKEN));
+ Eq(DeviceSettingsService::OwnershipStatus::kOwnershipTaken));
return owner;
}
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/multidevice_handler.cc b/chromium/chrome/browser/ui/webui/settings/ash/multidevice_handler.cc
index b2288b4862b..9aecc0ef152 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/multidevice_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/multidevice_handler.cc
@@ -147,10 +147,6 @@ void MultideviceHandler::RegisterMessages() {
base::BindRepeating(&MultideviceHandler::HandleSetUpAndroidSms,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
- "getSmartLockSignInAllowed",
- base::BindRepeating(&MultideviceHandler::HandleGetSmartLockSignInAllowed,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback(
"getAndroidSmsInfo",
base::BindRepeating(&MultideviceHandler::HandleGetAndroidSmsInfo,
base::Unretained(this)));
@@ -250,11 +246,6 @@ void MultideviceHandler::OnJavascriptAllowed() {
browser_tabs_model_provider_.get());
}
- pref_change_registrar_.Add(
- multidevice_setup::kSmartLockSigninAllowedPrefName,
- base::BindRepeating(
- &MultideviceHandler::NotifySmartLockSignInAllowedChanged,
- base::Unretained(this)));
if (NearbySharingServiceFactory::IsNearbyShareSupportedForBrowserContext(
Profile::FromWebUI(web_ui()))) {
pref_change_registrar_.Add(
@@ -473,16 +464,6 @@ void MultideviceHandler::HandleSetUpAndroidSms(const base::Value::List& args) {
android_sms_app_manager_->SetUpAndLaunchAndroidSmsApp();
}
-void MultideviceHandler::HandleGetSmartLockSignInAllowed(
- const base::Value::List& args) {
- const base::Value& callback_id = args[0];
- CHECK(callback_id.is_string());
-
- bool sign_in_allowed =
- prefs_->GetBoolean(multidevice_setup::kSmartLockSigninAllowedPrefName);
- ResolveJavascriptCallback(callback_id, base::Value(sign_in_allowed));
-}
-
base::Value::Dict MultideviceHandler::GenerateAndroidSmsInfo() {
absl::optional<GURL> app_url;
if (android_sms_app_manager_) {
@@ -885,13 +866,6 @@ base::Value::Dict MultideviceHandler::GeneratePageContentDataDictionary() {
return page_content_dictionary;
}
-void MultideviceHandler::NotifySmartLockSignInAllowedChanged() {
- bool sign_in_allowed =
- prefs_->GetBoolean(multidevice_setup::kSmartLockSigninAllowedPrefName);
- FireWebUIListener("smart-lock-signin-allowed-changed",
- base::Value(sign_in_allowed));
-}
-
bool MultideviceHandler::IsAuthTokenValid(const std::string& auth_token) {
Profile* profile = Profile::FromWebUI(web_ui());
quick_unlock::QuickUnlockStorage* quick_unlock_storage =
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/multidevice_handler.h b/chromium/chrome/browser/ui/webui/settings/ash/multidevice_handler.h
index 017b8f39ea9..cfca0a88525 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/multidevice_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/ash/multidevice_handler.h
@@ -142,9 +142,6 @@ class MultideviceHandler
void HandleRemoveHostDevice(const base::Value::List& args);
void HandleRetryPendingHostSetup(const base::Value::List& args);
void HandleSetUpAndroidSms(const base::Value::List& args);
- // TODO(b/227674947):Now that Sign in with Smart Lock is deprecated, delete
- // this method.
- void HandleGetSmartLockSignInAllowed(const base::Value::List& args);
void HandleGetAndroidSmsInfo(const base::Value::List& args);
void HandleAttemptNotificationSetup(const base::Value::List& args);
void HandleCancelNotificationSetup(const base::Value::List& args);
@@ -160,10 +157,6 @@ class MultideviceHandler
void OnSetFeatureStateEnabledResult(const std::string& js_callback_id,
bool success);
- // TODO(b/227674947):Now that Sign in with Smart Lock is deprecated, delete
- // this methods.
- void NotifySmartLockSignInAllowedChanged();
-
// Generate android sms info dictionary containing the messages for web
// content settings origin url and messages feature state.
base::Value::Dict GenerateAndroidSmsInfo();
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/multidevice_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/ash/multidevice_handler_unittest.cc
index 5b6a973e040..cf3a042aa9e 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/multidevice_handler_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/multidevice_handler_unittest.cc
@@ -981,7 +981,7 @@ class MultideviceHandlerTest : public testing::Test {
std::unique_ptr<eche_app::FakeAppsAccessManager> fake_apps_access_manager_;
std::unique_ptr<phonehub::FakeCameraRollManager> fake_camera_roll_manager_;
phonehub::FakeBrowserTabsModelProvider fake_browser_tabs_model_provider_;
- MockNewWindowDelegate* new_window_delegate_primary_;
+ raw_ptr<MockNewWindowDelegate, ExperimentalAsh> new_window_delegate_primary_;
std::unique_ptr<TestNewWindowDelegateProvider> new_window_provider_;
multidevice_setup::MultiDeviceSetupClient::HostStatusWithDevice
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/os_settings_hats_manager_factory.cc b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_hats_manager_factory.cc
index 02bb0dd328e..cc219c9bb75 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/os_settings_hats_manager_factory.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_hats_manager_factory.cc
@@ -26,7 +26,12 @@ OsSettingsHatsManagerFactory* OsSettingsHatsManagerFactory::GetInstance() {
OsSettingsHatsManagerFactory::OsSettingsHatsManagerFactory()
: ProfileKeyedServiceFactory(
"OsSettingsHatsManager",
- ProfileSelections::BuildForRegularAndIncognito()) {}
+ ProfileSelections::Builder()
+ .WithRegular(ProfileSelection::kOwnInstance)
+ // TODO(crbug.com/1418376): Check if this service is needed in
+ // Guest mode.
+ .WithGuest(ProfileSelection::kOwnInstance)
+ .Build()) {}
OsSettingsHatsManagerFactory::~OsSettingsHatsManagerFactory() = default;
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/os_settings_hats_manager_factory.h b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_hats_manager_factory.h
index 19e75695057..e1ac38055e7 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/os_settings_hats_manager_factory.h
+++ b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_hats_manager_factory.h
@@ -5,7 +5,6 @@
#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_OS_SETTINGS_HATS_MANAGER_FACTORY_H_
#define CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_OS_SETTINGS_HATS_MANAGER_FACTORY_H_
-#include "base/memory/singleton.h"
#include "base/no_destructor.h"
#include "chrome/browser/profiles/profile_keyed_service_factory.h"
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/os_settings_manager.cc b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_manager.cc
index 2df826727fd..7853a323154 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/os_settings_manager.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_manager.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/ui/webui/settings/ash/os_settings_manager.h"
#include "ash/public/cpp/input_device_settings_controller.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/settings/ash/hierarchy.h"
#include "chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.h"
#include "chrome/browser/ui/webui/settings/ash/os_apps_page/app_notification_handler.h"
@@ -23,7 +24,6 @@ OsSettingsManager::OsSettingsManager(
local_search_service::LocalSearchServiceProxy* local_search_service_proxy,
multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client,
phonehub::PhoneHubManager* phone_hub_manager,
- syncer::SyncService* sync_service,
KerberosCredentialsManager* kerberos_credentials_manager,
ArcAppListPrefs* arc_app_list_prefs,
signin::IdentityManager* identity_manager,
@@ -38,7 +38,6 @@ OsSettingsManager::OsSettingsManager(
search_tag_registry_.get(),
multidevice_setup_client,
phone_hub_manager,
- sync_service,
kerberos_credentials_manager,
arc_app_list_prefs,
identity_manager,
@@ -49,7 +48,8 @@ OsSettingsManager::OsSettingsManager(
hierarchy_(std::make_unique<Hierarchy>(sections_.get())),
settings_user_action_tracker_(
std::make_unique<SettingsUserActionTracker>(hierarchy_.get(),
- sections_.get())),
+ sections_.get(),
+ profile->GetPrefs())),
search_handler_(
std::make_unique<SearchHandler>(search_tag_registry_.get(),
sections_.get(),
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/os_settings_manager.h b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_manager.h
index bc28ac11f0f..7940dbe486f 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/os_settings_manager.h
+++ b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_manager.h
@@ -25,10 +25,6 @@ namespace signin {
class IdentityManager;
} // namespace signin
-namespace syncer {
-class SyncService;
-} // namespace syncer
-
namespace ash {
class CupsPrintersManager;
@@ -92,7 +88,6 @@ class OsSettingsManager : public KeyedService {
local_search_service::LocalSearchServiceProxy* local_search_service_proxy,
multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client,
phonehub::PhoneHubManager* phone_hub_manager,
- syncer::SyncService* sync_service,
KerberosCredentialsManager* kerberos_credentials_manager,
ArcAppListPrefs* arc_app_list_prefs,
signin::IdentityManager* identity_manager,
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/os_settings_manager_factory.cc b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_manager_factory.cc
index cf9a4dbd22a..a9af04e0260 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/os_settings_manager_factory.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_manager_factory.cc
@@ -15,7 +15,6 @@
#include "chrome/browser/ash/printing/cups_printers_manager_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/sync_service_factory.h"
#include "chrome/browser/ui/webui/settings/ash/os_settings_manager.h"
#include "chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy_factory.h"
@@ -30,18 +29,23 @@ OsSettingsManager* OsSettingsManagerFactory::GetForProfile(Profile* profile) {
// static
OsSettingsManagerFactory* OsSettingsManagerFactory::GetInstance() {
- return base::Singleton<OsSettingsManagerFactory>::get();
+ static base::NoDestructor<OsSettingsManagerFactory> instance;
+ return instance.get();
}
OsSettingsManagerFactory::OsSettingsManagerFactory()
: ProfileKeyedServiceFactory(
"OsSettingsManager",
- ProfileSelections::BuildForRegularAndIncognito()) {
+ ProfileSelections::Builder()
+ .WithRegular(ProfileSelection::kOwnInstance)
+ // TODO(crbug.com/1418376): Check if this service is needed in
+ // Guest mode.
+ .WithGuest(ProfileSelection::kOwnInstance)
+ .Build()) {
DependsOn(
local_search_service::LocalSearchServiceProxyFactory::GetInstance());
DependsOn(multidevice_setup::MultiDeviceSetupClientFactory::GetInstance());
DependsOn(phonehub::PhoneHubManagerFactory::GetInstance());
- DependsOn(SyncServiceFactory::GetInstance());
DependsOn(KerberosCredentialsManagerFactory::GetInstance());
DependsOn(ArcAppListPrefsFactory::GetInstance());
DependsOn(IdentityManagerFactory::GetInstance());
@@ -63,7 +67,6 @@ KeyedService* OsSettingsManagerFactory::BuildServiceInstanceFor(
GetForBrowserContext(context),
multidevice_setup::MultiDeviceSetupClientFactory::GetForProfile(profile),
phonehub::PhoneHubManagerFactory::GetForProfile(profile),
- SyncServiceFactory::GetForProfile(profile),
KerberosCredentialsManagerFactory::Get(profile),
ArcAppListPrefsFactory::GetForBrowserContext(profile),
IdentityManagerFactory::GetForProfile(profile),
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/os_settings_manager_factory.h b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_manager_factory.h
index 15279a05214..dad2c9ce335 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/os_settings_manager_factory.h
+++ b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_manager_factory.h
@@ -5,7 +5,7 @@
#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_OS_SETTINGS_MANAGER_FACTORY_H_
#define CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_OS_SETTINGS_MANAGER_FACTORY_H_
-#include "base/memory/singleton.h"
+#include "base/no_destructor.h"
#include "chrome/browser/profiles/profile_keyed_service_factory.h"
class Profile;
@@ -20,7 +20,7 @@ class OsSettingsManagerFactory : public ProfileKeyedServiceFactory {
static OsSettingsManagerFactory* GetInstance();
private:
- friend struct base::DefaultSingletonTraits<OsSettingsManagerFactory>;
+ friend base::NoDestructor<OsSettingsManagerFactory>;
OsSettingsManagerFactory();
~OsSettingsManagerFactory() override;
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/os_settings_manager_unittest.cc b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_manager_unittest.cc
index e209dc6c14c..69057eb21eb 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/os_settings_manager_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_manager_unittest.cc
@@ -17,7 +17,6 @@
#include "chrome/browser/ash/phonehub/phone_hub_manager_factory.h"
#include "chrome/browser/ash/printing/cups_printers_manager_factory.h"
#include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/browser/sync/sync_service_factory.h"
#include "chrome/browser/ui/webui/settings/ash/constants/constants_util.h"
#include "chrome/browser/ui/webui/settings/ash/hierarchy.h"
#include "chrome/browser/ui/webui/settings/ash/os_settings_manager_factory.h"
@@ -55,7 +54,8 @@ class OsSettingsManagerTest : public testing::Test {
scoped_feature_list_.InitWithFeatures(
{::features::kAccessibilityChromeVoxPageMigration,
::features::kAccessibilitySelectToSpeakPageMigration,
- ash::features::kInputDeviceSettingsSplit},
+ ash::features::kInputDeviceSettingsSplit,
+ ash::features::kPeripheralCustomization},
{});
ASSERT_TRUE(profile_manager_.SetUp());
TestingProfile* profile =
@@ -75,7 +75,6 @@ class OsSettingsManagerTest : public testing::Test {
multidevice_setup::MultiDeviceSetupClientFactory::GetForProfile(
profile),
phonehub::PhoneHubManagerFactory::GetForProfile(profile),
- SyncServiceFactory::GetForProfile(profile),
KerberosCredentialsManagerFactory::Get(profile),
ArcAppListPrefsFactory::GetForBrowserContext(profile),
IdentityManagerFactory::GetForProfile(profile),
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/os_settings_metrics_provider.cc b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_metrics_provider.cc
new file mode 100644
index 00000000000..8fd0adfde07
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_metrics_provider.cc
@@ -0,0 +1,30 @@
+// Copyright 2023 The Chromium Authors
+// 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/ash/os_settings_metrics_provider.h"
+
+#include "base/metrics/histogram_functions.h"
+#include "chrome/browser/ash/settings/cros_settings.h"
+#include "chromeos/ash/components/settings/cros_settings_names.h"
+
+namespace ash::settings {
+
+namespace {
+
+constexpr char kOsSettingsVerifiedAccessEnabledHistogramName[] =
+ "ChromeOS.Settings.Privacy.VerifiedAccessEnabled";
+
+} // namespace
+
+void OsSettingsMetricsProvider::ProvideCurrentSessionData(
+ metrics::ChromeUserMetricsExtension* uma_proto_unused) {
+ // Log verified access enabled/disabled value for this session
+ bool verified_access_enabled;
+ ash::CrosSettings::Get()->GetBoolean(
+ ash::kAttestationForContentProtectionEnabled, &verified_access_enabled);
+ base::UmaHistogramBoolean(kOsSettingsVerifiedAccessEnabledHistogramName,
+ verified_access_enabled);
+}
+
+} // namespace ash::settings
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/os_settings_metrics_provider.h b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_metrics_provider.h
new file mode 100644
index 00000000000..544b0015e5c
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_metrics_provider.h
@@ -0,0 +1,29 @@
+// Copyright 2023 The Chromium Authors
+// 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_ASH_OS_SETTINGS_METRICS_PROVIDER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_OS_SETTINGS_METRICS_PROVIDER_H_
+
+#include "components/metrics/metrics_provider.h"
+
+namespace ash::settings {
+
+class OsSettingsMetricsProvider : public metrics::MetricsProvider {
+ public:
+ OsSettingsMetricsProvider() = default;
+
+ OsSettingsMetricsProvider(const OsSettingsMetricsProvider&) = delete;
+ OsSettingsMetricsProvider& operator=(const OsSettingsMetricsProvider&) =
+ delete;
+
+ ~OsSettingsMetricsProvider() override = default;
+
+ // metrics::MetricsProvider:
+ void ProvideCurrentSessionData(
+ metrics::ChromeUserMetricsExtension* uma_proto) override;
+};
+
+} // namespace ash::settings
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_OS_SETTINGS_METRICS_PROVIDER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/os_settings_notification_settings_browsertest.cc b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_notification_settings_browsertest.cc
new file mode 100644
index 00000000000..9aa1cf9e989
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_notification_settings_browsertest.cc
@@ -0,0 +1,42 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/constants/ash_features.h"
+#include "ash/constants/ash_pref_names.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/test/scoped_feature_list.h"
+#include "chrome/browser/ash/profiles/profile_helper.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/webui/settings/ash/os_settings_lock_screen_browser_test_base.h"
+#include "chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom-shared.h"
+#include "chrome/test/data/webui/settings/chromeos/test_api.test-mojom-test-utils.h"
+#include "components/prefs/pref_service.h"
+#include "content/public/test/browser_test.h"
+
+namespace ash::settings {
+
+// Tests the toggle that controls notifications on the lock screen in the
+// lock-screen section of the chrome://os-settings webui.
+class OSSettingsNotificationSettingsTest
+ : public OSSettingsLockScreenBrowserTestBase {
+ public:
+ OSSettingsNotificationSettingsTest() {
+ feature_list_.InitAndEnableFeature(ash::features::kLockScreenNotifications);
+ }
+
+ private:
+ base::test::ScopedFeatureList feature_list_;
+};
+
+// Checks that the deep link to the notification toggle works.
+IN_PROC_BROWSER_TEST_F(OSSettingsNotificationSettingsTest,
+ NotificationSettings) {
+ mojom::LockScreenSettingsAsyncWaiter lock_screen_settings =
+ OpenLockScreenSettingsDeepLinkAndAuthenticate(
+ base::NumberToString(static_cast<int>(
+ chromeos::settings::mojom::Setting::kLockScreenNotification)));
+ lock_screen_settings.AssertLockScreenNotificationFocused();
+}
+
+} // namespace ash::settings
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/os_settings_section.h b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_section.h
index 50fcb4b9189..2a537abeaee 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/os_settings_section.h
+++ b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_section.h
@@ -180,8 +180,9 @@ class OsSettingsSection {
OsSettingsIdentifier id,
const std::string& url_to_modify);
- raw_ptr<Profile, ExperimentalAsh> profile_;
- raw_ptr<SearchTagRegistry, ExperimentalAsh> search_tag_registry_;
+ const raw_ptr<Profile, ExperimentalAsh> profile_ = nullptr;
+ const raw_ptr<SearchTagRegistry, ExperimentalAsh> search_tag_registry_ =
+ nullptr;
};
} // namespace ash::settings
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/os_settings_sections.cc b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_sections.cc
index 55f427446ad..3e4db6d579c 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/os_settings_sections.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_sections.cc
@@ -39,7 +39,6 @@ OsSettingsSections::OsSettingsSections(
SearchTagRegistry* search_tag_registry,
multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client,
phonehub::PhoneHubManager* phone_hub_manager,
- syncer::SyncService* sync_service,
KerberosCredentialsManager* kerberos_credentials_manager,
ArcAppListPrefs* arc_app_list_prefs,
signin::IdentityManager* identity_manager,
@@ -66,10 +65,9 @@ OsSettingsSections::OsSettingsSections(
profile, search_tag_registry, multidevice_setup_client,
phone_hub_manager, android_sms_service, prefs, eche_app_manager));
- AddSection(
- mojom::Section::kPeople,
- std::make_unique<PeopleSection>(profile, search_tag_registry,
- sync_service, identity_manager, prefs));
+ AddSection(mojom::Section::kPeople,
+ std::make_unique<PeopleSection>(profile, search_tag_registry,
+ identity_manager, prefs));
AddSection(mojom::Section::kDevice, std::make_unique<DeviceSection>(
profile, search_tag_registry, prefs));
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/os_settings_sections.h b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_sections.h
index 6ebf5847195..6e574081ef5 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/os_settings_sections.h
+++ b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_sections.h
@@ -20,10 +20,6 @@ namespace signin {
class IdentityManager;
} // namespace signin
-namespace syncer {
-class SyncService;
-} // namespace syncer
-
namespace ash {
class CupsPrintersManager;
@@ -51,7 +47,6 @@ class OsSettingsSections {
SearchTagRegistry* search_tag_registry,
multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client,
phonehub::PhoneHubManager* phone_hub_manager,
- syncer::SyncService* sync_service,
KerberosCredentialsManager* kerberos_credentials_manager,
ArcAppListPrefs* arc_app_list_prefs,
signin::IdentityManager* identity_manager,
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/os_settings_ui.cc b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_ui.cc
index 7a7ec31b490..6cab9488424 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/os_settings_ui.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_ui.cc
@@ -16,6 +16,7 @@
#include "ash/webui/personalization_app/search/search.mojom.h"
#include "ash/webui/personalization_app/search/search_handler.h"
#include "base/metrics/histogram_functions.h"
+#include "chrome/browser/ash/drive/file_system_util.h"
#include "chrome/browser/ash/login/quick_unlock/pin_backend.h"
#include "chrome/browser/ash/login/quick_unlock/quick_unlock_factory.h"
#include "chrome/browser/ash/web_applications/personalization_app/personalization_app_manager.h"
@@ -103,7 +104,7 @@ OSSettingsUI::OSSettingsUI(content::WebUI* web_ui)
webui::SetupWebUIDataSource(
html_source,
base::make_span(kOsSettingsResources, kOsSettingsResourcesSize),
- IDR_OS_SETTINGS_OS_SETTINGS_V3_HTML);
+ IDR_OS_SETTINGS_OS_SETTINGS_HTML);
#if !BUILDFLAG(OPTIMIZE_WEBUI)
html_source->AddResourcePaths(
@@ -255,7 +256,6 @@ void OSSettingsUI::BindInterface(
void OSSettingsUI::BindInterface(
mojo::PendingReceiver<audio_config::mojom::CrosAudioConfig> receiver) {
- DCHECK(features::IsAudioSettingsPageEnabled());
GetAudioConfigService(std::move(receiver));
}
@@ -301,7 +301,6 @@ void OSSettingsUI::BindInterface(
void OSSettingsUI::BindInterface(
mojo::PendingReceiver<google_drive::mojom::PageHandlerFactory> receiver) {
- CHECK(ash::features::IsDriveFsBulkPinningEnabled());
// The PageHandlerFactory is reused across same-origin navigations, so ensure
// any existing factories are reset.
google_drive_page_handler_factory_.reset();
@@ -311,6 +310,13 @@ void OSSettingsUI::BindInterface(
}
void OSSettingsUI::BindInterface(
+ mojo::PendingReceiver<one_drive::mojom::PageHandlerFactory> receiver) {
+ one_drive_page_handler_factory_ =
+ std::make_unique<OneDrivePageHandlerFactory>(Profile::FromWebUI(web_ui()),
+ std::move(receiver));
+}
+
+void OSSettingsUI::BindInterface(
mojo::PendingReceiver<chromeos::connectivity::mojom::PasspointService>
receiver) {
ash::GetPasspointService(std::move(receiver));
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/os_settings_ui.h b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_ui.h
index a27bfdef7f5..016571b0a95 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/os_settings_ui.h
+++ b/chromium/chrome/browser/ui/webui/settings/ash/os_settings_ui.h
@@ -14,6 +14,8 @@
#include "chrome/browser/ui/webui/nearby_share/nearby_share.mojom.h"
#include "chrome/browser/ui/webui/settings/ash/files_page/google_drive_page_handler_factory.h"
#include "chrome/browser/ui/webui/settings/ash/files_page/mojom/google_drive_handler.mojom-forward.h"
+#include "chrome/browser/ui/webui/settings/ash/files_page/mojom/one_drive_handler.mojom-forward.h"
+#include "chrome/browser/ui/webui/settings/ash/files_page/one_drive_page_handler_factory.h"
#include "chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.mojom.h"
#include "chrome/browser/ui/webui/settings/ash/os_apps_page/mojom/app_notification_handler.mojom-forward.h"
#include "chrome/browser/ui/webui/settings/ash/search/user_action_recorder.mojom-forward.h"
@@ -170,6 +172,10 @@ class OSSettingsUI : public ui::MojoWebUIController {
void BindInterface(
mojo::PendingReceiver<google_drive::mojom::PageHandlerFactory> receiver);
+ // Binds to the OneDrive page handler mojo.
+ void BindInterface(
+ mojo::PendingReceiver<one_drive::mojom::PageHandlerFactory> receiver);
+
// Binds to the cros Passpoint service.
void BindInterface(
mojo::PendingReceiver<chromeos::connectivity::mojom::PasspointService>
@@ -185,6 +191,7 @@ class OSSettingsUI : public ui::MojoWebUIController {
app_management_page_handler_factory_;
std::unique_ptr<GoogleDrivePageHandlerFactory>
google_drive_page_handler_factory_;
+ std::unique_ptr<OneDrivePageHandlerFactory> one_drive_page_handler_factory_;
// This handler notifies the WebUI when the color provider changes.
std::unique_ptr<ui::ColorChangeHandler> color_provider_handler_;
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/parental_controls_handler.cc b/chromium/chrome/browser/ui/webui/settings/ash/parental_controls_handler.cc
index e752fb2f759..7ab482cdda3 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/parental_controls_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/parental_controls_handler.cc
@@ -4,6 +4,7 @@
#include "chrome/browser/ui/webui/settings/ash/parental_controls_handler.h"
+#include "ash/public/cpp/new_window_delegate.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/values.h"
@@ -12,15 +13,11 @@
#include "chrome/browser/apps/app_service/launch_utils.h"
#include "chrome/browser/ash/app_list/arc/arc_app_utils.h"
#include "chrome/browser/ash/child_accounts/child_user_service.h"
-#include "chrome/browser/ui/browser_navigator.h"
-#include "chrome/browser/ui/browser_navigator_params.h"
#include "chrome/browser/ui/webui/ash/add_supervision/add_supervision_ui.h"
#include "components/services/app_service/public/cpp/app_launch_util.h"
#include "components/services/app_service/public/cpp/app_registry_cache.h"
#include "components/services/app_service/public/cpp/app_types.h"
#include "components/services/app_service/public/cpp/app_update.h"
-#include "ui/base/page_transition_types.h"
-#include "ui/base/window_open_disposition.h"
#include "ui/display/types/display_constants.h"
#include "ui/events/event_constants.h"
#include "url/gurl.h"
@@ -85,11 +82,10 @@ void ParentalControlsHandler::HandleLaunchFamilyLinkSettings(
}
// As a last resort, launch browser to the family link site.
- NavigateParams params(profile_, GURL(kFamilyLinkSiteURL),
- ui::PAGE_TRANSITION_FROM_API);
- params.disposition = WindowOpenDisposition::NEW_WINDOW;
- params.window_action = NavigateParams::SHOW_WINDOW;
- Navigate(&params);
+ NewWindowDelegate::GetPrimary()->OpenUrl(
+ GURL(kFamilyLinkSiteURL),
+ NewWindowDelegate::OpenUrlFrom::kUserInteraction,
+ NewWindowDelegate::Disposition::kNewWindow);
}
} // namespace ash::settings
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/pdf_ocr_handler.cc b/chromium/chrome/browser/ui/webui/settings/ash/pdf_ocr_handler.cc
index 7920260c6f9..ed56b8486f4 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/pdf_ocr_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/pdf_ocr_handler.cc
@@ -5,9 +5,9 @@
#include <string>
#include "base/feature_list.h"
+#include "chrome/browser/screen_ai/screen_ai_install_state.h"
#include "chrome/browser/ui/webui/settings/ash/pdf_ocr_handler.h"
#include "chrome/grit/generated_resources.h"
-#include "components/services/screen_ai/public/cpp/screen_ai_install_state.h"
#include "ui/accessibility/accessibility_features.h"
#include "ui/base/l10n/l10n_util.h"
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/pdf_ocr_handler.h b/chromium/chrome/browser/ui/webui/settings/ash/pdf_ocr_handler.h
index ceb50090a31..f40a3925dcf 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/pdf_ocr_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/ash/pdf_ocr_handler.h
@@ -7,8 +7,8 @@
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
+#include "chrome/browser/screen_ai/screen_ai_install_state.h"
#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
-#include "components/services/screen_ai/public/cpp/screen_ai_install_state.h"
namespace settings {
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/pdf_ocr_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/ash/pdf_ocr_handler_unittest.cc
index cc7ba384ca7..b589855edbf 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/pdf_ocr_handler_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/pdf_ocr_handler_unittest.cc
@@ -7,8 +7,8 @@
#include "base/memory/raw_ptr.h"
#include "base/test/scoped_feature_list.h"
+#include "chrome/browser/screen_ai/screen_ai_install_state.h"
#include "chrome/test/base/testing_profile.h"
-#include "components/services/screen_ai/public/cpp/screen_ai_install_state.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/test_web_ui.h"
@@ -32,7 +32,11 @@ class TestScreenAIInstallState : public screen_ai::ScreenAIInstallState {
TestScreenAIInstallState(const TestScreenAIInstallState&) = delete;
TestScreenAIInstallState& operator=(const TestScreenAIInstallState&) = delete;
- ~TestScreenAIInstallState() = default;
+ ~TestScreenAIInstallState() override {}
+
+ void SetLastUsageTime() override {}
+
+ void DownloadComponent() override {}
};
class TestPdfOcrHandler : public PdfOcrHandler {
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/people_section.cc b/chromium/chrome/browser/ui/webui/settings/ash/people_section.cc
index 3318a24fda5..78b10eac276 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/people_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/people_section.cc
@@ -50,8 +50,6 @@
#include "components/prefs/pref_service.h"
#include "components/strings/grit/components_strings.h"
#include "components/sync/base/features.h"
-#include "components/sync/driver/sync_service.h"
-#include "components/sync/driver/sync_user_settings.h"
#include "components/user_manager/user.h"
#include "components/user_manager/user_manager.h"
#include "content/public/browser/web_ui.h"
@@ -427,6 +425,10 @@ void AddSyncControlsStrings(content::WebUIDataSource* html_source) {
base::FeatureList::IsEnabled(syncer::kSyncChromeOSAppsToggleSharing) &&
crosapi::browser_util::IsLacrosEnabled());
+ html_source->AddBoolean(
+ "osDeprecateSyncMetricsToggle",
+ ash::features::IsOsSettingsDeprecateSyncMetricsToggleEnabled());
+
// This handler is for chrome://os-settings.
html_source->AddBoolean("isOSSettings", true);
}
@@ -487,10 +489,8 @@ bool IsSameAccount(const ::account_manager::AccountKey& account_key,
} // namespace
-// TODO(https://crbug.com/1274802): Remove sync_service param.
PeopleSection::PeopleSection(Profile* profile,
SearchTagRegistry* search_tag_registry,
- syncer::SyncService* sync_service,
signin::IdentityManager* identity_manager,
PrefService* pref_service)
: OsSettingsSection(profile, search_tag_registry),
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/people_section.h b/chromium/chrome/browser/ui/webui/settings/ash/people_section.h
index 1c4bcfe22fd..5d378dd6570 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/people_section.h
+++ b/chromium/chrome/browser/ui/webui/settings/ash/people_section.h
@@ -16,7 +16,6 @@
#include "components/account_manager_core/account_manager_facade.h"
#include "components/account_manager_core/chromeos/account_manager.h"
#include "components/prefs/pref_change_registrar.h"
-#include "components/sync/driver/sync_service_observer.h"
class PrefService;
class Profile;
@@ -29,10 +28,6 @@ namespace signin {
class IdentityManager;
} // namespace signin
-namespace syncer {
-class SyncService;
-} // namespace syncer
-
namespace ash {
class AccountAppsAvailability;
@@ -52,7 +47,6 @@ class PeopleSection : public OsSettingsSection,
public:
PeopleSection(Profile* profile,
SearchTagRegistry* search_tag_registry,
- syncer::SyncService* sync_service,
signin::IdentityManager* identity_manager,
PrefService* pref_service);
~PeopleSection() override;
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/printing_section.cc b/chromium/chrome/browser/ui/webui/settings/ash/printing_section.cc
index f70821634c5..ec99d9f3a35 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/printing_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/printing_section.cc
@@ -120,6 +120,8 @@ void PrintingSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
{"cupsPrintersLearnMoreLabel",
IDS_SETTINGS_PRINTING_CUPS_PRINTERS_LEARN_MORE_LABEL},
{"addCupsPrinter", IDS_SETTINGS_PRINTING_CUPS_PRINTERS_ADD_PRINTER},
+ {"addCupsPrinterManually",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTERS_ADD_PRINTER_MANUALLY},
{"editPrinter", IDS_SETTINGS_PRINTING_CUPS_PRINTERS_EDIT},
{"viewPrinter", IDS_SETTINGS_PRINTING_CUPS_PRINTERS_VIEW},
{"removePrinter", IDS_SETTINGS_PRINTING_CUPS_PRINTERS_REMOVE},
@@ -150,6 +152,10 @@ void PrintingSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
IDS_SETTINGS_PRINTING_CUPS_PRINTERS_SAVED_PRINTERS_COUNT_ONE},
{"savedPrintersCountNone",
IDS_SETTINGS_PRINTING_CUPS_PRINTERS_SAVED_PRINTERS_COUNT_NONE},
+ {"noSavedPrinters", IDS_SETTINGS_PRINTING_CUPS_NO_SAVED_PRINTERS},
+ {"helpSectionTitle", IDS_SETTINGS_PRINTING_CUPS_HELP_SECTION_TITLE},
+ {"helpSectionDescription",
+ IDS_SETTINGS_PRINTING_CUPS_HELP_SECTION_DESCRIPTION},
{"showMorePrinters", IDS_SETTINGS_PRINTING_CUPS_SHOW_MORE},
{"addPrintersNearbyTitle",
IDS_SETTINGS_PRINTING_CUPS_ADD_PRINTERS_NEARBY_TITLE},
@@ -279,6 +285,30 @@ void PrintingSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
IDS_SETTINGS_PRINTING_CUPS_PRINT_SERVER_CONNECTION_ERROR},
{"printServerConfigurationErrorMessage",
IDS_SETTINGS_PRINTING_CUPS_PRINT_SERVER_REACHABLE_BUT_CANNOT_ADD},
+ {"printerStatusDeviceError",
+ IDS_SETTINGS_PRINTING_PRINTER_STATUS_DEVICE_ERROR},
+ {"printerStatusDoorOpen", IDS_SETTINGS_PRINTING_PRINTER_STATUS_DOOR_OPEN},
+ {"printerStatusLowOnInk",
+ IDS_SETTINGS_PRINTING_PRINTER_STATUS_LOW_ON_INK},
+ {"printerStatusLowOnPaper",
+ IDS_SETTINGS_PRINTING_PRINTER_STATUS_LOW_ON_PAPER},
+ {"printerStatusOutOfInk",
+ IDS_SETTINGS_PRINTING_PRINTER_STATUS_OUT_OF_INK},
+ {"printerStatusOutOfPaper",
+ IDS_SETTINGS_PRINTING_PRINTER_STATUS_OUT_OF_PAPER},
+ {"printerStatusOutputAlmostFull",
+ IDS_SETTINGS_PRINTING_PRINTER_STATUS_OUPUT_ALMOST_FULL},
+ {"printerStatusOutputFull",
+ IDS_SETTINGS_PRINTING_PRINTER_STATUS_OUPUT_FULL},
+ {"printerStatusPaperJam", IDS_SETTINGS_PRINTING_PRINTER_STATUS_PAPER_JAM},
+ {"printerStatusPaused", IDS_SETTINGS_PRINTING_PRINTER_STATUS_PAUSED},
+ {"printerStatusPrinterQueueFull",
+ IDS_SETTINGS_PRINTING_PRINTER_STATUS_PRINTER_QUEUE_FULL},
+ {"printerStatusPrinterUnreachable",
+ IDS_SETTINGS_PRINTING_PRINTER_STATUS_PRINTER_UNREACHABLE},
+ {"printerStatusStopped", IDS_SETTINGS_PRINTING_PRINTER_STATUS_STOPPED},
+ {"printerStatusTrayMissing",
+ IDS_SETTINGS_PRINTING_PRINTER_STATUS_TRAY_MISSING},
};
html_source->AddLocalizedStrings(kLocalizedStrings);
@@ -287,9 +317,10 @@ void PrintingSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
html_source->AddString(
"printingCUPSPrintPpdLearnMoreUrl",
GetHelpUrlWithBoard(chrome::kCupsPrintPPDLearnMoreURL));
- html_source->AddBoolean("isViewPpdEnabled", features::IsViewPpdEnabled());
html_source->AddBoolean("isPrinterSettingsRevampEnabled",
features::IsPrinterSettingsRevampEnabled());
+ html_source->AddBoolean("isPrinterSettingsPrinterStatusEnabled",
+ features::IsPrinterSettingsPrinterStatusEnabled());
}
void PrintingSection::AddHandlers(content::WebUI* web_ui) {
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/privacy_hub_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/ash/privacy_hub_handler_unittest.cc
index da20c1b2d2d..f8f5a6c2d2b 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/privacy_hub_handler_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/privacy_hub_handler_unittest.cc
@@ -6,6 +6,7 @@
#include "ash/constants/ash_features.h"
#include "base/containers/adapters.h"
+#include "base/ranges/algorithm.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "chrome/browser/ash/privacy_hub/privacy_hub_hats_trigger.h"
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/privacy_section.cc b/chromium/chrome/browser/ui/webui/settings/ash/privacy_section.cc
index 5ccdfaf869d..57aea46c694 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/privacy_section.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/privacy_section.cc
@@ -402,6 +402,10 @@ void PrivacySection::AddLoadTimeData(content::WebUIDataSource* html_source) {
IDS_OS_SETTINGS_PRIVACY_HUB_MICROPHONE_TOGGLE_SUBTEXT},
{"noMicrophoneConnectedText",
IDS_OS_SETTINGS_PRIVACY_HUB_NO_MICROPHONE_CONNECTED_TEXT},
+ {"speakOnMuteDetectionToggleTitle",
+ IDS_OS_SETTINGS_PRIVACY_HUB_SPEAK_ON_MUTE_DETECTION_TOGGLE_TITLE},
+ {"speakOnMuteDetectionToggleSubtext",
+ IDS_OS_SETTINGS_PRIVACY_HUB_SPEAK_ON_MUTE_DETECTION_TOGGLE_SUBTEXT},
{"geolocationToggleTitle",
IDS_OS_SETTINGS_PRIVACY_HUB_GEOLOCATION_TOGGLE_TITLE},
{"geolocationToggleDesc",
@@ -426,6 +430,8 @@ void PrivacySection::AddLoadTimeData(content::WebUIDataSource* html_source) {
ash::features::IsCrosPrivacyHubV1Enabled());
html_source->AddBoolean("showPrivacyHubFuturePage",
ash::features::IsCrosPrivacyHubV2Enabled());
+ html_source->AddBoolean("showSpeakOnMuteDetectionPage",
+ ash::features::IsVideoConferenceEnabled());
html_source->AddString(
"smartPrivacyDesc",
@@ -443,6 +449,12 @@ void PrivacySection::AddLoadTimeData(content::WebUIDataSource* html_source) {
html_source->AddString("peripheralDataAccessLearnMoreURL",
chrome::kPeripheralDataAccessHelpURL);
+ html_source->AddString("speakOnMuteDetectionLearnMoreURL",
+ chrome::kSpeakOnMuteDetectionLearnMoreURL);
+
+ html_source->AddString("geolocationToggleLearnMoreURL",
+ chrome::kGeolocationToggleLearnMoreURL);
+
html_source->AddBoolean("showSecureDnsSetting", IsSecureDnsAvailable());
html_source->AddBoolean("showSecureDnsOsSettingLink", false);
@@ -512,6 +524,7 @@ void PrivacySection::RegisterHierarchy(HierarchyGenerator* generator) const {
mojom::Setting::kLockScreenV2,
mojom::Setting::kChangeAuthPinV2,
mojom::Setting::kPeripheralDataAccessProtection,
+ mojom::Setting::kLockScreenNotification,
};
RegisterNestedSettingBulk(mojom::Subpage::kSecurityAndSignInV2,
kSecurityAndSignInSettings, generator);
@@ -564,7 +577,8 @@ void PrivacySection::RegisterHierarchy(HierarchyGenerator* generator) const {
RegisterNestedSettingBulk(
mojom::Subpage::kPrivacyHub,
{{mojom::Setting::kCameraOnOff, mojom::Setting::kMicrophoneOnOff,
- mojom::Setting::kGeolocationOnOff}},
+ mojom::Setting::kGeolocationOnOff,
+ mojom::Setting::kSpeakOnMuteDetectionOnOff}},
generator);
}
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/search/BUILD.gn b/chromium/chrome/browser/ui/webui/settings/ash/search/BUILD.gn
index 0beca303f84..6f2027b16af 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/search/BUILD.gn
+++ b/chromium/chrome/browser/ui/webui/settings/ash/search/BUILD.gn
@@ -19,6 +19,6 @@ mojom("mojo_bindings") {
"//mojo/public/mojom/base",
]
- webui_module_path = "/search"
+ webui_module_path = "/"
use_typescript_sources = true
}
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker.cc b/chromium/chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker.cc
index 4e29e582871..efbb6e34add 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker.cc
@@ -5,6 +5,10 @@
#include "chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker.h"
#include "base/metrics/histogram_functions.h"
+#include "base/strings/string_number_conversions.h"
+#include "chrome/browser/ash/login/login_pref_names.h"
+#include "chrome/common/pref_names.h"
+#include "components/prefs/scoped_user_pref_update.h"
namespace ash::settings {
@@ -25,6 +29,10 @@ constexpr base::TimeDelta kMinSubsequentChange = base::Milliseconds(200);
constexpr base::TimeDelta kMinDurationMetric = base::Milliseconds(100);
constexpr base::TimeDelta kMaxDurationMetric = base::Minutes(10);
+// Used to check whether it has been one week since the user has finished OOBE
+// onboarding.
+constexpr base::TimeDelta kOneWeek = base::Days(7);
+
void LogDurationMetric(const char* metric_name, base::TimeDelta duration) {
base::UmaHistogramCustomTimes(metric_name, duration, kMinDurationMetric,
kMaxDurationMetric, /*buckets=*/50);
@@ -32,19 +40,91 @@ void LogDurationMetric(const char* metric_name, base::TimeDelta duration) {
} // namespace
-PerSessionSettingsUserActionTracker::PerSessionSettingsUserActionTracker()
- : metric_start_time_(base::TimeTicks::Now()) {}
+PerSessionSettingsUserActionTracker::PerSessionSettingsUserActionTracker(
+ PrefService* pref_service)
+ : metric_start_time_(base::TimeTicks::Now()),
+ window_last_active_timestamp_(base::TimeTicks::Now()),
+ pref_service_(pref_service) {}
+
+PerSessionSettingsUserActionTracker::~PerSessionSettingsUserActionTracker() {
+ RecordPageActiveTime();
+ LogDurationMetric("ChromeOS.Settings.WindowTotalActiveDuration",
+ total_time_session_active_);
+
+ base::UmaHistogramCounts1000(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.PerSession",
+ changed_settings_.size());
+
+ // The pref kHasResetFirst7DaysSettingsUsedCount indicates whether the pref
+ // kTotalUniqueOsSettingsChanged has been cleared once after 1 week has passed
+ // since OOBE. If the pref kHasResetFirst7DaysSettingsUsedCount is False and
+ // it has been over 7 days since the user has taken OOBE, it means that this
+ // is the first time since one week after OOBE that the user has opened and
+ // changed Settings. In this case, clear the pref
+ // kTotalUniqueOsSettingsChanged to prepare it for the
+ // ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime.SubsequentWeeks
+ // histogram.
+ // NOTE: prefs::kOobeOnboardingTime does not exist for users in guest mode.
+ if (!pref_service_->GetBoolean(
+ ::prefs::kHasResetFirst7DaysSettingsUsedCount) &&
+ pref_service_->HasPrefPath(prefs::kOobeOnboardingTime) &&
+ !IsTodayInFirst7Days()) {
+ pref_service_->SetBoolean(::prefs::kHasResetFirst7DaysSettingsUsedCount,
+ true);
+ ClearTotalUniqueSettingsChangedPref();
+ }
+
+ // Record number of unique settings changed in this session.
+ absl::optional<int> total_unique_settings_changed_count =
+ UpdateSettingsPrefTotalUniqueChanged();
+
+ // If the number of total unique setting used increased, flagged by the
+ // optional variable total_unique_settings_changed_count having a value, add
+ // the datapoint to the histogram.
+ // NOTE: prefs::kOobeOnboardingTime does not exist for users in guest mode.
+ if (pref_service_->HasPrefPath(prefs::kOobeOnboardingTime) &&
+ total_unique_settings_changed_count.has_value()) {
+ if (IsTodayInFirst7Days()) {
+ base::UmaHistogramCounts1000(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime.FirstWeek",
+ total_unique_settings_changed_count.value());
+ } else {
+ base::UmaHistogramCounts1000(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime."
+ "SubsequentWeeks",
+ total_unique_settings_changed_count.value());
+ }
+ // Store the total unique Settings changed in .DeviceLifetime histogram.
+ base::UmaHistogramCounts1000(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime.Total",
+ total_unique_settings_changed_count.value());
+ }
+}
+
+bool PerSessionSettingsUserActionTracker::IsTodayInFirst7Days() {
+ // The pref kOobeOnboardingTime does not get set for users in guest mode.
+ // Because we are accessing the value of the pref, we must ensure that it does
+ // exist.
+ DCHECK(pref_service_->HasPrefPath(prefs::kOobeOnboardingTime));
+ return base::Time::Now() -
+ pref_service_->GetTime(::ash::prefs::kOobeOnboardingTime) <=
+ kOneWeek;
+}
-PerSessionSettingsUserActionTracker::~PerSessionSettingsUserActionTracker() =
- default;
+void PerSessionSettingsUserActionTracker::
+ ClearTotalUniqueSettingsChangedPref() {
+ pref_service_->ClearPref(::prefs::kTotalUniqueOsSettingsChanged);
+}
void PerSessionSettingsUserActionTracker::RecordPageFocus() {
+ const base::TimeTicks now = base::TimeTicks::Now();
+ window_last_active_timestamp_ = now;
+
if (last_blur_timestamp_.is_null())
return;
// Log the duration of being blurred.
- const base::TimeDelta blurred_duration =
- base::TimeTicks::Now() - last_blur_timestamp_;
+ const base::TimeDelta blurred_duration = now - last_blur_timestamp_;
LogDurationMetric("ChromeOS.Settings.BlurredWindowDuration",
blurred_duration);
@@ -57,8 +137,17 @@ void PerSessionSettingsUserActionTracker::RecordPageFocus() {
}
}
+void PerSessionSettingsUserActionTracker::RecordPageActiveTime() {
+ if (window_last_active_timestamp_ != base::TimeTicks()) {
+ total_time_session_active_ +=
+ base::TimeTicks::Now() - window_last_active_timestamp_;
+ }
+ window_last_active_timestamp_ = base::TimeTicks();
+}
+
void PerSessionSettingsUserActionTracker::RecordPageBlur() {
last_blur_timestamp_ = base::TimeTicks::Now();
+ RecordPageActiveTime();
}
void PerSessionSettingsUserActionTracker::RecordClick() {
@@ -73,7 +162,12 @@ void PerSessionSettingsUserActionTracker::RecordSearch() {
++num_searches_since_start_time_;
}
-void PerSessionSettingsUserActionTracker::RecordSettingChange() {
+void PerSessionSettingsUserActionTracker::RecordSettingChange(
+ absl::optional<chromeos::settings::mojom::Setting> setting) {
+ if (setting.has_value()) {
+ changed_settings_.insert(
+ base::NumberToString(static_cast<int>(setting.value())));
+ }
base::TimeTicks now = base::TimeTicks::Now();
if (!last_record_setting_changed_timestamp_.is_null()) {
@@ -119,4 +213,34 @@ void PerSessionSettingsUserActionTracker::ResetMetricsCountersAndTimestamp() {
num_searches_since_start_time_ = 0u;
}
+absl::optional<int>
+PerSessionSettingsUserActionTracker::UpdateSettingsPrefTotalUniqueChanged() {
+ // Fetch the dictionary from the pref.
+ ScopedDictPrefUpdate total_unique_settings_changed_(
+ pref_service_, ::prefs::kTotalUniqueOsSettingsChanged);
+ base::Value::Dict& pref_data = total_unique_settings_changed_.Get();
+ int current_count = pref_data.size();
+
+ // Set the dictionary.
+ // Value is a constant 1 since we only want to know which Setting has been
+ // used, not how many times it has been used.
+ constexpr int value = 1;
+ for (const std::string& setting_string : changed_settings_) {
+ if (!pref_data.contains(setting_string)) {
+ pref_data.Set(setting_string, value);
+ }
+ }
+
+ int new_count = pref_data.size();
+
+ // If the new size of the pref dictionary is the same as before, we do not
+ // want to record that in UMA so we will return a nullopt to flag not to add
+ // to histogram bucket.
+ //
+ // The value of pref_data will automatically get stored to pref_service_ upon
+ // destruction.
+ return current_count == new_count ? absl::nullopt
+ : absl::optional<int>{new_count};
+}
+
} // namespace ash::settings
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker.h b/chromium/chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker.h
index de21202069a..1bf9a1d1644 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker.h
+++ b/chromium/chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker.h
@@ -5,7 +5,12 @@
#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_SEARCH_PER_SESSION_SETTINGS_USER_ACTION_TRACKER_H_
#define CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_SEARCH_PER_SESSION_SETTINGS_USER_ACTION_TRACKER_H_
+#include <set>
+
#include "base/time/time.h"
+#include "chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom.h"
+#include "components/prefs/pref_service.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace ash::settings {
@@ -15,25 +20,60 @@ namespace ash::settings {
// should be created for that new session.
class PerSessionSettingsUserActionTracker {
public:
- PerSessionSettingsUserActionTracker();
+ explicit PerSessionSettingsUserActionTracker(PrefService* pref_service);
PerSessionSettingsUserActionTracker(
const PerSessionSettingsUserActionTracker& other) = delete;
PerSessionSettingsUserActionTracker& operator=(
const PerSessionSettingsUserActionTracker& other) = delete;
~PerSessionSettingsUserActionTracker();
+ void RecordPageActiveTime();
void RecordPageFocus();
void RecordPageBlur();
void RecordClick();
void RecordNavigation();
void RecordSearch();
- void RecordSettingChange();
+ // TODO (b/282233232): make 'setting' a required parameter once the
+ // corresponding function 'RecordSettingChange()' in ts files have been
+ // backfilled with the information on what specific Setting has been changed.
+ // In the meantime, this parameter is optional, and if it is not provided, it
+ // will be set to nullopt to indicate that it has not been initialized.
+ void RecordSettingChange(absl::optional<chromeos::settings::mojom::Setting>
+ setting = absl::nullopt);
+
+ const std::set<std::string>& GetChangedSettingsForTesting() {
+ return changed_settings_;
+ }
+ const base::TimeDelta& GetTotalTimeSessionActiveForTesting() {
+ return total_time_session_active_;
+ }
+ const base::TimeTicks& GetWindowLastActiveTimeStampForTesting() {
+ return window_last_active_timestamp_;
+ }
private:
friend class PerSessionSettingsUserActionTrackerTest;
+ // Clears the pref kTotalUniqueOsSettingsChanged after 7 days have passed
+ // since the user finished OOBE. We will track the changes made within the
+ // first week in
+ // ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime.FirstWeek, and
+ // ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime.SubsequentWeeks
+ // for the weeks following the first week.
+ void ClearTotalUniqueSettingsChangedPref();
+
+ // Checks whether it has been 7 days since the user has completed
+ // OOBE. It utilized the currently existing pref called kOobeOnboardingTime,
+ // which is set once the user finished the OOBE.
+ bool IsTodayInFirst7Days();
+
void ResetMetricsCountersAndTimestamp();
+ // Returns the size of the pref dict if it changes. Otherwise, no value will
+ // get returned if if there were no new unique settings changed in the
+ // session.
+ absl::optional<int> UpdateSettingsPrefTotalUniqueChanged();
+
// Time at which the last setting change metric was recorded since the window
// has been focused, or null if no setting change has been recorded since the
// window has been focused. Note that if the user blurs the window then
@@ -56,6 +96,18 @@ class PerSessionSettingsUserActionTracker {
// The last time at which a page blur event was received; if no blur events
// have been received, this field is_null().
base::TimeTicks last_blur_timestamp_;
+
+ // Tracks which settings have been changed in this user session
+ std::set<std::string> changed_settings_;
+
+ // Total time the Settings page has been active and in focus from the opening
+ // of the page to closing. Blur events pause the timer.
+ base::TimeDelta total_time_session_active_;
+
+ // The point in time which the Settings page was last active and in focus.
+ base::TimeTicks window_last_active_timestamp_;
+
+ raw_ptr<PrefService> pref_service_;
};
} // namespace ash::settings
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker_unittest.cc b/chromium/chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker_unittest.cc
index aa678f3103b..ddc32391b90 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker_unittest.cc
@@ -5,31 +5,65 @@
#include "chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker.h"
#include "base/test/metrics/histogram_tester.h"
-#include "base/test/task_environment.h"
#include "base/time/time.h"
+#include "chrome/browser/ash/login/login_pref_names.h"
+#include "chrome/test/base/browser_with_test_window_test.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "chrome/test/base/testing_profile.h"
+#include "chrome/test/base/testing_profile_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
+using chromeos::settings::mojom::Setting;
+
namespace ash::settings {
+constexpr char kProfileName[] = "user@gmail.com";
+
class PerSessionSettingsUserActionTrackerTest : public testing::Test {
protected:
PerSessionSettingsUserActionTrackerTest() = default;
~PerSessionSettingsUserActionTrackerTest() override = default;
- base::test::TaskEnvironment task_environment_{
+ void SetUp() override {
+ profile_manager_ = std::make_unique<TestingProfileManager>(
+ TestingBrowserProcess::GetGlobal());
+ ASSERT_TRUE(profile_manager_->SetUp());
+ testing_profile_ = profile_manager_->CreateTestingProfile(kProfileName);
+ test_pref_service_ = testing_profile_->GetPrefs();
+ tracker_ = std::make_unique<PerSessionSettingsUserActionTracker>(
+ test_pref_service_);
+ }
+
+ void TearDown() override {
+ if (tracker_) {
+ tracker_.reset();
+ }
+ profile_manager_->DeleteTestingProfile(kProfileName);
+ testing_profile_ = nullptr;
+ profile_manager_.reset();
+ }
+
+ std::string SettingAsIntString(Setting setting) {
+ return base::NumberToString(static_cast<int>(setting));
+ }
+
+ content::BrowserTaskEnvironment task_environment_{
base::test::TaskEnvironment::TimeSource::MOCK_TIME};
base::HistogramTester histogram_tester_;
- PerSessionSettingsUserActionTracker tracker_;
+ TestingProfile* testing_profile_;
+ raw_ptr<PrefService> test_pref_service_;
+ std::unique_ptr<TestingProfileManager> profile_manager_;
+ std::unique_ptr<PerSessionSettingsUserActionTracker> tracker_;
};
TEST_F(PerSessionSettingsUserActionTrackerTest, TestRecordMetrics) {
// Focus the page, perform some tasks, and change a setting.
- tracker_.RecordPageFocus();
- tracker_.RecordClick();
- tracker_.RecordNavigation();
- tracker_.RecordSearch();
+ tracker_->RecordPageFocus();
+ tracker_->RecordClick();
+ tracker_->RecordNavigation();
+ tracker_->RecordSearch();
task_environment_.FastForwardBy(base::Seconds(10));
- tracker_.RecordSettingChange();
+ tracker_->RecordSettingChange();
// The "first change" metrics should have been logged.
histogram_tester_.ExpectTotalCount(
@@ -48,11 +82,11 @@ TEST_F(PerSessionSettingsUserActionTrackerTest, TestRecordMetrics) {
// Without leaving the page, perform some more tasks, and change another
// setting.
- tracker_.RecordClick();
- tracker_.RecordNavigation();
- tracker_.RecordSearch();
+ tracker_->RecordClick();
+ tracker_->RecordNavigation();
+ tracker_->RecordSearch();
task_environment_.FastForwardBy(base::Seconds(10));
- tracker_.RecordSettingChange();
+ tracker_->RecordSettingChange();
// The "subsequent change" metrics should have been logged.
histogram_tester_.ExpectTotalCount(
@@ -71,11 +105,11 @@ TEST_F(PerSessionSettingsUserActionTrackerTest, TestRecordMetrics) {
// Repeat this, but only after 100ms. This is lower than the minimum value
// required for this metric, so it should be ignored.
- tracker_.RecordClick();
- tracker_.RecordNavigation();
- tracker_.RecordSearch();
+ tracker_->RecordClick();
+ tracker_->RecordNavigation();
+ tracker_->RecordSearch();
task_environment_.FastForwardBy(base::Milliseconds(100));
- tracker_.RecordSettingChange();
+ tracker_->RecordSettingChange();
// No additional logging should have occurred, so make the same verifications
// as above.
@@ -94,11 +128,11 @@ TEST_F(PerSessionSettingsUserActionTrackerTest, TestRecordMetrics) {
/*count=*/1);
// Repeat this once more, and verify that the counts increased.
- tracker_.RecordClick();
- tracker_.RecordNavigation();
- tracker_.RecordSearch();
+ tracker_->RecordClick();
+ tracker_->RecordNavigation();
+ tracker_->RecordSearch();
task_environment_.FastForwardBy(base::Seconds(10));
- tracker_.RecordSettingChange();
+ tracker_->RecordSettingChange();
// The "subsequent change" metrics should have been logged.
histogram_tester_.ExpectTotalCount(
@@ -118,10 +152,10 @@ TEST_F(PerSessionSettingsUserActionTrackerTest, TestRecordMetrics) {
TEST_F(PerSessionSettingsUserActionTrackerTest, TestBlurAndFocus) {
// Focus the page, click, and change a setting.
- tracker_.RecordPageFocus();
- tracker_.RecordClick();
+ tracker_->RecordPageFocus();
+ tracker_->RecordClick();
task_environment_.FastForwardBy(base::Seconds(1));
- tracker_.RecordSettingChange();
+ tracker_->RecordSettingChange();
histogram_tester_.ExpectTotalCount(
"ChromeOS.Settings.NumClicksUntilChange.FirstChange",
/*count=*/1);
@@ -133,11 +167,11 @@ TEST_F(PerSessionSettingsUserActionTrackerTest, TestBlurAndFocus) {
// Blur for 59 seconds (not quite a minute), click, and change a setting.
// Since the blur was under a minute, this should count for the "subsequent
// change" metrics.
- tracker_.RecordPageBlur();
+ tracker_->RecordPageBlur();
task_environment_.FastForwardBy(base::Seconds(59));
- tracker_.RecordPageFocus();
- tracker_.RecordClick();
- tracker_.RecordSettingChange();
+ tracker_->RecordPageFocus();
+ tracker_->RecordClick();
+ tracker_->RecordSettingChange();
histogram_tester_.ExpectTimeBucketCount(
"ChromeOS.Settings.BlurredWindowDuration",
/*sample=*/base::Seconds(59),
@@ -152,12 +186,12 @@ TEST_F(PerSessionSettingsUserActionTrackerTest, TestBlurAndFocus) {
// Now, blur for a full minute, click, and change a setting. Since the blur
// was a full minute, this should count for the "first change" metrics.
- tracker_.RecordPageBlur();
+ tracker_->RecordPageBlur();
task_environment_.FastForwardBy(base::Minutes(1));
- tracker_.RecordPageFocus();
+ tracker_->RecordPageFocus();
task_environment_.FastForwardBy(base::Seconds(5));
- tracker_.RecordClick();
- tracker_.RecordSettingChange();
+ tracker_->RecordClick();
+ tracker_->RecordSettingChange();
histogram_tester_.ExpectTimeBucketCount(
"ChromeOS.Settings.BlurredWindowDuration",
/*sample=*/base::Minutes(1),
@@ -171,4 +205,436 @@ TEST_F(PerSessionSettingsUserActionTrackerTest, TestBlurAndFocus) {
/*count=*/1);
}
+TEST_F(PerSessionSettingsUserActionTrackerTest, TestEndSessionWithBlur) {
+ // fast forward the time by 30 seconds. Total window active time does not get
+ // changed as we have not blurred the session.
+ tracker_->RecordPageFocus();
+ task_environment_.FastForwardBy(base::Seconds(30));
+ EXPECT_EQ(base::TimeDelta(), tracker_->GetTotalTimeSessionActiveForTesting());
+
+ // Total window active time changes to 30 seconds as the page is no longer in
+ // focus.
+ tracker_->RecordPageBlur();
+ EXPECT_EQ(base::Seconds(30), tracker_->GetTotalTimeSessionActiveForTesting());
+ // the window is no longer active, so the timer resets.
+ EXPECT_EQ(base::TimeTicks(),
+ tracker_->GetWindowLastActiveTimeStampForTesting());
+}
+
+TEST_F(PerSessionSettingsUserActionTrackerTest, TestUniqueChangedSettings) {
+ std::set<std::string> expected_set;
+
+ // Flip the WiFi toggle in Settings, this is a unique Setting that is changing
+ // so the number of unique settings that have been changed increases by 1 for
+ // a total of 1
+ tracker_->RecordSettingChange(Setting::kWifiOnOff);
+ expected_set = {SettingAsIntString(Setting::kWifiOnOff)};
+ EXPECT_EQ(expected_set, tracker_->GetChangedSettingsForTesting());
+
+ // Destruct tracker_ to trigger recording the data to the histogram.
+ tracker_.reset();
+ histogram_tester_.ExpectBucketCount(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.PerSession",
+ /*sample=*/1,
+ /*count=*/1);
+
+ // Create a new PerSessionSettingsUserActionTracker to imitate a newly opened
+ // Settings page.
+ tracker_ =
+ std::make_unique<PerSessionSettingsUserActionTracker>(test_pref_service_);
+
+ // test that the set has been destructed and cleared appropriately
+ expected_set = {};
+ EXPECT_EQ(expected_set, tracker_->GetChangedSettingsForTesting());
+
+ // Flip the Do Not Disturb and WiFi toggles in Settings, this is a unique
+ // Setting that is changing so the number of unique settings that have been
+ // changed increases by 1 for a total of 2
+ tracker_->RecordSettingChange(Setting::kDoNotDisturbOnOff);
+ tracker_->RecordSettingChange(Setting::kWifiOnOff);
+ expected_set = {SettingAsIntString(Setting::kDoNotDisturbOnOff),
+ SettingAsIntString(Setting::kWifiOnOff)};
+ EXPECT_EQ(expected_set, tracker_->GetChangedSettingsForTesting());
+
+ // Destruct tracker_ to trigger recording the data to the histogram.
+ tracker_.reset();
+ histogram_tester_.ExpectBucketCount(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.PerSession",
+ /*sample=*/2,
+ /*count=*/1);
+
+ // Create a new PerSessionSettingsUserActionTracker to imitate a newly opened
+ // Settings page.
+ tracker_ =
+ std::make_unique<PerSessionSettingsUserActionTracker>(test_pref_service_);
+
+ // Flip the Do Not Disturb and WiFi toggles. Flip Do Not Disturb toggle again
+ // in Settings, this is not a unique Setting that is changing so the number of
+ // unique settings that have been changed does not increase. The bucket sample
+ // 2 should now have 2 counts.
+ tracker_->RecordSettingChange(Setting::kDoNotDisturbOnOff);
+ tracker_->RecordSettingChange(Setting::kWifiOnOff);
+ tracker_->RecordSettingChange(Setting::kDoNotDisturbOnOff);
+ // expected_set will not change
+ EXPECT_EQ(expected_set, tracker_->GetChangedSettingsForTesting());
+
+ // Destruct tracker_ to trigger recording the data to the histogram.
+ tracker_.reset();
+
+ histogram_tester_.ExpectBucketCount(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.PerSession",
+ /*sample=*/2,
+ /*count=*/2);
+
+ // bucket 1 will still reflect the correct number of count added to it
+ histogram_tester_.ExpectBucketCount(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.PerSession",
+ /*sample=*/1,
+ /*count=*/1);
+}
+
+TEST_F(PerSessionSettingsUserActionTrackerTest,
+ TestTotalUniqueChangedSettings) {
+ // Simulate that the user has taken OOBE.
+ test_pref_service_->SetTime(::ash::prefs::kOobeOnboardingTime,
+ base::Time::Now());
+
+ std::set<std::string> expected_set;
+
+ // Flip the WiFi toggle in Settings, this is a unique Setting that is changing
+ // so the number of unique settings that have been changed increases by 1 for
+ // a total of 1.
+ tracker_->RecordSettingChange(Setting::kWifiOnOff);
+ expected_set = {SettingAsIntString(Setting::kWifiOnOff)};
+ EXPECT_EQ(expected_set, tracker_->GetChangedSettingsForTesting());
+
+ // Destruct tracker_ to trigger recording the data to the histogram.
+ tracker_.reset();
+ // The time is still in the first week, so the data gets recorded to
+ // .FirstWeek histogram.
+ histogram_tester_.ExpectBucketCount(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime.FirstWeek",
+ /*sample=*/1,
+ /*count=*/1);
+ // There are no data in the .SubsequentWeeks histogram.
+ histogram_tester_.ExpectBucketCount(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime."
+ "SubsequentWeeks",
+ /*sample=*/1,
+ /*count=*/0);
+ // Overall total unique Settings changed in the lifetime of the Device.
+ histogram_tester_.ExpectBucketCount(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime.Total",
+ /*sample=*/1,
+ /*count=*/1);
+
+ // Fast forward the time for 7 days and 1 second. We will now record data to
+ // .SubsequentWeeks instead of .FirstWeek.
+ task_environment_.FastForwardBy(base::Days(7));
+ task_environment_.FastForwardBy(base::Seconds(1));
+
+ // Create a new PerSessionSettingsUserActionTracker to imitate a newly opened
+ // Settings page.
+ tracker_ =
+ std::make_unique<PerSessionSettingsUserActionTracker>(test_pref_service_);
+
+ // test that the set has been destructed and cleared appropriately
+ expected_set = {};
+ EXPECT_EQ(expected_set, tracker_->GetChangedSettingsForTesting());
+
+ // Flip the Do Not Disturb toggle twice in Settings. Now that more than 7 days
+ // has passed since the user has taken OOBE, this change is a unique Setting
+ // that is changing so the number of unique settings in .SubsequentWeeks
+ // should increases by 1.
+ tracker_->RecordSettingChange(Setting::kDoNotDisturbOnOff);
+ expected_set = {SettingAsIntString(Setting::kDoNotDisturbOnOff)};
+ EXPECT_EQ(expected_set, tracker_->GetChangedSettingsForTesting());
+
+ // Destruct tracker_ to trigger recording the data to the histogram.
+ tracker_.reset();
+ // .FirstWeek will not change
+ histogram_tester_.ExpectBucketCount(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime.FirstWeek",
+ /*sample=*/1,
+ /*count=*/1);
+ histogram_tester_.ExpectBucketCount(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime."
+ "SubsequentWeeks",
+ /*sample=*/1,
+ /*count=*/1);
+ // Overall total unique Settings changed in the lifetime of the Device.
+ histogram_tester_.ExpectBucketCount(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime.Total",
+ /*sample=*/1,
+ /*count=*/2);
+
+ // Create a new PerSessionSettingsUserActionTracker to imitate a newly opened
+ // Settings page.
+ tracker_ =
+ std::make_unique<PerSessionSettingsUserActionTracker>(test_pref_service_);
+
+ // test that the set has been destructed and cleared appropriately
+ expected_set = {};
+ EXPECT_EQ(expected_set, tracker_->GetChangedSettingsForTesting());
+
+ // Flip the Do Not Disturb and WiFi toggles in Settings, this is a unique
+ // Setting that is changing so the number of unique settings that have been
+ // changed increases by 1. Note that we are still past the 1 week point, so we
+ // will add the data to .SubsequentWeeks histogram.
+ tracker_->RecordSettingChange(Setting::kDoNotDisturbOnOff);
+ tracker_->RecordSettingChange(Setting::kWifiOnOff);
+ expected_set = {SettingAsIntString(Setting::kDoNotDisturbOnOff),
+ SettingAsIntString(Setting::kWifiOnOff)};
+ EXPECT_EQ(expected_set, tracker_->GetChangedSettingsForTesting());
+
+ // Destruct tracker_ to trigger recording the data to the histogram.
+ tracker_.reset();
+ // .FirstWeek will not change
+ histogram_tester_.ExpectBucketCount(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime.FirstWeek",
+ /*sample=*/1,
+ /*count=*/1);
+ histogram_tester_.ExpectBucketCount(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime."
+ "SubsequentWeeks",
+ /*sample=*/1,
+ /*count=*/1);
+ histogram_tester_.ExpectBucketCount(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime."
+ "SubsequentWeeks",
+ /*sample=*/2,
+ /*count=*/1);
+ // Overall total unique Settings changed in the lifetime of the Device.
+ histogram_tester_.ExpectBucketCount(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime.Total",
+ /*sample=*/1,
+ /*count=*/2);
+ histogram_tester_.ExpectBucketCount(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime.Total",
+ /*sample=*/2,
+ /*count=*/1);
+
+ // Create a new PerSessionSettingsUserActionTracker to imitate a newly opened
+ // Settings page.
+ tracker_ =
+ std::make_unique<PerSessionSettingsUserActionTracker>(test_pref_service_);
+
+ // Flip the Do Not Disturb and WiFi toggles. Flip Do Not Disturb toggle again
+ // in Settings, this is not a unique Setting that is changing so the number of
+ // unique settings that have been changed does not increase. The bucket sample
+ // 2 should now have 2 counts.
+ tracker_->RecordSettingChange(Setting::kDoNotDisturbOnOff);
+ tracker_->RecordSettingChange(Setting::kWifiOnOff);
+ tracker_->RecordSettingChange(Setting::kDoNotDisturbOnOff);
+ // expected_set will not change
+ EXPECT_EQ(expected_set, tracker_->GetChangedSettingsForTesting());
+
+ // Destruct tracker_ to trigger recording the data to the histogram.
+ tracker_.reset();
+
+ histogram_tester_.ExpectBucketCount(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime.FirstWeek",
+ /*sample=*/1,
+ /*count=*/1);
+ histogram_tester_.ExpectBucketCount(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime."
+ "SubsequentWeeks",
+ /*sample=*/1,
+ /*count=*/1);
+ histogram_tester_.ExpectBucketCount(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime."
+ "SubsequentWeeks",
+ /*sample=*/2,
+ /*count=*/1);
+ // Overall total unique Settings changed in the lifetime of the Device.
+ histogram_tester_.ExpectBucketCount(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime.Total",
+ /*sample=*/1,
+ /*count=*/2);
+ histogram_tester_.ExpectBucketCount(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime.Total",
+ /*sample=*/2,
+ /*count=*/1);
+}
+
+TEST_F(PerSessionSettingsUserActionTrackerTest,
+ TestTotalUniqueChangedSettingsWithinFirstWeek) {
+ // Simulate that the user has taken OOBE.
+ test_pref_service_->SetTime(::ash::prefs::kOobeOnboardingTime,
+ base::Time::Now());
+ std::set<std::string> expected_set;
+
+ // Flip the Do Not Disturb and WiFi toggles in Settings, these are unique
+ // Settings that are changing so the number of unique settings that have been
+ // changed is 2.
+ tracker_->RecordSettingChange(Setting::kDoNotDisturbOnOff);
+ tracker_->RecordSettingChange(Setting::kWifiOnOff);
+ expected_set = {SettingAsIntString(Setting::kDoNotDisturbOnOff),
+ SettingAsIntString(Setting::kWifiOnOff)};
+ EXPECT_EQ(expected_set, tracker_->GetChangedSettingsForTesting());
+
+ // Destruct tracker_ to trigger recording the data to the histogram.
+ tracker_.reset();
+ histogram_tester_.ExpectBucketCount(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime.FirstWeek",
+ /*sample=*/2,
+ /*count=*/1);
+ // This is within the first week, no data should be recorded in the
+ // .SubsequentWeeks histogram
+ histogram_tester_.ExpectBucketCount(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime."
+ "SubsequentWeeks",
+ /*sample=*/2,
+ /*count=*/0);
+ histogram_tester_.ExpectBucketCount(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime.Total",
+ /*sample=*/2,
+ /*count=*/1);
+}
+
+TEST_F(PerSessionSettingsUserActionTrackerTest,
+ TestTotalUniqueChangedSettingsAfterFirstWeek) {
+ // Simulate that the user has taken OOBE.
+ test_pref_service_->SetTime(::ash::prefs::kOobeOnboardingTime,
+ base::Time::Now());
+ std::set<std::string> expected_set;
+ // Fast forward the time for 7 days and 1 second. We will now record data to
+ // .SubsequentWeeks instead of .FirstWeek.
+ task_environment_.FastForwardBy(base::Days(16));
+
+ // Flip the Do Not Disturb and WiFi toggles in Settings, these are unique
+ // Settings that are changing so the number of unique settings that have been
+ // changed is 2.
+ tracker_->RecordSettingChange(Setting::kDoNotDisturbOnOff);
+ tracker_->RecordSettingChange(Setting::kWifiOnOff);
+ expected_set = {SettingAsIntString(Setting::kDoNotDisturbOnOff),
+ SettingAsIntString(Setting::kWifiOnOff)};
+ EXPECT_EQ(expected_set, tracker_->GetChangedSettingsForTesting());
+
+ // Destruct tracker_ to trigger recording the data to the histogram.
+ tracker_.reset();
+ histogram_tester_.ExpectBucketCount(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime."
+ "SubsequentWeeks",
+ /*sample=*/2,
+ /*count=*/1);
+ // This is after the first week, no data should be recorded in the
+ // .FirstWeek histogram
+ histogram_tester_.ExpectBucketCount(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime.FirstWeek",
+ /*sample=*/2,
+ /*count=*/0);
+ histogram_tester_.ExpectBucketCount(
+ "ChromeOS.Settings.NumUniqueSettingsChanged.DeviceLifetime.Total",
+ /*sample=*/2,
+ /*count=*/1);
+}
+
+TEST_F(PerSessionSettingsUserActionTrackerTest,
+ TestNoTimeDeltaOpenCloseSettings) {
+ // Focus on page, close the page immediately. total_time_session_active_
+ // should be 0 seconds.
+ tracker_->RecordPageFocus();
+
+ // Destruct tracker_ to trigger recording the data to the histogram.
+ tracker_.reset();
+
+ histogram_tester_.ExpectTimeBucketCount(
+ "ChromeOS.Settings.WindowTotalActiveDuration",
+ /*sample=*/base::Seconds(0),
+ /*count=*/1);
+}
+
+TEST_F(PerSessionSettingsUserActionTrackerTest,
+ TestTotalTimeSessionActiveWithBlurAndFocus) {
+ // Focus on page, wait for 16 seconds to pass, and blur the page.
+ // total active time should be 16 seconds.
+ tracker_->RecordPageFocus();
+ task_environment_.FastForwardBy(base::Seconds(16));
+ tracker_->RecordPageBlur();
+ EXPECT_EQ(base::TimeTicks(),
+ tracker_->GetWindowLastActiveTimeStampForTesting());
+ EXPECT_EQ(base::Seconds(16), tracker_->GetTotalTimeSessionActiveForTesting());
+
+ // When the page is blurred, fast forwarding the time would not increase the
+ // total active time as the session is not active.
+ task_environment_.FastForwardBy(base::Seconds(59));
+ EXPECT_EQ(base::TimeTicks(),
+ tracker_->GetWindowLastActiveTimeStampForTesting());
+ EXPECT_EQ(base::Seconds(16), tracker_->GetTotalTimeSessionActiveForTesting());
+
+ // Focus back on the page, the timer should start up again. wait for 1 minute,
+ // now total active time should accumulate to 16 + 60 = 76 seconds.
+ tracker_->RecordPageFocus();
+ task_environment_.FastForwardBy(base::Minutes(1));
+ tracker_->RecordPageBlur();
+ EXPECT_EQ(base::TimeTicks(),
+ tracker_->GetWindowLastActiveTimeStampForTesting());
+ EXPECT_EQ(base::Seconds(76), tracker_->GetTotalTimeSessionActiveForTesting());
+ tracker_->RecordPageFocus();
+
+ // Destruct tracker_ to trigger recording the data to the histogram.
+ tracker_.reset();
+
+ // Histogram should have 1 count in the 76 seconds bucket.
+ histogram_tester_.ExpectTimeBucketCount(
+ "ChromeOS.Settings.WindowTotalActiveDuration",
+ /*sample=*/base::Seconds(76),
+ /*count=*/1);
+}
+
+TEST_F(PerSessionSettingsUserActionTrackerTest,
+ TestMultipleTotalTimeSessionActive) {
+ // Focus on page, wait for 22 seconds to pass.
+ tracker_->RecordPageFocus();
+ task_environment_.FastForwardBy(base::Seconds(22));
+
+ // Destruct tracker_ to trigger recording the data to the histogram.
+ tracker_.reset();
+
+ // Histogram should have 1 count in the 22 seconds bucket.
+ histogram_tester_.ExpectTimeBucketCount(
+ "ChromeOS.Settings.WindowTotalActiveDuration",
+ /*sample=*/base::Seconds(22),
+ /*count=*/1);
+
+ // Create a new tracker, focus on page, wait for another 22 seconds to
+ // pass.
+ tracker_ =
+ std::make_unique<PerSessionSettingsUserActionTracker>(test_pref_service_);
+ tracker_->RecordPageFocus();
+ task_environment_.FastForwardBy(base::Seconds(22));
+
+ // Destruct tracker_ to trigger recording the data to the histogram.
+ tracker_.reset();
+
+ // Histogram should have 2 counts in the 22 seconds bucket.
+ histogram_tester_.ExpectTimeBucketCount(
+ "ChromeOS.Settings.WindowTotalActiveDuration",
+ /*sample=*/base::Seconds(22),
+ /*count=*/2);
+
+ // Create a new tracker, focus on page, this time wait for 3 seconds to
+ // pass.
+ tracker_ =
+ std::make_unique<PerSessionSettingsUserActionTracker>(test_pref_service_);
+ tracker_->RecordPageFocus();
+ task_environment_.FastForwardBy(base::Seconds(3));
+
+ // Destruct tracker_ to trigger recording the data to the histogram.
+ tracker_.reset();
+
+ // Histogram should have 1 count in the 3 seconds bucket, 2 counts in 22
+ // seconds bucket.
+ histogram_tester_.ExpectTimeBucketCount(
+ "ChromeOS.Settings.WindowTotalActiveDuration",
+ /*sample=*/base::Seconds(3),
+ /*count=*/1);
+
+ histogram_tester_.ExpectTimeBucketCount(
+ "ChromeOS.Settings.WindowTotalActiveDuration",
+ /*sample=*/base::Seconds(22),
+ /*count=*/2);
+}
+
} // namespace ash::settings
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/settings_user_action_tracker.cc b/chromium/chrome/browser/ui/webui/settings/ash/settings_user_action_tracker.cc
index a45bac0e539..e8cc3546686 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/settings_user_action_tracker.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/settings_user_action_tracker.cc
@@ -15,8 +15,9 @@ namespace ash::settings {
SettingsUserActionTracker::SettingsUserActionTracker(
Hierarchy* hierarchy,
- OsSettingsSections* sections)
- : hierarchy_(hierarchy), sections_(sections) {}
+ OsSettingsSections* sections,
+ PrefService* pref_service)
+ : hierarchy_(hierarchy), sections_(sections), pref_service_(pref_service) {}
SettingsUserActionTracker::~SettingsUserActionTracker() = default;
@@ -31,16 +32,17 @@ void SettingsUserActionTracker::BindInterface(
// New session started, so create a new per session tracker.
per_session_tracker_ =
- std::make_unique<PerSessionSettingsUserActionTracker>();
+ std::make_unique<PerSessionSettingsUserActionTracker>(pref_service_);
}
void SettingsUserActionTracker::EndCurrentSession() {
- // Session ended, so delete the per session tracker.
+ // reset the pointers
per_session_tracker_.reset();
receiver_.reset();
}
void SettingsUserActionTracker::OnBindingDisconnected() {
+ // Settings window is closed by the user, ending the current session.
EndCurrentSession();
}
@@ -72,7 +74,7 @@ void SettingsUserActionTracker::RecordSettingChange() {
void SettingsUserActionTracker::RecordSettingChangeWithDetails(
chromeos::settings::mojom::Setting setting,
mojom::SettingChangeValuePtr value) {
- per_session_tracker_->RecordSettingChange();
+ per_session_tracker_->RecordSettingChange(setting);
// Get the primary section location of the changed setting and log the metric.
chromeos::settings::mojom::Section section_id =
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/settings_user_action_tracker.h b/chromium/chrome/browser/ui/webui/settings/ash/settings_user_action_tracker.h
index f97388209b6..127689400e5 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/settings_user_action_tracker.h
+++ b/chromium/chrome/browser/ui/webui/settings/ash/settings_user_action_tracker.h
@@ -11,6 +11,7 @@
#include "base/memory/raw_ptr.h"
#include "chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker.h"
#include "chrome/browser/ui/webui/settings/ash/search/user_action_recorder.mojom.h"
+#include "components/prefs/pref_service.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
@@ -24,7 +25,9 @@ class OsSettingsSections;
// a per section tracker to record metrics in each section.
class SettingsUserActionTracker : public mojom::UserActionRecorder {
public:
- SettingsUserActionTracker(Hierarchy* hierarchy, OsSettingsSections* sections);
+ SettingsUserActionTracker(Hierarchy* hierarchy,
+ OsSettingsSections* sections,
+ PrefService* pref_service);
SettingsUserActionTracker(const SettingsUserActionTracker& other) = delete;
SettingsUserActionTracker& operator=(const SettingsUserActionTracker& other) =
delete;
@@ -66,6 +69,7 @@ class SettingsUserActionTracker : public mojom::UserActionRecorder {
raw_ptr<Hierarchy, ExperimentalAsh> hierarchy_;
raw_ptr<OsSettingsSections, ExperimentalAsh> sections_;
+ raw_ptr<PrefService> pref_service_;
std::unique_ptr<PerSessionSettingsUserActionTracker> per_session_tracker_;
mojo::Receiver<mojom::UserActionRecorder> receiver_{this};
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/settings_user_action_tracker_unittest.cc b/chromium/chrome/browser/ui/webui/settings/ash/settings_user_action_tracker_unittest.cc
index 5bba5360c14..574a9cb166f 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/settings_user_action_tracker_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/settings_user_action_tracker_unittest.cc
@@ -12,10 +12,16 @@
#include "chrome/browser/ui/webui/settings/ash/search/per_session_settings_user_action_tracker.h"
#include "chrome/browser/ui/webui/settings/ash/search/user_action_recorder.mojom.h"
#include "chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom.h"
+#include "chrome/test/base/browser_with_test_window_test.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "chrome/test/base/testing_profile.h"
+#include "chrome/test/base/testing_profile_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace ash::settings {
+constexpr char kProfileName[] = "user@gmail.com";
+
namespace mojom {
using ::chromeos::settings::mojom::Section;
using ::chromeos::settings::mojom::Setting;
@@ -25,14 +31,28 @@ class SettingsUserActionTrackerTest : public testing::Test {
protected:
SettingsUserActionTrackerTest()
: fake_hierarchy_(&fake_sections_),
- tracker_(&fake_hierarchy_, &fake_sections_) {
+ tracker_(&fake_hierarchy_, &fake_sections_, GetTestProfilePref()) {
// Initialize per_session_tracker_ manually since BindInterface is never
// called on tracker_.
tracker_.per_session_tracker_ =
- std::make_unique<PerSessionSettingsUserActionTracker>();
+ std::make_unique<PerSessionSettingsUserActionTracker>(
+ testing_profile_->GetPrefs());
}
~SettingsUserActionTrackerTest() override = default;
+ void SetUpTestingProfile() {
+ profile_manager_ = std::make_unique<TestingProfileManager>(
+ TestingBrowserProcess::GetGlobal());
+ ASSERT_TRUE(profile_manager_->SetUp());
+ testing_profile_ = profile_manager_->CreateTestingProfile(kProfileName);
+ }
+
+ PrefService* GetTestProfilePref() {
+ SetUpTestingProfile();
+ test_pref_service_ = testing_profile_->GetPrefs();
+ return test_pref_service_;
+ }
+
// testing::Test:
void SetUp() override {
fake_hierarchy_.AddSettingMetadata(mojom::Section::kBluetooth,
@@ -49,10 +69,18 @@ class SettingsUserActionTrackerTest : public testing::Test {
mojom::Setting::kWifiAddNetwork);
}
+ void TearDown() override { tracker_.per_session_tracker_.reset(); }
+
+ // TestingProfile is bound to the IO thread:
+ // CurrentlyOn(content::BrowserThread::UI).
+ content::BrowserTaskEnvironment task_environment_;
base::HistogramTester histogram_tester_;
FakeOsSettingsSections fake_sections_;
+ raw_ptr<PrefService> test_pref_service_;
FakeHierarchy fake_hierarchy_;
+ std::unique_ptr<TestingProfileManager> profile_manager_;
SettingsUserActionTracker tracker_;
+ TestingProfile* testing_profile_;
};
TEST_F(SettingsUserActionTrackerTest, TestRecordSettingChangedBool) {
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/tts_handler.cc b/chromium/chrome/browser/ui/webui/settings/ash/tts_handler.cc
index 6398b9cdc05..987de613a82 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/tts_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/ash/tts_handler.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/ui/webui/settings/ash/tts_handler.h"
#include "base/functional/bind.h"
+#include "base/i18n/rtl.h"
#include "base/json/json_reader.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
@@ -68,6 +69,29 @@ void TtsHandler::HandleGetTtsExtensions(const base::Value::List& args) {
FireWebUIListener("tts-extensions-updated", responses);
}
+void TtsHandler::HandleGetDisplayNameForLocale(const base::Value::List& args) {
+ CHECK_EQ(2U, args.size());
+ const std::string callback_id = args[0].GetString();
+ const std::string locale = args[1].GetString();
+
+ const std::u16string display_name = l10n_util::GetDisplayNameForLocale(
+ locale, g_browser_process->GetApplicationLocale(), true);
+
+ AllowJavascript();
+ ResolveJavascriptCallback(callback_id, base::UTF16ToUTF8(display_name));
+}
+
+void TtsHandler::HandleGetApplicationLocale(const base::Value::List& args) {
+ CHECK_EQ(1U, args.size());
+ const std::string callback_id = args[0].GetString();
+
+ const std::string& application_locale =
+ g_browser_process->GetApplicationLocale();
+
+ AllowJavascript();
+ ResolveJavascriptCallback(callback_id, application_locale);
+}
+
void TtsHandler::OnVoicesChanged() {
content::TtsController* tts_controller =
content::TtsController::GetInstance();
@@ -113,6 +137,14 @@ void TtsHandler::RegisterMessages() {
base::BindRepeating(&TtsHandler::HandleGetTtsExtensions,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
+ "getDisplayNameForLocale",
+ base::BindRepeating(&TtsHandler::HandleGetDisplayNameForLocale,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "getApplicationLocale",
+ base::BindRepeating(&TtsHandler::HandleGetApplicationLocale,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
"previewTtsVoice",
base::BindRepeating(&SettingsWithTtsPreviewHandler::HandlePreviewTtsVoice,
base::Unretained(this)));
diff --git a/chromium/chrome/browser/ui/webui/settings/ash/tts_handler.h b/chromium/chrome/browser/ui/webui/settings/ash/tts_handler.h
index 27f7bf01ef1..a3f81e2a627 100644
--- a/chromium/chrome/browser/ui/webui/settings/ash/tts_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/ash/tts_handler.h
@@ -23,6 +23,8 @@ class TtsHandler : public SettingsWithTtsPreviewHandler {
void HandleGetAllTtsVoiceData(const base::Value::List& args);
void HandleGetTtsExtensions(const base::Value::List& args);
+ void HandleGetDisplayNameForLocale(const base::Value::List& args);
+ void HandleGetApplicationLocale(const base::Value::List& args);
// SettingsPageUIHandler implementation.
void RegisterMessages() override;
diff --git a/chromium/chrome/browser/ui/webui/settings/captions_handler.cc b/chromium/chrome/browser/ui/webui/settings/captions_handler.cc
index a70e9562636..c3a94da8ae1 100644
--- a/chromium/chrome/browser/ui/webui/settings/captions_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/captions_handler.cc
@@ -4,7 +4,9 @@
#include "chrome/browser/ui/webui/settings/captions_handler.h"
+#include "base/containers/contains.h"
#include "base/functional/bind.h"
+#include "base/strings/string_split.h"
#include "base/values.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
@@ -33,6 +35,15 @@ namespace {
constexpr char kCodeKey[] = "code";
constexpr char kDisplayNameKey[] = "displayName";
constexpr char kNativeDisplayNameKey[] = "nativeDisplayName";
+
+// Gets a list of locales enabled by the Finch flag.
+std::vector<std::string> GetEnabledLanguages() {
+ return base::SplitString(
+ base::GetFieldTrialParamValueByFeature(media::kLiveCaptionMultiLanguage,
+ "available_languages"),
+ ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+}
+
} // namespace
namespace settings {
@@ -138,9 +149,11 @@ void CaptionsHandler::HandleInstallLanguagePacks(
}
base::Value::List CaptionsHandler::GetAvailableLanguagePacks() {
+ auto enabled_languages = GetEnabledLanguages();
base::Value::List available_language_packs;
for (const auto& config : speech::kLanguageComponentConfigs) {
- if (config.language_code != speech::LanguageCode::kNone) {
+ if (config.language_code != speech::LanguageCode::kNone &&
+ base::Contains(enabled_languages, config.language_name)) {
base::Value::Dict available_language_pack;
available_language_pack.Set(kCodeKey, config.language_name);
available_language_pack.Set(
diff --git a/chromium/chrome/browser/ui/webui/settings/chrome_cleanup_handler_win.cc b/chromium/chrome/browser/ui/webui/settings/chrome_cleanup_handler_win.cc
deleted file mode 100644
index e0daa4e0757..00000000000
--- a/chromium/chrome/browser/ui/webui/settings/chrome_cleanup_handler_win.cc
+++ /dev/null
@@ -1,304 +0,0 @@
-// Copyright 2017 The Chromium Authors
-// 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/chrome_cleanup_handler_win.h"
-
-#include <memory>
-#include <set>
-#include <string>
-#include <utility>
-
-#include "base/command_line.h"
-#include "base/feature_list.h"
-#include "base/functional/bind.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/metrics/user_metrics.h"
-#include "base/metrics/user_metrics_action.h"
-#include "base/strings/string_util.h"
-#include "base/synchronization/lock.h"
-#include "base/values.h"
-#include "build/branding_buildflags.h"
-#include "build/build_config.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h"
-#include "chrome/grit/generated_resources.h"
-#include "components/component_updater/pref_names.h"
-#include "components/prefs/pref_service.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_ui.h"
-#include "content/public/browser/web_ui_message_handler.h"
-#include "ui/base/l10n/l10n_util.h"
-
-using safe_browsing::ChromeCleanerController;
-
-namespace settings {
-
-namespace {
-
-// Returns a base::Value::List containing a copy of the file paths stored in
-// |files|.
-base::Value::List GetFilesAsListStorage(const std::set<base::FilePath>& files) {
- base::Value::List value;
- for (const base::FilePath& path : files) {
- base::Value::Dict item;
- item.Set("dirname", path.DirName().AsEndingWithSeparator().AsUTF8Unsafe());
- item.Set("basename", path.BaseName().AsUTF8Unsafe());
- value.Append(std::move(item));
- }
- return value;
-}
-
-// Returns a base::Value::List containing a copy of the strings stored in
-// |string_set|.
-base::Value::List GetStringSetAsListStorage(
- const std::set<std::wstring>& string_set) {
- base::Value::List value;
- for (const std::wstring& string : string_set)
- value.Append(base::AsString16(string));
-
- return value;
-}
-
-base::Value::Dict GetScannerResultsAsDictionary(
- const safe_browsing::ChromeCleanerScannerResults& scanner_results,
- Profile* profile) {
- base::Value::Dict value;
- value.Set("files", GetFilesAsListStorage(scanner_results.files_to_delete()));
- value.Set("registryKeys",
- GetStringSetAsListStorage(scanner_results.registry_keys()));
- return value;
-}
-
-std::string IdleReasonToString(
- ChromeCleanerController::IdleReason idle_reason) {
- switch (idle_reason) {
- case ChromeCleanerController::IdleReason::kInitial:
- return "initial";
- case ChromeCleanerController::IdleReason::kReporterFoundNothing:
- return "reporter_found_nothing";
- case ChromeCleanerController::IdleReason::kReporterFailed:
- return "reporter_failed";
- case ChromeCleanerController::IdleReason::kScanningFoundNothing:
- return "scanning_found_nothing";
- case ChromeCleanerController::IdleReason::kScanningFailed:
- return "scanning_failed";
- case ChromeCleanerController::IdleReason::kConnectionLost:
- return "connection_lost";
- case ChromeCleanerController::IdleReason::kUserDeclinedCleanup:
- return "user_declined_cleanup";
- case ChromeCleanerController::IdleReason::kCleaningFailed:
- return "cleaning_failed";
- case ChromeCleanerController::IdleReason::kCleaningSucceeded:
- return "cleaning_succeeded";
- case ChromeCleanerController::IdleReason::kCleanerDownloadFailed:
- return "cleaner_download_failed";
- }
- NOTREACHED();
- return "";
-}
-
-} // namespace
-
-ChromeCleanupHandler::ChromeCleanupHandler(Profile* profile)
- : controller_(ChromeCleanerController::GetInstance()), profile_(profile) {}
-
-ChromeCleanupHandler::~ChromeCleanupHandler() {
- controller_->RemoveObserver(this);
-}
-
-void ChromeCleanupHandler::RegisterMessages() {
- web_ui()->RegisterMessageCallback(
- "registerChromeCleanerObserver",
- base::BindRepeating(
- &ChromeCleanupHandler::HandleRegisterChromeCleanerObserver,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback(
- "startScanning",
- base::BindRepeating(&ChromeCleanupHandler::HandleStartScanning,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback(
- "restartComputer",
- base::BindRepeating(&ChromeCleanupHandler::HandleRestartComputer,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback(
- "startCleanup",
- base::BindRepeating(&ChromeCleanupHandler::HandleStartCleanup,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback(
- "notifyShowDetails",
- base::BindRepeating(&ChromeCleanupHandler::HandleNotifyShowDetails,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback(
- "notifyChromeCleanupLearnMoreClicked",
- base::BindRepeating(
- &ChromeCleanupHandler::HandleNotifyChromeCleanupLearnMoreClicked,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback(
- "getMoreItemsPluralString",
- base::BindRepeating(&ChromeCleanupHandler::HandleGetMoreItemsPluralString,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback(
- "getItemsToRemovePluralString",
- base::BindRepeating(
- &ChromeCleanupHandler::HandleGetItemsToRemovePluralString,
- base::Unretained(this)));
-}
-
-void ChromeCleanupHandler::OnJavascriptAllowed() {
- controller_->AddObserver(this);
-}
-
-void ChromeCleanupHandler::OnJavascriptDisallowed() {
- controller_->RemoveObserver(this);
-}
-
-void ChromeCleanupHandler::OnIdle(
- ChromeCleanerController::IdleReason idle_reason) {
- FireWebUIListener("chrome-cleanup-on-idle",
- base::Value(IdleReasonToString(idle_reason)));
-}
-
-void ChromeCleanupHandler::OnScanning() {
- FireWebUIListener("chrome-cleanup-on-scanning");
-}
-
-void ChromeCleanupHandler::OnReporterRunning() {
- FireWebUIListener("chrome-cleanup-on-reporter-running");
-}
-
-void ChromeCleanupHandler::OnInfected(
- bool is_powered_by_partner,
- const safe_browsing::ChromeCleanerScannerResults& scanner_results) {
- FireWebUIListener("chrome-cleanup-on-infected",
- base::Value(is_powered_by_partner),
- GetScannerResultsAsDictionary(scanner_results, profile_));
-}
-
-void ChromeCleanupHandler::OnCleaning(
- bool is_powered_by_partner,
- const safe_browsing::ChromeCleanerScannerResults& scanner_results) {
- FireWebUIListener("chrome-cleanup-on-cleaning",
- base::Value(is_powered_by_partner),
- GetScannerResultsAsDictionary(scanner_results, profile_));
-}
-
-void ChromeCleanupHandler::OnRebootRequired() {
- FireWebUIListener("chrome-cleanup-on-reboot-required");
-}
-
-void ChromeCleanupHandler::HandleRegisterChromeCleanerObserver(
- const base::Value::List& args) {
- DCHECK_EQ(0U, args.size());
-
- base::RecordAction(
- base::UserMetricsAction("SoftwareReporter.CleanupWebui_Shown"));
- AllowJavascript();
-
- FireWebUIListener("chrome-cleanup-enabled-change",
- base::Value(controller_->IsAllowedByPolicy()));
-}
-
-void ChromeCleanupHandler::HandleStartScanning(const base::Value::List& args) {
- CHECK_EQ(1U, args.size());
- bool allow_logs_upload = false;
- if (args[0].is_bool())
- allow_logs_upload = args[0].GetBool();
-
- // If this operation is not allowed the UI should be disabled.
- CHECK(controller_->IsAllowedByPolicy());
-
- // The state is propagated to all open tabs and should be consistent.
- DCHECK_EQ(controller_->logs_enabled(profile_), allow_logs_upload);
-
- controller_->RequestUserInitiatedScan(profile_);
-
- base::RecordAction(
- base::UserMetricsAction("SoftwareReporter.CleanupWebui_StartScanning"));
-}
-
-void ChromeCleanupHandler::HandleRestartComputer(
- const base::Value::List& args) {
- DCHECK_EQ(0U, args.size());
-
- base::RecordAction(
- base::UserMetricsAction("SoftwareReporter.CleanupWebui_RestartComputer"));
-
- controller_->Reboot();
-}
-
-void ChromeCleanupHandler::HandleStartCleanup(const base::Value::List& args) {
- CHECK_EQ(1U, args.size());
- bool allow_logs_upload = false;
- if (args[0].is_bool())
- allow_logs_upload = args[0].GetBool();
-
- // The state is propagated to all open tabs and should be consistent.
- DCHECK_EQ(controller_->logs_enabled(profile_), allow_logs_upload);
-
- base::RecordAction(
- base::UserMetricsAction("SoftwareReporter.CleanupWebui_StartCleanup"));
-
- controller_->ReplyWithUserResponse(
- profile_,
- allow_logs_upload
- ? ChromeCleanerController::UserResponse::kAcceptedWithLogs
- : ChromeCleanerController::UserResponse::kAcceptedWithoutLogs);
-}
-
-void ChromeCleanupHandler::HandleNotifyShowDetails(
- const base::Value::List& args) {
- CHECK_EQ(1U, args.size());
- bool details_section_visible = false;
- if (args[0].is_bool())
- details_section_visible = args[0].GetBool();
-
- if (details_section_visible) {
- base::RecordAction(
- base::UserMetricsAction("SoftwareReporter.CleanupWebui_ShowDetails"));
- } else {
- base::RecordAction(
- base::UserMetricsAction("SoftwareReporter.CleanupWebui_HideDetails"));
- }
-}
-
-void ChromeCleanupHandler::HandleNotifyChromeCleanupLearnMoreClicked(
- const base::Value::List& args) {
- CHECK_EQ(0U, args.size());
-
- base::RecordAction(
- base::UserMetricsAction("SoftwareReporter.CleanupWebui_LearnMore"));
-}
-
-void ChromeCleanupHandler::HandleGetMoreItemsPluralString(
- const base::Value::List& args) {
-#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
- GetPluralString(IDS_SETTINGS_RESET_CLEANUP_DETAILS_MORE, args);
-#endif // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
-}
-
-void ChromeCleanupHandler::HandleGetItemsToRemovePluralString(
- const base::Value::List& args) {
-#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
- GetPluralString(IDS_SETTINGS_RESET_CLEANUP_DETAILS_ITEMS_TO_BE_REMOVED, args);
-#endif // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
-}
-
-void ChromeCleanupHandler::GetPluralString(int id,
- const base::Value::List& args) {
- const auto& list = args;
- CHECK_EQ(2U, list.size());
-
- std::string callback_id = list[0].GetString();
-
- int num_items = list[1].GetIfInt().value_or(0);
-
- const std::u16string plural_string =
- num_items > 0 ? l10n_util::GetPluralStringFUTF16(id, num_items)
- : std::u16string();
- ResolveJavascriptCallback(base::Value(callback_id),
- base::Value(plural_string));
-}
-
-} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/chrome_cleanup_handler_win.h b/chromium/chrome/browser/ui/webui/settings/chrome_cleanup_handler_win.h
deleted file mode 100644
index e79cfd62430..00000000000
--- a/chromium/chrome/browser/ui/webui/settings/chrome_cleanup_handler_win.h
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2017 The Chromium Authors
-// 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_CHROME_CLEANUP_HANDLER_WIN_H_
-#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROME_CLEANUP_HANDLER_WIN_H_
-
-#include "base/memory/raw_ptr.h"
-#include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h"
-#include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_scanner_results_win.h"
-#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
-#include "components/prefs/pref_change_registrar.h"
-
-class Profile;
-
-namespace safe_browsing {
-class ChromeCleanerController;
-}
-
-namespace settings {
-
-// Chrome Cleanup settings page UI handler.
-class ChromeCleanupHandler
- : public SettingsPageUIHandler,
- public safe_browsing::ChromeCleanerController::Observer {
- public:
- explicit ChromeCleanupHandler(Profile* profile);
-
- ChromeCleanupHandler(const ChromeCleanupHandler&) = delete;
- ChromeCleanupHandler& operator=(const ChromeCleanupHandler&) = delete;
-
- ~ChromeCleanupHandler() override;
-
- // SettingsPageUIHandler implementation.
- void RegisterMessages() override;
- void OnJavascriptAllowed() override;
- void OnJavascriptDisallowed() override;
-
- // ChromeCleanerController::Observer implementation.
- void OnIdle(
- safe_browsing::ChromeCleanerController::IdleReason idle_reason) override;
- void OnReporterRunning() override;
- void OnScanning() override;
- void OnInfected(bool is_powered_by_partner,
- const safe_browsing::ChromeCleanerScannerResults&
- reported_results) override;
- void OnCleaning(bool is_powered_by_partner,
- const safe_browsing::ChromeCleanerScannerResults&
- reported_results) override;
- void OnRebootRequired() override;
-
- private:
- // Callback for the "registerChromeCleanerObserver" message. This registers
- // this object as an observer of the Chrome Cleanup global state and
- // and retrieves the current cleanup state.
- void HandleRegisterChromeCleanerObserver(const base::Value::List& args);
-
- // Callback for the "startScanning" message to start scanning the user's
- // system to detect unwanted software.
- void HandleStartScanning(const base::Value::List& args);
-
- // Callback for the "restartComputer" message to finalize the cleanup with a
- // system restart.
- void HandleRestartComputer(const base::Value::List& args);
-
- // Callback for the "startCleanup" message to start removing unwanted
- // software from the user's computer.
- void HandleStartCleanup(const base::Value::List& args);
-
- // Callback for the "showDetails" message that notifies Chrome about whether
- // the user expanded or closed the details section of the page.
- void HandleNotifyShowDetails(const base::Value::List& args);
-
- // Callback for the "chromeCleanupLearnMore" message that notifies Chrome that
- // the "learn more" link was clicked.
- void HandleNotifyChromeCleanupLearnMoreClicked(const base::Value::List& args);
-
- // Callback for the "getMoreItemsPluralString" message, that obtains the text
- // string for the "show more" items on the detailed view.
- void HandleGetMoreItemsPluralString(const base::Value::List& args);
-
- // Callback for the "getItemsToRemovePluralString" message, that obtains the
- // text string for the detailed view when user-initiated cleanups are enabled.
- void HandleGetItemsToRemovePluralString(const base::Value::List& args);
-
- void GetPluralString(int id, const base::Value::List& args);
-
- // Raw pointer to a singleton. Must outlive this object.
- raw_ptr<safe_browsing::ChromeCleanerController> controller_;
-
- raw_ptr<Profile> profile_;
-};
-
-} // namespace settings
-
-#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROME_CLEANUP_HANDLER_WIN_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/OWNERS b/chromium/chrome/browser/ui/webui/settings/chromeos/OWNERS
index 96f54b2cb48..7942dfa92ff 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/OWNERS
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/OWNERS
@@ -1 +1 @@
-file://chrome/browser/resources/settings/chromeos/OWNERS
+file://chrome/browser/resources/ash/settings/OWNERS
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 dfa3307a923..fb28c8abb20 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom
@@ -4,9 +4,10 @@
module chromeos.settings.mojom;
-// Chrome OS Settings sections (i.e., top-level navigation items). Each section
-// has a corresponding path string listed below. Numerical values are used for
-// metrics; do not change or reuse values.
+// ChromeOS Settings sections (i.e., top-level pages & their navigation items).
+// Each section has a corresponding path string listed below. Numerical values
+// are used for metrics.
+// DO NOT change or reuse values.
enum Section {
kNetwork = 0,
kBluetooth = 1,
@@ -45,6 +46,7 @@ enum Subpage {
kVpnDetails = 7,
kApn = 8,
kHotspotDetails = 9,
+ kPasspointDetails = 10,
// Bluetooth section.
kBluetoothDevices = 100,
@@ -85,6 +87,7 @@ enum Subpage {
kPerDeviceTouchpad = 411,
kPerDevicePointingStick = 412,
kPerDeviceKeyboardRemapKeys = 413,
+ kGraphicsTablet = 414,
// Personalization section.
// 500 was used for kChangePicture. Do not reuse.
@@ -148,6 +151,7 @@ enum Subpage {
kNetworkFileShares = 1300,
kOfficeFiles = 1301,
kGoogleDrive = 1302,
+ kOneDrive = 1303,
// Printing section.
kPrintingDetails = 1400,
@@ -178,16 +182,18 @@ enum Subpage {
// Network section.
const string kNetworkSectionPath = "internet";
const string kEthernetDetailsSubpagePath = "networkDetail";
+const string kNetworksSubpageBasePath = "networks";
const string kWifiNetworksSubpagePath = "networks?type=WiFi";
-const string kWifiDetailsSubpagePath = "networkDetail";
-const string kKnownNetworksSubpagePath = "knownNetworks";
const string kCellularNetworksSubpagePath = "networks?type=Cellular";
const string kMobileDataNetworksSubpagePath = "networks?type=Tether";
+const string kKnownNetworksSubpagePath = "knownNetworks";
+const string kWifiDetailsSubpagePath = "networkDetail";
const string kCellularDetailsSubpagePath = "networkDetail";
const string kTetherDetailsSubpagePath = "networkDetail";
const string kVpnDetailsSubpagePath = "networkDetail";
const string kApnSubpagePath = "apn";
const string kHotspotSubpagePath = "hotspotDetail";
+const string kPasspointDetailSubpagePath = "passpointDetail";
// Bluetooth section.
const string kBluetoothSectionPath = "bluetooth";
@@ -223,6 +229,7 @@ const string kAudioSubpagePath = "audio";
const string kStorageSubpagePath = "storage";
const string kExternalStorageSubpagePath = "storage/externalStoragePreferences";
const string kPowerSubpagePath = "power";
+const string kGraphicsTabletSubpagePath = "graphics-tablet";
// Personalization section.
const string kPersonalizationSectionPath = "personalization";
@@ -285,8 +292,9 @@ const string kJapaneseManageUserDictionarySubpagePath =
// Files section.
const string kFilesSectionPath = "files";
const string kGoogleDriveSubpagePath = "googleDrive";
-const string kNetworkFileSharesSubpagePath = "smbShares";
+const string kOneDriveSubpagePath = "oneDrive";
const string kOfficeFilesSubpagePath = "officeFiles";
+const string kNetworkFileSharesSubpagePath = "smbShares";
// Printing section.
const string kPrintingSectionPath = "osPrinting";
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 c4f71859a82..02bfa2e447d 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom
@@ -144,6 +144,9 @@ enum Setting {
kAdaptiveCharging = 440,
kKeyboardBlockMetaFkeyRewrites = 441,
kKeyboardRemapKeys = 442,
+ kChargingSounds = 443,
+ kLowBatterySound = 444,
+ kBatterySaver = 445,
// Personalization section.
kOpenWallpaper = 500,
@@ -215,6 +218,8 @@ enum Setting {
kCameraOnOff = 1116,
kMicrophoneOnOff = 1117,
kGeolocationOnOff = 1118,
+ kLockScreenNotification = 1119,
+ kSpeakOnMuteDetectionOnOff = 1120,
// Languages and Input section.
kAddLanguage = 1200,
diff --git a/chromium/chrome/browser/ui/webui/settings/downloads_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/downloads_handler_unittest.cc
index 1befd7801a7..ac9c7dc9c9e 100644
--- a/chromium/chrome/browser/ui/webui/settings/downloads_handler_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/downloads_handler_unittest.cc
@@ -81,7 +81,8 @@ class DownloadsHandlerTest : public testing::Test {
raw_ptr<DownloadCoreService> service_;
raw_ptr<content::MockDownloadManager>
download_manager_; // Owned by |profile_|.
- raw_ptr<ChromeDownloadManagerDelegate> chrome_download_manager_delegate_;
+ raw_ptr<ChromeDownloadManagerDelegate, DanglingUntriaged>
+ chrome_download_manager_delegate_;
bool connection_policy_enabled_;
std::string account_name_, account_login_, folder_name_, folder_id_;
diff --git a/chromium/chrome/browser/ui/webui/settings/extensions_safety_check_handler.cc b/chromium/chrome/browser/ui/webui/settings/extensions_safety_check_handler.cc
deleted file mode 100644
index f44a00e9aaa..00000000000
--- a/chromium/chrome/browser/ui/webui/settings/extensions_safety_check_handler.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// 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/extensions_safety_check_handler.h"
-
-#include "chrome/grit/generated_resources.h"
-#include "ui/base/l10n/l10n_util.h"
-
-namespace settings {
-
-ExtensionsSafetyCheckHandler::ExtensionsSafetyCheckHandler() = default;
-
-ExtensionsSafetyCheckHandler::~ExtensionsSafetyCheckHandler() = default;
-
-void ExtensionsSafetyCheckHandler::HandleGetExtensionsThatNeedReview(
- const base::Value::List& args) {
- const base::Value& callback_id = args[0];
- AllowJavascript();
- ResolveJavascriptCallback(callback_id,
- base::Value(GetExtensionsThatNeedReview()));
-}
-
-std::u16string ExtensionsSafetyCheckHandler::GetExtensionsThatNeedReview() {
- // TODO(psarouthakis): Replace skeleton code to return real number of
- // extensions that need to be reviewed via the CWSInfoService and
- // update the string ID to use new extensions safety check strings.
- return (l10n_util::GetPluralStringFUTF16(
- IDS_SETTINGS_SAFETY_CHECK_EXTENSIONS_BLOCKLISTED_OFF, 1));
-}
-
-void ExtensionsSafetyCheckHandler::OnJavascriptAllowed() {}
-
-void ExtensionsSafetyCheckHandler::OnJavascriptDisallowed() {}
-
-void ExtensionsSafetyCheckHandler::RegisterMessages() {
- // Usage of base::Unretained(this) is safe, because web_ui() owns `this` and
- // won't release ownership until destruction.
- web_ui()->RegisterMessageCallback(
- "getExtensionsThatNeedReview",
- base::BindRepeating(
- &ExtensionsSafetyCheckHandler::HandleGetExtensionsThatNeedReview,
- base::Unretained(this)));
-}
-
-} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/extensions_safety_check_handler.h b/chromium/chrome/browser/ui/webui/settings/extensions_safety_check_handler.h
deleted file mode 100644
index d53037d0902..00000000000
--- a/chromium/chrome/browser/ui/webui/settings/extensions_safety_check_handler.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// 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_EXTENSIONS_SAFETY_CHECK_HANDLER_H_
-#define CHROME_BROWSER_UI_WEBUI_SETTINGS_EXTENSIONS_SAFETY_CHECK_HANDLER_H_
-
-#include "base/memory/raw_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
-
-namespace settings {
-
-// Settings page UI handler that checks for any extensions that trigger
-// a review by the safety check.
-class ExtensionsSafetyCheckHandler : public settings::SettingsPageUIHandler {
- public:
- ExtensionsSafetyCheckHandler();
- ~ExtensionsSafetyCheckHandler() override;
-
- protected:
- // Return the display string that represents how many extensions
- // need to be reviewed by the user.
- std::u16string GetExtensionsThatNeedReview();
-
- private:
- // Calculate the number of extensions that need to be reviewed by the
- // user.
- void HandleGetExtensionsThatNeedReview(const base::Value::List& args);
-
- // SettingsPageUIHandler implementation.
- void OnJavascriptDisallowed() override;
- void OnJavascriptAllowed() override;
-
- // WebUIMessageHandler implementation.
- void RegisterMessages() override;
-
- base::WeakPtrFactory<ExtensionsSafetyCheckHandler> weak_ptr_factory_{this};
-};
-
-} // namespace settings
-
-#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_EXTENSIONS_SAFETY_CHECK_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/extensions_safety_check_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/extensions_safety_check_handler_unittest.cc
deleted file mode 100644
index 30958e0c9ad..00000000000
--- a/chromium/chrome/browser/ui/webui/settings/extensions_safety_check_handler_unittest.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// 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/extensions_safety_check_handler.h"
-
-#include <string>
-
-#include "chrome/test/base/testing_profile.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-class TestingExtensionsSafetyCheckHandler
- : public settings::ExtensionsSafetyCheckHandler {
- public:
- using ExtensionsSafetyCheckHandler::AllowJavascript;
- using ExtensionsSafetyCheckHandler::DisallowJavascript;
- using ExtensionsSafetyCheckHandler::GetExtensionsThatNeedReview;
-};
-
-} // namespace
-
-class ExtensionsSafetyCheckHandlerTest : public testing::Test {
- protected:
- std::unique_ptr<TestingProfile> profile_;
- std::unique_ptr<TestingExtensionsSafetyCheckHandler> entry_point_handler_;
- base::test::ScopedFeatureList feature_list_;
-};
-
-TEST_F(ExtensionsSafetyCheckHandlerTest, GetExtensionsThatNeedReviewTest) {
- // Display string for 1 triggering extension.
- std::u16string display_string =
- u"1 potentially harmful extension is off. You can also remove it.";
- EXPECT_EQ(display_string,
- entry_point_handler_->GetExtensionsThatNeedReview());
-}
diff --git a/chromium/chrome/browser/ui/webui/settings/hats_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/hats_handler_unittest.cc
index 14701e76e20..54c4e57cea4 100644
--- a/chromium/chrome/browser/ui/webui/settings/hats_handler_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/hats_handler_unittest.cc
@@ -80,8 +80,9 @@ class HatsHandlerTest : public ChromeRenderViewHostTestHarness {
content::TestWebUI* web_ui() { return web_ui_.get(); }
HatsHandler* handler() { return handler_.get(); }
- raw_ptr<MockHatsService> mock_hats_service_;
- raw_ptr<MockTrustSafetySentimentService> mock_sentiment_service_;
+ raw_ptr<MockHatsService, DanglingUntriaged> mock_hats_service_;
+ raw_ptr<MockTrustSafetySentimentService, DanglingUntriaged>
+ mock_sentiment_service_;
protected:
// This should only be accessed in the test constructor, to avoid race
diff --git a/chromium/chrome/browser/ui/webui/settings/metrics_reporting_handler.cc b/chromium/chrome/browser/ui/webui/settings/metrics_reporting_handler.cc
index dceb42b0b3e..7c87022bd5b 100644
--- a/chromium/chrome/browser/ui/webui/settings/metrics_reporting_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/metrics_reporting_handler.cc
@@ -104,7 +104,7 @@ void MetricsReportingHandler::HandleSetMetricsReportingEnabled(
if (!lacros_chrome_service)
return;
// The metrics reporting API was added in Chrome OS 89.
- if (!lacros_chrome_service->IsMetricsReportingAvailable()) {
+ if (!lacros_chrome_service->IsSupported<crosapi::mojom::MetricsReporting>()) {
LOG(WARNING) << "MetricsReporting API not available";
return;
}
diff --git a/chromium/chrome/browser/ui/webui/settings/people_handler.cc b/chromium/chrome/browser/ui/webui/settings/people_handler.cc
index 16e81bb2922..77ebeea4178 100644
--- a/chromium/chrome/browser/ui/webui/settings/people_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/people_handler.cc
@@ -54,8 +54,8 @@
#include "components/strings/grit/components_strings.h"
#include "components/sync/base/passphrase_enums.h"
#include "components/sync/base/user_selectable_type.h"
-#include "components/sync/driver/sync_service_utils.h"
-#include "components/sync/driver/sync_user_settings.h"
+#include "components/sync/service/sync_service_utils.h"
+#include "components/sync/service/sync_user_settings.h"
#include "components/unified_consent/unified_consent_metrics.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
@@ -433,10 +433,6 @@ void PeopleHandler::HandleSetDatatypes(const base::Value::List& args) {
// Choosing data types to sync never fails.
ResolveJavascriptCallback(*callback_id, base::Value(kConfigurePageStatus));
-
- ProfileMetrics::LogProfileSyncInfo(ProfileMetrics::SYNC_CUSTOMIZE);
- if (!configuration.sync_everything)
- ProfileMetrics::LogProfileSyncInfo(ProfileMetrics::SYNC_CHOOSE);
}
void PeopleHandler::HandleGetStoredAccounts(const base::Value::List& args) {
@@ -546,8 +542,6 @@ void PeopleHandler::HandleSetEncryptionPassphrase(
} else {
sync_user_settings->SetEncryptionPassphrase(passphrase);
successfully_set = true;
- ProfileMetrics::LogProfileSyncInfo(
- ProfileMetrics::SYNC_CREATED_NEW_PASSPHRASE);
}
ResolveJavascriptCallback(callback_id, base::Value(successfully_set));
}
@@ -573,10 +567,6 @@ void PeopleHandler::HandleSetDecryptionPassphrase(
bool successfully_set = false;
if (!passphrase.empty() && sync_user_settings->IsPassphraseRequired()) {
successfully_set = sync_user_settings->SetDecryptionPassphrase(passphrase);
- if (successfully_set) {
- ProfileMetrics::LogProfileSyncInfo(
- ProfileMetrics::SYNC_ENTERED_EXISTING_PASSPHRASE);
- }
}
ResolveJavascriptCallback(callback_id, base::Value(successfully_set));
}
@@ -782,15 +772,16 @@ void PeopleHandler::CloseSyncSetup() {
// (i.e. if the user is running in guest mode in cros and brings up settings).
LoginUIService* service = GetLoginUIService();
if (service) {
+ auto self_weak_ptr = weak_factory_.GetWeakPtr();
syncer::SyncService* sync_service = GetSyncService();
// Don't log a cancel event if the sync setup dialog is being
// automatically closed due to an auth error.
if ((service->current_login_ui() == this) &&
- (!sync_service ||
- (!sync_service->GetUserSettings()->IsFirstSetupComplete() &&
- sync_service->GetAuthError().state() ==
- GoogleServiceAuthError::NONE))) {
+ (!sync_service || (!sync_service->GetUserSettings()
+ ->IsInitialSyncFeatureSetupComplete() &&
+ sync_service->GetAuthError().state() ==
+ GoogleServiceAuthError::NONE))) {
if (configuring_sync_) {
// If the user clicked "Cancel" while setting up sync, disable sync
// because we don't want the sync engine to remain in the
@@ -805,7 +796,8 @@ void PeopleHandler::CloseSyncSetup() {
#if !BUILDFLAG(IS_CHROMEOS_ASH)
// Revoke sync consent on desktop Chrome if they click cancel during
// initial setup or close sync setup without confirming sync.
- if (!sync_service->GetUserSettings()->IsFirstSetupComplete()) {
+ if (!sync_service->GetUserSettings()
+ ->IsInitialSyncFeatureSetupComplete()) {
IdentityManagerFactory::GetForProfile(profile_)
->GetPrimaryAccountMutator()
->RevokeSyncConsent(
@@ -818,6 +810,14 @@ void PeopleHandler::CloseSyncSetup() {
}
service->LoginUIClosed(this);
+
+ // The call to RevokeSyncConsent() above may delete the current browser that
+ // owns `this` if force signin is enabled. Accessing instance members caused
+ // crashes (see https://crbug.com/1441820) which we guard against by
+ // checking a weak pointer to the current instance.
+ if (!self_weak_ptr) {
+ return;
+ }
}
// Alert the sync service anytime the sync setup dialog is closed. This can
@@ -894,7 +894,7 @@ void PeopleHandler::BeforeUnloadDialogCancelled() {
signin::ConsentLevel::kSync));
syncer::SyncService* service = GetSyncService();
DCHECK(service && service->IsSetupInProgress() &&
- !service->GetUserSettings()->IsFirstSetupComplete());
+ !service->GetUserSettings()->IsInitialSyncFeatureSetupComplete());
base::RecordAction(
base::UserMetricsAction("Signin_Signin_CancelAbortAdvancedSyncSettings"));
@@ -909,15 +909,10 @@ base::Value::Dict PeopleHandler::GetSyncStatusDictionary() const {
}
sync_status.Set("supervisedUser", profile_->IsChild());
- sync_status.Set("childUser", profile_->IsChild());
auto* identity_manager = IdentityManagerFactory::GetForProfile(profile_);
DCHECK(identity_manager);
- // TODO(crbug.com/1369982): |domain| is used to show the profile deletion
- // dialog on turn off sync. This is no longer needed since users are allowed
- // to turn off sync. Enterprise team to decide whether to show the delete
- // profile dialog on signout.
if (identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSignin)) {
CoreAccountInfo primary_account_info =
identity_manager->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin);
@@ -942,7 +937,7 @@ base::Value::Dict PeopleHandler::GetSyncStatusDictionary() const {
sync_status.Set(
"firstSetupInProgress",
service && !disallowed_by_policy && service->IsSetupInProgress() &&
- !service->GetUserSettings()->IsFirstSetupComplete() &&
+ !service->GetUserSettings()->IsInitialSyncFeatureSetupComplete() &&
identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync));
const SyncStatusLabels status_labels = GetSyncStatusLabels(profile_);
@@ -1081,15 +1076,16 @@ void PeopleHandler::MarkFirstSetupComplete() {
service->SetSyncFeatureRequested();
// If the first-time setup is already complete, there's nothing else to do.
- if (service->GetUserSettings()->IsFirstSetupComplete())
+ if (service->GetUserSettings()->IsInitialSyncFeatureSetupComplete()) {
return;
+ }
unified_consent::metrics::RecordSyncSetupDataTypesHistrogam(
service->GetUserSettings(), profile_->GetPrefs());
// We're done configuring, so notify SyncService that it is OK to start
// syncing.
- service->GetUserSettings()->SetFirstSetupComplete(
+ service->GetUserSettings()->SetInitialSyncFeatureSetupComplete(
syncer::SyncFirstSetupCompleteSource::ADVANCED_FLOW_CONFIRM);
FireWebUIListener("sync-settings-saved");
}
diff --git a/chromium/chrome/browser/ui/webui/settings/people_handler.h b/chromium/chrome/browser/ui/webui/settings/people_handler.h
index 09d2ab80866..5c6ec3870af 100644
--- a/chromium/chrome/browser/ui/webui/settings/people_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/people_handler.h
@@ -20,8 +20,8 @@
#include "components/prefs/pref_change_registrar.h"
#include "components/signin/public/base/signin_buildflags.h"
#include "components/signin/public/identity_manager/identity_manager.h"
-#include "components/sync/driver/sync_service.h"
-#include "components/sync/driver/sync_service_observer.h"
+#include "components/sync/service/sync_service.h"
+#include "components/sync/service/sync_service_observer.h"
#include "content/public/browser/web_contents_observer.h"
class LoginUIService;
@@ -233,7 +233,7 @@ class PeopleHandler : public SettingsPageUIHandler,
void InitializeSyncBlocker();
// Weak pointer.
- raw_ptr<Profile> profile_;
+ raw_ptr<Profile, DanglingUntriaged> profile_;
// Prevents Sync from running until configuration is complete.
std::unique_ptr<syncer::SyncSetupInProgressHandle> sync_blocker_;
diff --git a/chromium/chrome/browser/ui/webui/settings/people_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/people_handler_unittest.cc
index adb1ed37d8a..11918015874 100644
--- a/chromium/chrome/browser/ui/webui/settings/people_handler_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/people_handler_unittest.cc
@@ -48,7 +48,7 @@
#include "components/signin/public/identity_manager/identity_test_utils.h"
#include "components/sync/base/passphrase_enums.h"
#include "components/sync/base/user_selectable_type.h"
-#include "components/sync/driver/sync_user_settings_impl.h"
+#include "components/sync/service/sync_user_settings_impl.h"
#include "components/sync/test/mock_sync_service.h"
#include "components/sync/test/sync_user_settings_mock.h"
#include "content/public/browser/web_contents.h"
@@ -112,8 +112,6 @@ std::string GetConfiguration(SyncAllDataConfig sync_all,
result.Set("themesSynced", types.Has(syncer::UserSelectableType::kThemes));
result.Set("typedUrlsSynced",
types.Has(syncer::UserSelectableType::kHistory));
- result.Set("wifiConfigurationsSynced",
- types.Has(syncer::UserSelectableType::kWifiConfigurations));
result.Set("paymentsIntegrationEnabled", false);
// Reading list doesn't really have a UI and is supported on ios only.
@@ -166,8 +164,6 @@ void CheckConfigDataTypeArguments(const base::Value::Dict& dictionary,
types.Has(syncer::UserSelectableType::kThemes));
ExpectHasBoolKey(dictionary, "typedUrlsSynced",
types.Has(syncer::UserSelectableType::kHistory));
- ExpectHasBoolKey(dictionary, "wifiConfigurationsSynced",
- types.Has(syncer::UserSelectableType::kWifiConfigurations));
}
std::unique_ptr<KeyedService> BuildMockSyncService(
@@ -366,7 +362,7 @@ class PeopleHandlerTest : public ChromeRenderViewHostTestHarness {
testing::NiceMock<base::MockCallback<base::RepeatingClosure>>
mock_on_setup_in_progress_handle_destroyed_;
- raw_ptr<syncer::MockSyncService> mock_sync_service_;
+ raw_ptr<syncer::MockSyncService, DanglingUntriaged> mock_sync_service_;
std::unique_ptr<IdentityTestEnvironmentProfileAdaptor>
identity_test_env_adaptor_;
content::TestWebUI web_ui_;
@@ -384,8 +380,10 @@ TEST_F(PeopleHandlerTest, DisplayBasicLogin) {
handler_->DisallowJavascript();
ON_CALL(*mock_sync_service_, GetDisableReasons())
- .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN));
- ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsFirstSetupComplete())
+ .WillByDefault(Return(syncer::SyncService::DisableReasonSet(
+ {syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN})));
+ ON_CALL(*mock_sync_service_->GetMockUserSettings(),
+ IsInitialSyncFeatureSetupComplete())
.WillByDefault(Return(false));
// Ensure that the user is not signed in before calling |HandleStartSignin()|.
identity_test_env()->ClearPrimaryAccount();
@@ -411,7 +409,8 @@ TEST_F(PeopleHandlerTest, DisplayConfigureWithEngineDisabledAndCancel) {
CreatePeopleHandler();
ON_CALL(*mock_sync_service_, GetDisableReasons())
.WillByDefault(Return(syncer::SyncService::DisableReasonSet()));
- ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsFirstSetupComplete())
+ ON_CALL(*mock_sync_service_->GetMockUserSettings(),
+ IsInitialSyncFeatureSetupComplete())
.WillByDefault(Return(false));
ON_CALL(*mock_sync_service_, GetTransportState())
.WillByDefault(Return(syncer::SyncService::TransportState::INITIALIZING));
@@ -442,7 +441,8 @@ TEST_F(PeopleHandlerTest,
DisplayConfigureWithEngineDisabledAndSyncStartupCompleted) {
SigninUser();
CreatePeopleHandler();
- ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsFirstSetupComplete())
+ ON_CALL(*mock_sync_service_->GetMockUserSettings(),
+ IsInitialSyncFeatureSetupComplete())
.WillByDefault(Return(false));
ON_CALL(*mock_sync_service_, GetDisableReasons())
.WillByDefault(Return(syncer::SyncService::DisableReasonSet()));
@@ -484,7 +484,8 @@ TEST_F(PeopleHandlerTest,
CreatePeopleHandler();
ON_CALL(*mock_sync_service_, GetDisableReasons())
.WillByDefault(Return(syncer::SyncService::DisableReasonSet()));
- ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsFirstSetupComplete())
+ ON_CALL(*mock_sync_service_->GetMockUserSettings(),
+ IsInitialSyncFeatureSetupComplete())
.WillByDefault(Return(false));
EXPECT_CALL(*mock_sync_service_, GetTransportState())
.WillOnce(Return(syncer::SyncService::TransportState::INITIALIZING))
@@ -511,20 +512,24 @@ TEST_F(PeopleHandlerTest,
TEST_F(PeopleHandlerTest, RestartSyncAfterDashboardClear) {
SigninUser();
CreatePeopleHandler();
- // Clearing sync from the dashboard results in DISABLE_REASON_USER_CHOICE
- // being set.
- ON_CALL(*mock_sync_service_, GetDisableReasons())
- .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_USER_CHOICE));
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+ ON_CALL(*mock_sync_service_, IsSyncFeatureDisabledViaDashboard())
+ .WillByDefault(Return(true));
+#endif // BUILDFLAG(IS_CHROMEOS_ASH)
ON_CALL(*mock_sync_service_, GetTransportState())
.WillByDefault(Return(syncer::SyncService::TransportState::DISABLED));
// Attempting to open the setup UI should restart sync.
EXPECT_CALL(*mock_sync_service_, SetSyncFeatureRequested())
.WillOnce([&]() {
- // SetSyncFeatureRequested() clears DISABLE_REASON_USER_CHOICE, and
- // immediately starts initializing the engine.
+ // SetSyncFeatureRequested() clears IsSyncFeatureDisabledViaDashboard()
+ // and immediately starts initializing the engine.
ON_CALL(*mock_sync_service_, GetDisableReasons())
.WillByDefault(Return(syncer::SyncService::DisableReasonSet()));
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+ ON_CALL(*mock_sync_service_, IsSyncFeatureDisabledViaDashboard())
+ .WillByDefault(Return(false));
+#endif // BUILDFLAG(IS_CHROMEOS_ASH)
ON_CALL(*mock_sync_service_, GetTransportState())
.WillByDefault(
Return(syncer::SyncService::TransportState::INITIALIZING));
@@ -540,21 +545,25 @@ TEST_F(PeopleHandlerTest,
RestartSyncAfterDashboardClearWithStandaloneTransport) {
SigninUser();
CreatePeopleHandler();
- // Clearing sync from the dashboard results in DISABLE_REASON_USER_CHOICE
- // being set. However, the sync engine has restarted in standalone transport
- // mode.
- ON_CALL(*mock_sync_service_, GetDisableReasons())
- .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_USER_CHOICE));
+
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+ // Clearing sync from the dashboard results in
+ // IsSyncFeatureDisabledViaDashboard() returning true. Nevertheless,
+ // the sync engine has restarted in standalone transport mode.
+ ON_CALL(*mock_sync_service_, IsSyncFeatureDisabledViaDashboard())
+ .WillByDefault(Return(true));
+#endif // BUILDFLAG(IS_CHROMEOS_ASH)
+
ON_CALL(*mock_sync_service_, GetTransportState())
.WillByDefault(Return(syncer::SyncService::TransportState::ACTIVE));
// Attempting to open the setup UI should re-enable sync-the-feature.
EXPECT_CALL(*mock_sync_service_, SetSyncFeatureRequested())
.WillOnce([&]() {
- // SetSyncFeatureRequested() clears DISABLE_REASON_USER_CHOICE. Since
- // the engine is already running, it just gets reconfigured.
- ON_CALL(*mock_sync_service_, GetDisableReasons())
- .WillByDefault(Return(syncer::SyncService::DisableReasonSet()));
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+ ON_CALL(*mock_sync_service_, IsSyncFeatureDisabledViaDashboard())
+ .WillByDefault(Return(false));
+#endif // BUILDFLAG(IS_CHROMEOS_ASH)
ON_CALL(*mock_sync_service_, GetTransportState())
.WillByDefault(
Return(syncer::SyncService::TransportState::CONFIGURING));
@@ -603,9 +612,10 @@ TEST_F(PeopleHandlerTest, UnrecoverableErrorInitializingSync) {
SigninUser();
CreatePeopleHandler();
ON_CALL(*mock_sync_service_, GetDisableReasons())
- .WillByDefault(
- Return(syncer::SyncService::DISABLE_REASON_UNRECOVERABLE_ERROR));
- ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsFirstSetupComplete())
+ .WillByDefault(Return(syncer::SyncService::DisableReasonSet(
+ {syncer::SyncService::DISABLE_REASON_UNRECOVERABLE_ERROR})));
+ ON_CALL(*mock_sync_service_->GetMockUserSettings(),
+ IsInitialSyncFeatureSetupComplete())
.WillByDefault(Return(false));
// Open the web UI.
handler_->HandleShowSyncSetupUI(base::Value::List());
@@ -617,8 +627,10 @@ TEST_F(PeopleHandlerTest, GaiaErrorInitializingSync) {
SigninUser();
CreatePeopleHandler();
ON_CALL(*mock_sync_service_, GetDisableReasons())
- .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN));
- ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsFirstSetupComplete())
+ .WillByDefault(Return(syncer::SyncService::DisableReasonSet(
+ {syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN})));
+ ON_CALL(*mock_sync_service_->GetMockUserSettings(),
+ IsInitialSyncFeatureSetupComplete())
.WillByDefault(Return(false));
// Open the web UI.
handler_->HandleShowSyncSetupUI(base::Value::List());
@@ -916,7 +928,7 @@ TEST_F(PeopleHandlerTest, ShowSetupSyncForAllTypesIndividually) {
ON_CALL(*mock_sync_service_->GetMockUserSettings(),
IsSyncEverythingEnabled())
.WillByDefault(Return(false));
- syncer::UserSelectableTypeSet types(type);
+ const syncer::UserSelectableTypeSet types = {type};
ON_CALL(*mock_sync_service_->GetMockUserSettings(), GetSelectedTypes())
.WillByDefault(Return(types));
@@ -1114,12 +1126,16 @@ TEST_F(PeopleHandlerTest, DashboardClearWhileSettingsOpen_ConfirmSoon) {
handler_->HandleShowSyncSetupUI(base::Value::List());
+#if BUILDFLAG(IS_CHROMEOS_ASH)
// Now sync gets reset from the dashboard (the user clicked the "Manage synced
- // data" link), which results in the sync-requested and first-setup-complete
- // bits being cleared.
- ON_CALL(*mock_sync_service_, GetDisableReasons())
- .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_USER_CHOICE));
- ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsFirstSetupComplete())
+ // data" link), which results in the first-setup-complete bit being cleared.
+ // While first-setup isn't completed, IsSyncFeatureDisabledViaDashboard() also
+ // returns false.
+ ON_CALL(*mock_sync_service_, IsSyncFeatureDisabledViaDashboard())
+ .WillByDefault(Return(false));
+#endif // BUILDFLAG(IS_CHROMEOS_ASH)
+ ON_CALL(*mock_sync_service_->GetMockUserSettings(),
+ IsInitialSyncFeatureSetupComplete())
.WillByDefault(Return(false));
// Sync will eventually start again in transport mode.
ON_CALL(*mock_sync_service_, GetTransportState())
@@ -1132,21 +1148,17 @@ TEST_F(PeopleHandlerTest, DashboardClearWhileSettingsOpen_ConfirmSoon) {
// and the first-setup-complete bits.
EXPECT_CALL(*mock_sync_service_, SetSyncFeatureRequested())
.WillOnce([&]() {
- // SetSyncFeatureRequested() clears DISABLE_REASON_USER_CHOICE, and
- // immediately starts initializing the engine.
- ON_CALL(*mock_sync_service_, GetDisableReasons())
- .WillByDefault(Return(syncer::SyncService::DisableReasonSet()));
ON_CALL(*mock_sync_service_, GetTransportState())
.WillByDefault(
Return(syncer::SyncService::TransportState::INITIALIZING));
NotifySyncStateChanged();
});
EXPECT_CALL(*mock_sync_service_->GetMockUserSettings(),
- SetFirstSetupComplete(
+ SetInitialSyncFeatureSetupComplete(
syncer::SyncFirstSetupCompleteSource::ADVANCED_FLOW_CONFIRM))
.WillOnce([&](syncer::SyncFirstSetupCompleteSource) {
ON_CALL(*mock_sync_service_->GetMockUserSettings(),
- IsFirstSetupComplete())
+ IsInitialSyncFeatureSetupComplete())
.WillByDefault(Return(true));
NotifySyncStateChanged();
});
@@ -1164,12 +1176,16 @@ TEST_F(PeopleHandlerTest, DashboardClearWhileSettingsOpen_ConfirmLater) {
handler_->HandleShowSyncSetupUI(base::Value::List());
+#if BUILDFLAG(IS_CHROMEOS_ASH)
// Now sync gets reset from the dashboard (the user clicked the "Manage synced
- // data" link), which results in the sync-requested and first-setup-complete
- // bits being cleared.
- ON_CALL(*mock_sync_service_, GetDisableReasons())
- .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_USER_CHOICE));
- ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsFirstSetupComplete())
+ // data" link), which results in the first-setup-complete bit being cleared.
+ // While first-setup isn't completed, IsSyncFeatureDisabledViaDashboard() also
+ // returns false.
+ ON_CALL(*mock_sync_service_, IsSyncFeatureDisabledViaDashboard())
+ .WillByDefault(Return(false));
+#endif
+ ON_CALL(*mock_sync_service_->GetMockUserSettings(),
+ IsInitialSyncFeatureSetupComplete())
.WillByDefault(Return(false));
// Sync will eventually start again in transport mode.
ON_CALL(*mock_sync_service_, GetTransportState())
@@ -1182,12 +1198,12 @@ TEST_F(PeopleHandlerTest, DashboardClearWhileSettingsOpen_ConfirmLater) {
// transport mode.
ON_CALL(*mock_sync_service_, GetTransportState())
.WillByDefault(Return(syncer::SyncService::TransportState::ACTIVE));
- // On some platforms (e.g. ChromeOS), the first-setup-complete bit gets set
- // automatically during engine startup.
- if (browser_defaults::kSyncAutoStarts) {
- ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsFirstSetupComplete())
- .WillByDefault(Return(true));
- }
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+ // The first-setup-complete bit gets set automatically during engine startup.
+ ON_CALL(*mock_sync_service_->GetMockUserSettings(),
+ IsInitialSyncFeatureSetupComplete())
+ .WillByDefault(Return(true));
+#endif
NotifySyncStateChanged();
// Now the user confirms sync again. This should set the sync-requested bit
@@ -1195,27 +1211,22 @@ TEST_F(PeopleHandlerTest, DashboardClearWhileSettingsOpen_ConfirmLater) {
// first-setup-complete bit.
EXPECT_CALL(*mock_sync_service_, SetSyncFeatureRequested())
.WillOnce([&]() {
- // SetSyncFeatureRequested() clears DISABLE_REASON_USER_CHOICE, and
- // immediately starts initializing the engine.
- ON_CALL(*mock_sync_service_, GetDisableReasons())
- .WillByDefault(Return(syncer::SyncService::DisableReasonSet()));
ON_CALL(*mock_sync_service_, GetTransportState())
.WillByDefault(
Return(syncer::SyncService::TransportState::INITIALIZING));
NotifySyncStateChanged();
});
- if (!browser_defaults::kSyncAutoStarts) {
- EXPECT_CALL(
- *mock_sync_service_->GetMockUserSettings(),
- SetFirstSetupComplete(
- syncer::SyncFirstSetupCompleteSource::ADVANCED_FLOW_CONFIRM))
- .WillOnce([&](syncer::SyncFirstSetupCompleteSource) {
- ON_CALL(*mock_sync_service_->GetMockUserSettings(),
- IsFirstSetupComplete())
- .WillByDefault(Return(true));
- NotifySyncStateChanged();
- });
- }
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
+ EXPECT_CALL(*mock_sync_service_->GetMockUserSettings(),
+ SetInitialSyncFeatureSetupComplete(
+ syncer::SyncFirstSetupCompleteSource::ADVANCED_FLOW_CONFIRM))
+ .WillOnce([&](syncer::SyncFirstSetupCompleteSource) {
+ ON_CALL(*mock_sync_service_->GetMockUserSettings(),
+ IsInitialSyncFeatureSetupComplete())
+ .WillByDefault(Return(true));
+ NotifySyncStateChanged();
+ });
+#endif
base::Value::List did_abort;
did_abort.Append(false);
diff --git a/chromium/chrome/browser/ui/webui/settings/performance_handler.cc b/chromium/chrome/browser/ui/webui/settings/performance_handler.cc
index c149f5518ea..f3fed823b21 100644
--- a/chromium/chrome/browser/ui/webui/settings/performance_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/performance_handler.cc
@@ -6,12 +6,18 @@
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/values.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/chrome_pages.h"
#include "components/performance_manager/public/features.h"
#include "components/url_matcher/url_util.h"
+#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
+#include "url/gurl.h"
+
+using content::WebContents;
namespace settings {
@@ -38,6 +44,10 @@ void PerformanceHandler::RegisterMessages() {
base::BindRepeating(
&PerformanceHandler::HandleValidateTabDiscardExceptionRule,
base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "getCurrentOpenSites",
+ base::BindRepeating(&PerformanceHandler::HandleGetCurrentOpenSites,
+ base::Unretained(this)));
}
void PerformanceHandler::OnJavascriptAllowed() {
@@ -55,6 +65,49 @@ void PerformanceHandler::OnDeviceHasBatteryChanged(bool device_has_battery) {
FireWebUIListener("device-has-battery-changed", device_has_battery);
}
+base::Value PerformanceHandler::GetCurrentOpenSites() {
+ base::Value::List hosts;
+ std::set<std::pair<base::TimeTicks, std::string>, std::greater<>>
+ last_active_time_host_pairs;
+ const Profile* profile = Profile::FromWebUI(web_ui());
+ for (auto* browser : *BrowserList::GetInstance()) {
+ // Exclude browsers not signed into the current profile
+ if (browser->profile() != profile) {
+ continue;
+ }
+
+ TabStripModel* tab_strip_model = browser->tab_strip_model();
+
+ for (int tab_index = 0; tab_index < tab_strip_model->count(); ++tab_index) {
+ WebContents* web_contents = tab_strip_model->GetWebContentsAt(tab_index);
+ const GURL url = web_contents->GetLastCommittedURL();
+ if (url.is_valid() && url.SchemeIsHTTPOrHTTPS()) {
+ last_active_time_host_pairs.insert(
+ std::make_pair(web_contents->GetLastActiveTime(), url.host()));
+ }
+ }
+ }
+
+ std::unordered_set<std::string> added_hosts;
+ for (auto& [last_active_time, host] : last_active_time_host_pairs) {
+ if (!base::Contains(added_hosts, host)) {
+ added_hosts.insert(host);
+ hosts.Append(host);
+ }
+ }
+
+ return base::Value(std::move(hosts));
+}
+
+void PerformanceHandler::HandleGetCurrentOpenSites(
+ const base::Value::List& args) {
+ CHECK_EQ(1U, args.size());
+ const base::Value& callback_id = args[0];
+
+ AllowJavascript();
+ ResolveJavascriptCallback(callback_id, GetCurrentOpenSites());
+}
+
void PerformanceHandler::HandleGetDeviceHasBattery(
const base::Value::List& args) {
CHECK_EQ(1U, args.size());
diff --git a/chromium/chrome/browser/ui/webui/settings/performance_handler.h b/chromium/chrome/browser/ui/webui/settings/performance_handler.h
index 8915b9ab218..0c7fcc34329 100644
--- a/chromium/chrome/browser/ui/webui/settings/performance_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/performance_handler.h
@@ -27,6 +27,9 @@ class PerformanceHandler : public SettingsPageUIHandler,
void OnJavascriptDisallowed() override;
private:
+ friend class PerformanceHandlerTest;
+ FRIEND_TEST_ALL_PREFIXES(PerformanceHandlerTest, GetCurrentOpenSites);
+
base::ScopedObservation<
performance_manager::user_tuning::UserPerformanceTuningManager,
performance_manager::user_tuning::UserPerformanceTuningManager::Observer>
@@ -36,6 +39,12 @@ class PerformanceHandler : public SettingsPageUIHandler,
void OnDeviceHasBatteryChanged(bool device_has_battery) override;
/**
+ * Returns a list of currently opened tabs' urls in order of most recently used.
+ */
+ base::Value GetCurrentOpenSites();
+ void HandleGetCurrentOpenSites(const base::Value::List& args);
+
+ /**
* This function is called from the frontend in order to get the initial
* state of the battery, and also has the side effect of notifying the handler
* that it is ready to receive updates for future battery status changes.
diff --git a/chromium/chrome/browser/ui/webui/settings/performance_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/performance_handler_unittest.cc
new file mode 100644
index 00000000000..36e210003da
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/performance_handler_unittest.cc
@@ -0,0 +1,112 @@
+// Copyright 2023 The Chromium Authors
+// 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/performance_handler.h"
+
+#include "base/values.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/test/base/browser_with_test_window_test.h"
+#include "chrome/test/base/testing_profile.h"
+#include "content/public/browser/visibility.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/test/test_renderer_host.h"
+#include "content/public/test/test_web_ui.h"
+#include "content/public/test/web_contents_tester.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace settings {
+
+class PerformanceHandlerTest : public BrowserWithTestWindowTest {
+ public:
+ PerformanceHandlerTest() = default;
+
+ void SetUp() override {
+ web_contents_ = content::WebContentsTester::CreateTestWebContents(profile(), nullptr);
+ web_ui_ = std::make_unique<content::TestWebUI>();
+ web_ui_->set_web_contents(web_contents_.get());
+ handler_ = std::make_unique<PerformanceHandler>();
+ handler_->set_web_ui(web_ui());
+
+ incognito_profile_ = TestingProfile::Builder().BuildIncognito(profile());
+ }
+
+ void TearDown() override {
+ handler_->set_web_ui(nullptr);
+ handler_.reset();
+ web_ui_.reset();
+
+ for (auto& browser : browsers_) {
+ browser->tab_strip_model()->CloseAllTabs();
+ }
+ }
+
+ content::TestWebUI* web_ui() { return web_ui_.get(); }
+ PerformanceHandler* handler() { return handler_.get(); }
+ TestingProfile* profile() { return &profile_; }
+ TestingProfile* incognito_profile() { return incognito_profile_; }
+
+ Browser* AddBrowser(Profile* profile) {
+ Browser::CreateParams params(profile, true);
+ std::unique_ptr<Browser> browser =
+ CreateBrowserWithTestWindowForParams(params);
+ Browser* browser_ptr = browser.get();
+ browsers_.emplace_back(std::move(browser));
+ return browser_ptr;
+ }
+
+ content::WebContents* AddTabToBrowser(Browser* browser, GURL url) {
+ AddTab(browser, url);
+ return browser->tab_strip_model()->GetActiveWebContents();
+ }
+
+ void ExpectCurrentOpenSitesEquals(std::vector<std::string> expected_sites,
+ base::Value actual) {
+ ASSERT_TRUE(actual.is_list());
+ base::Value::List* actual_sites = actual.GetIfList();
+ EXPECT_EQ(expected_sites.size(), actual_sites->size());
+ for (size_t i = 0; i < expected_sites.size(); i++) {
+ const base::Value& actual_site_value = (*actual_sites)[i];
+ ASSERT_TRUE(actual_site_value.is_string());
+ const std::string actual_site = actual_site_value.GetString();
+ EXPECT_EQ(expected_sites[i], actual_site);
+ }
+ }
+
+ private:
+ content::RenderViewHostTestEnabler render_view_host_test_enabler_;
+ std::unique_ptr<content::TestWebUI> web_ui_;
+ std::unique_ptr<PerformanceHandler> handler_;
+ TestingProfile profile_;
+ raw_ptr<TestingProfile, DanglingUntriaged> incognito_profile_ = nullptr;
+ std::unique_ptr<content::WebContents> web_contents_;
+ std::vector<std::unique_ptr<Browser>> browsers_;
+};
+
+TEST_F(PerformanceHandlerTest, GetCurrentOpenSites) {
+ Browser* first_browser = AddBrowser(profile());
+ AddTabToBrowser(first_browser, GURL("https://www.foo.com/ignorethispart"));
+ content::WebContents* bar_tab =
+ AddTabToBrowser(first_browser, GURL("https://bar.com"));
+ AddTabToBrowser(first_browser, GURL("chrome://version"));
+
+ Browser* second_browser = AddBrowser(profile());
+ AddTabToBrowser(second_browser,
+ GURL("https://www.foo.com/ignorethispartaswell"));
+ AddTabToBrowser(second_browser, GURL("http://www.baz.com"));
+
+ Browser* incognito_browser = AddBrowser(incognito_profile());
+ AddTabToBrowser(incognito_browser,
+ GURL("https://www.toshowthiswouldbeaprivacyviolation.com"));
+
+ ExpectCurrentOpenSitesEquals({"www.baz.com", "www.foo.com", "bar.com"},
+ handler()->GetCurrentOpenSites());
+
+ bar_tab->UpdateWebContentsVisibility(content::Visibility::VISIBLE);
+ ExpectCurrentOpenSitesEquals({"bar.com", "www.baz.com", "www.foo.com"},
+ handler()->GetCurrentOpenSites());
+}
+
+} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/performance_settings_interactive_uitest.cc b/chromium/chrome/browser/ui/webui/settings/performance_settings_interactive_uitest.cc
index 8a30468b6d1..65db12188ea 100644
--- a/chromium/chrome/browser/ui/webui/settings/performance_settings_interactive_uitest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/performance_settings_interactive_uitest.cc
@@ -8,16 +8,19 @@
#include "base/test/power_monitor_test_utils.h"
#include "base/test/scoped_feature_list.h"
#include "build/branding_buildflags.h"
+#include "chrome/browser/browser_process.h"
#include "chrome/browser/ui/webui/feedback/feedback_dialog.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/ui_test_utils.h"
#include "chrome/test/interaction/interactive_browser_test.h"
+#include "chrome/test/interaction/webcontents_interaction_test_util.h"
#include "components/performance_manager/public/features.h"
#include "components/performance_manager/public/user_tuning/prefs.h"
#include "content/public/test/browser_test.h"
#include "url/gurl.h"
using performance_manager::user_tuning::prefs::BatterySaverModeState;
+using performance_manager::user_tuning::prefs::HighEfficiencyModeState;
namespace {
DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kPerformanceSettingsPage);
@@ -28,6 +31,14 @@ constexpr char kCheckJsElementIsChecked[] = "(el) => { return el.checked; }";
constexpr char kCheckJsElementIsNotChecked[] =
"(el) => { return !el.checked; }";
+const WebContentsInteractionTestUtil::DeepQuery kHighEfficiencyToggleQuery = {
+ "settings-ui",
+ "settings-main",
+ "settings-basic-page",
+ "settings-performance-page",
+ "settings-toggle-button",
+ "cr-toggle#control"};
+
class PerformanceSettingsInteractiveTest : public InteractiveBrowserTest {
public:
void SetUp() override {
@@ -78,14 +89,23 @@ class PerformanceSettingsInteractiveTest : public InteractiveBrowserTest {
return CheckResult(get_tab_count, expected_tab_count);
}
- auto CheckHighEffiencyModeLogged(
- bool high_efficiency_enabled,
+ auto CheckHighEfficiencyModePrefState(HighEfficiencyModeState state) {
+ return CheckResult(base::BindLambdaForTesting([]() {
+ return performance_manager::user_tuning::prefs::
+ GetCurrentHighEfficiencyModeState(
+ g_browser_process->local_state());
+ }),
+ state);
+ }
+
+ auto CheckHighEfficiencyModeLogged(
+ HighEfficiencyModeState state,
int expected_count,
const base::HistogramTester& histogram_tester) {
return Do(base::BindLambdaForTesting([=, &histogram_tester]() {
histogram_tester.ExpectBucketCount(
- "PerformanceControls.HighEfficiency.SettingsChangeMode",
- high_efficiency_enabled, expected_count);
+ "PerformanceControls.HighEfficiency.SettingsChangeMode2",
+ static_cast<int>(state), expected_count);
}));
}
@@ -124,6 +144,7 @@ class PerformanceSettingsInteractiveTest : public InteractiveBrowserTest {
return WaitForStateChange(contents_id, element_renders);
}
+ private:
raw_ptr<base::test::TestSamplingEventSource, DanglingUntriaged>
sampling_source_;
raw_ptr<base::test::TestBatteryLevelProvider, DanglingUntriaged>
@@ -132,6 +153,31 @@ class PerformanceSettingsInteractiveTest : public InteractiveBrowserTest {
};
IN_PROC_BROWSER_TEST_F(PerformanceSettingsInteractiveTest,
+ HighEfficiencyPrefChanged) {
+ RunTestSequence(
+ InstrumentTab(kPerformanceSettingsPage),
+ NavigateWebContents(kPerformanceSettingsPage,
+ GURL(chrome::kChromeUIPerformanceSettingsURL)),
+ WaitForElementToRender(kPerformanceSettingsPage,
+ kHighEfficiencyToggleQuery),
+ CheckJsResultAt(kPerformanceSettingsPage, kHighEfficiencyToggleQuery,
+ kCheckJsElementIsChecked),
+
+ // Turn Off High Efficiency Mode
+ ClickElement(kPerformanceSettingsPage, kHighEfficiencyToggleQuery),
+ WaitForButtonStateChange(kPerformanceSettingsPage,
+ kHighEfficiencyToggleQuery, false),
+ CheckHighEfficiencyModePrefState(HighEfficiencyModeState::kDisabled),
+
+ // Turn High Efficiency Mode back on
+ ClickElement(kPerformanceSettingsPage, kHighEfficiencyToggleQuery),
+ WaitForButtonStateChange(kPerformanceSettingsPage,
+ kHighEfficiencyToggleQuery, true),
+ CheckHighEfficiencyModePrefState(
+ HighEfficiencyModeState::kEnabledOnTimer));
+}
+
+IN_PROC_BROWSER_TEST_F(PerformanceSettingsInteractiveTest,
HighEfficiencyLearnMoreLinkNavigates) {
DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kLearnMorePage);
const DeepQuery high_efficiency_learn_more = {"settings-ui",
@@ -172,34 +218,30 @@ IN_PROC_BROWSER_TEST_F(PerformanceSettingsInteractiveTest,
IN_PROC_BROWSER_TEST_F(PerformanceSettingsInteractiveTest,
HighEfficiencyMetricsShouldLogOnToggle) {
- const DeepQuery high_efficiency_toggle = {"settings-ui",
- "settings-main",
- "settings-basic-page",
- "settings-performance-page",
- "settings-toggle-button",
- "cr-toggle#control"};
-
base::HistogramTester histogram_tester;
RunTestSequence(
InstrumentTab(kPerformanceSettingsPage),
NavigateWebContents(kPerformanceSettingsPage,
GURL(chrome::kChromeUIPerformanceSettingsURL)),
- WaitForElementToRender(kPerformanceSettingsPage, high_efficiency_toggle),
- CheckJsResultAt(kPerformanceSettingsPage, high_efficiency_toggle,
+ WaitForElementToRender(kPerformanceSettingsPage,
+ kHighEfficiencyToggleQuery),
+ CheckJsResultAt(kPerformanceSettingsPage, kHighEfficiencyToggleQuery,
kCheckJsElementIsChecked),
// Turn Off High Efficiency Mode
- ClickElement(kPerformanceSettingsPage, high_efficiency_toggle),
- WaitForButtonStateChange(kPerformanceSettingsPage, high_efficiency_toggle,
- false),
- CheckHighEffiencyModeLogged(false, 1, histogram_tester),
+ ClickElement(kPerformanceSettingsPage, kHighEfficiencyToggleQuery),
+ WaitForButtonStateChange(kPerformanceSettingsPage,
+ kHighEfficiencyToggleQuery, false),
+ CheckHighEfficiencyModeLogged(HighEfficiencyModeState::kDisabled, 1,
+ histogram_tester),
// Turn High Efficiency Mode back on
- ClickElement(kPerformanceSettingsPage, high_efficiency_toggle),
- WaitForButtonStateChange(kPerformanceSettingsPage, high_efficiency_toggle,
- true),
- CheckHighEffiencyModeLogged(true, 1, histogram_tester));
+ ClickElement(kPerformanceSettingsPage, kHighEfficiencyToggleQuery),
+ WaitForButtonStateChange(kPerformanceSettingsPage,
+ kHighEfficiencyToggleQuery, true),
+ CheckHighEfficiencyModeLogged(HighEfficiencyModeState::kEnabledOnTimer, 1,
+ histogram_tester));
}
IN_PROC_BROWSER_TEST_F(PerformanceSettingsInteractiveTest,
@@ -275,8 +317,9 @@ IN_PROC_BROWSER_TEST_F(PerformanceSettingsInteractiveTest,
}
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
+// TODO(http://b/281528238): reenable the test.
IN_PROC_BROWSER_TEST_F(PerformanceSettingsInteractiveTest,
- HighEfficiencySendFeedbackDialogOpens) {
+ DISABLED_HighEfficiencySendFeedbackDialogOpens) {
const DeepQuery high_efficiency_feedback = {
"settings-ui", "settings-main", "settings-basic-page",
"settings-section#performanceSettingsSection", "cr-icon-button#feedback"};
@@ -289,8 +332,9 @@ IN_PROC_BROWSER_TEST_F(PerformanceSettingsInteractiveTest,
InAnyContext(WaitForShow(FeedbackDialog::kFeedbackDialogForTesting)));
}
+// TODO(http://b/281528238): reenable the test.
IN_PROC_BROWSER_TEST_F(PerformanceSettingsInteractiveTest,
- BatterySaverSendFeedbackDialogOpens) {
+ DISABLED_BatterySaverSendFeedbackDialogOpens) {
const DeepQuery battery_saver_feedback = {
"settings-ui", "settings-main", "settings-basic-page",
"settings-section#batterySettingsSection", "cr-icon-button#feedback"};
diff --git a/chromium/chrome/browser/ui/webui/settings/privacy_sandbox_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/privacy_sandbox_handler_unittest.cc
index 9c050602484..42f836a240a 100644
--- a/chromium/chrome/browser/ui/webui/settings/privacy_sandbox_handler_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/privacy_sandbox_handler_unittest.cc
@@ -26,6 +26,8 @@ using Topic = browsing_topics::Topic;
constexpr char kCallbackId1[] = "test-callback-id";
constexpr char kCallbackId2[] = "test-callback-id-2";
+constexpr int kTestTaxonomyVersion = 1;
+
class MockPrivacySandboxService : public PrivacySandboxService {
public:
MOCK_METHOD(void,
@@ -220,8 +222,8 @@ TEST_F(PrivacySandboxHandlerTestMockService, GetFledgeState) {
TEST_F(PrivacySandboxHandlerTestMockService, SetTopicAllowed) {
// Confirm that the handler correctly constructs the CanonicalTopic and
// passes it to the PrivacySandboxService.
- const privacy_sandbox::CanonicalTopic kTestTopic(
- Topic(1), privacy_sandbox::CanonicalTopic::AVAILABLE_TAXONOMY);
+ const privacy_sandbox::CanonicalTopic kTestTopic(Topic(1),
+ kTestTaxonomyVersion);
EXPECT_CALL(*mock_privacy_sandbox_service(),
SetTopicAllowed(kTestTopic, false))
.Times(1);
@@ -234,15 +236,11 @@ TEST_F(PrivacySandboxHandlerTestMockService, SetTopicAllowed) {
TEST_F(PrivacySandboxHandlerTestMockService, GetTopicsState) {
const std::vector<privacy_sandbox::CanonicalTopic> kBlockedTopics = {
- privacy_sandbox::CanonicalTopic(
- Topic(1), privacy_sandbox::CanonicalTopic::AVAILABLE_TAXONOMY),
- privacy_sandbox::CanonicalTopic(
- Topic(2), privacy_sandbox::CanonicalTopic::AVAILABLE_TAXONOMY)};
+ privacy_sandbox::CanonicalTopic(Topic(1), kTestTaxonomyVersion),
+ privacy_sandbox::CanonicalTopic(Topic(2), kTestTaxonomyVersion)};
const std::vector<privacy_sandbox::CanonicalTopic> kTopTopics = {
- privacy_sandbox::CanonicalTopic(
- Topic(3), privacy_sandbox::CanonicalTopic::AVAILABLE_TAXONOMY),
- privacy_sandbox::CanonicalTopic(
- Topic(4), privacy_sandbox::CanonicalTopic::AVAILABLE_TAXONOMY)};
+ privacy_sandbox::CanonicalTopic(Topic(3), kTestTaxonomyVersion),
+ privacy_sandbox::CanonicalTopic(Topic(4), kTestTaxonomyVersion)};
EXPECT_CALL(*mock_privacy_sandbox_service(), GetCurrentTopTopics())
.Times(1)
diff --git a/chromium/chrome/browser/ui/webui/settings/protocol_handlers_handler.h b/chromium/chrome/browser/ui/webui/settings/protocol_handlers_handler.h
index f3ecf96e50a..cc0e76540fd 100644
--- a/chromium/chrome/browser/ui/webui/settings/protocol_handlers_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/protocol_handlers_handler.h
@@ -11,12 +11,12 @@
#include "base/scoped_observation.h"
#include "base/values.h"
#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
-#include "chrome/browser/web_applications/app_registrar_observer.h"
#include "chrome/browser/web_applications/web_app_id.h"
#include "chrome/browser/web_applications/web_app_install_manager.h"
#include "chrome/browser/web_applications/web_app_install_manager_observer.h"
#include "chrome/browser/web_applications/web_app_provider.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
+#include "chrome/browser/web_applications/web_app_registrar_observer.h"
#include "components/custom_handlers/protocol_handler_registry.h"
////////////////////////////////////////////////////////////////////////////////
@@ -32,7 +32,7 @@ namespace settings {
class ProtocolHandlersHandler
: public SettingsPageUIHandler,
public custom_handlers::ProtocolHandlerRegistry::Observer,
- public web_app::AppRegistrarObserver,
+ public web_app::WebAppRegistrarObserver,
public web_app::WebAppInstallManagerObserver {
public:
explicit ProtocolHandlersHandler(Profile* profile);
@@ -56,7 +56,7 @@ class ProtocolHandlersHandler
webapps::WebappUninstallSource uninstall_source) override;
void OnWebAppInstallManagerDestroyed() override;
- // web_app::AppRegistrarObserver:
+ // web_app::WebAppRegistrarObserver:
void OnWebAppProtocolSettingsChanged() override;
void OnAppRegistrarDestroyed() override;
@@ -135,7 +135,7 @@ class ProtocolHandlersHandler
const raw_ptr<web_app::WebAppProvider> web_app_provider_;
base::ScopedObservation<web_app::WebAppRegistrar,
- web_app::AppRegistrarObserver>
+ web_app::WebAppRegistrarObserver>
app_observation_{this};
base::ScopedObservation<web_app::WebAppInstallManager,
web_app::WebAppInstallManagerObserver>
diff --git a/chromium/chrome/browser/ui/webui/settings/recent_site_settings_helper.cc b/chromium/chrome/browser/ui/webui/settings/recent_site_settings_helper.cc
index dc3427f34b9..eb1d2bcdd39 100644
--- a/chromium/chrome/browser/ui/webui/settings/recent_site_settings_helper.cc
+++ b/chromium/chrome/browser/ui/webui/settings/recent_site_settings_helper.cc
@@ -60,7 +60,7 @@ std::map<GURL, std::vector<TimestampedSetting>> GetAllSettingsForProfile(
site_settings::GetSingleOriginExceptionsForContentType(
content_settings_map, content_type);
for (const auto& e : exceptions_for_type) {
- auto last_modified = e.metadata.last_modified;
+ auto last_modified = e.metadata.last_modified();
if (last_modified.is_null()) {
continue;
}
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 0dbccafb004..297c18b4ce5 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
@@ -34,7 +34,7 @@ base::Time GetSettingLastModifiedDate(HostContentSettingsMap* map,
ContentSettingsType type) {
content_settings::SettingInfo info;
map->GetWebsiteSetting(primary_url, secondary_url, type, &info);
- return info.metadata.last_modified;
+ return info.metadata.last_modified();
}
} // namespace
diff --git a/chromium/chrome/browser/ui/webui/settings/safety_check_extensions_handler.cc b/chromium/chrome/browser/ui/webui/settings/safety_check_extensions_handler.cc
new file mode 100644
index 00000000000..5b7c3a01fae
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/safety_check_extensions_handler.cc
@@ -0,0 +1,112 @@
+// Copyright 2023 The Chromium Authors
+// 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/safety_check_extensions_handler.h"
+
+#include "chrome/browser/extensions/cws_info_service.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/grit/generated_resources.h"
+#include "extensions/browser/extension_prefs.h"
+#include "extensions/browser/extension_prefs_factory.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/common/extension_id.h"
+#include "extensions/common/manifest.h"
+
+namespace settings {
+
+namespace {
+
+// `kPrefAcknowledgeSafetyCheckWarning` should mirror the definition in
+// chrome/browser/extensions/api/developer_private/developer_private_api.h.
+constexpr extensions::PrefMap kPrefAcknowledgeSafetyCheckWarning = {
+ "ack_safety_check_warning", extensions::PrefType::kBool,
+ extensions::PrefScope::kExtensionSpecific};
+
+} // namespace
+
+SafetyCheckExtensionsHandler::SafetyCheckExtensionsHandler(Profile* profile)
+ : profile_(profile) {}
+
+SafetyCheckExtensionsHandler::~SafetyCheckExtensionsHandler() = default;
+
+void SafetyCheckExtensionsHandler::HandleGetNumberOfExtensionsThatNeedReview(
+ const base::Value::List& args) {
+ const base::Value& callback_id = args[0];
+ AllowJavascript();
+ ResolveJavascriptCallback(callback_id,
+ base::Value(GetNumberOfExtensionsThatNeedReview()));
+}
+
+void SafetyCheckExtensionsHandler::SetCWSInfoServiceForTest(
+ extensions::CWSInfoService* cws_info_service) {
+ cws_info_service_ = cws_info_service;
+}
+
+int SafetyCheckExtensionsHandler::GetNumberOfExtensionsThatNeedReview() {
+ int num_extensions_that_need_review = 0;
+ if (!base::FeatureList::IsEnabled(extensions::kCWSInfoService)) {
+ return num_extensions_that_need_review;
+ }
+
+ if (cws_info_service_ == nullptr) {
+ cws_info_service_ = extensions::CWSInfoService::Get(profile_);
+ }
+
+ extensions::ExtensionPrefs* extension_prefs =
+ extensions::ExtensionPrefsFactory::GetForBrowserContext(profile_);
+
+ for (const auto& extension_id : extension_prefs->GetExtensions()) {
+ const extensions::Extension* extension =
+ extensions::ExtensionRegistry::Get(profile_)->GetExtensionById(
+ extension_id, extensions::ExtensionRegistry::EVERYTHING);
+ // Check if the extension is installed by a policy.
+ if (!extension ||
+ extensions::Manifest::IsPolicyLocation(extension->location())) {
+ continue;
+ }
+ bool warning_acked = false;
+ extension_prefs->ReadPrefAsBoolean(
+ extension->id(), kPrefAcknowledgeSafetyCheckWarning, &warning_acked);
+ // If the user has previously acknowledged the warning on this
+ // extension and chosen to keep it, we will not show an additional
+ // safety hub warning.
+ if (warning_acked) {
+ continue;
+ }
+ absl::optional<extensions::CWSInfoService::CWSInfo> extension_info =
+ cws_info_service_->GetCWSInfo(*extension);
+ if (extension_info.has_value() && extension_info->is_present) {
+ switch (extension_info->violation_type) {
+ case extensions::CWSInfoService::CWSViolationType::kMalware:
+ case extensions::CWSInfoService::CWSViolationType::kPolicy:
+ num_extensions_that_need_review++;
+ break;
+ case extensions::CWSInfoService::CWSViolationType::kNone:
+ case extensions::CWSInfoService::CWSViolationType::kMinorPolicy:
+ case extensions::CWSInfoService::CWSViolationType::kUnknown:
+ if (extension_info->unpublished_long_ago) {
+ num_extensions_that_need_review++;
+ }
+ break;
+ }
+ }
+ }
+ return num_extensions_that_need_review;
+}
+
+void SafetyCheckExtensionsHandler::OnJavascriptAllowed() {}
+
+void SafetyCheckExtensionsHandler::OnJavascriptDisallowed() {}
+
+void SafetyCheckExtensionsHandler::RegisterMessages() {
+ // Usage of base::Unretained(this) is safe, because web_ui() owns `this` and
+ // won't release ownership until destruction.
+ web_ui()->RegisterMessageCallback(
+ "getNumberOfExtensionsThatNeedReview",
+ base::BindRepeating(&SafetyCheckExtensionsHandler::
+ HandleGetNumberOfExtensionsThatNeedReview,
+ base::Unretained(this)));
+}
+
+} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/safety_check_extensions_handler.h b/chromium/chrome/browser/ui/webui/settings/safety_check_extensions_handler.h
new file mode 100644
index 00000000000..7d05c9b113f
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/safety_check_extensions_handler.h
@@ -0,0 +1,59 @@
+// Copyright 2023 The Chromium Authors
+// 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_SAFETY_CHECK_EXTENSIONS_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_SAFETY_CHECK_EXTENSIONS_HANDLER_H_
+
+#include "base/memory/raw_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+
+class Profile;
+
+namespace extensions {
+class CWSInfoService;
+class SafetyCheckExtensionsHandlerTest;
+} // namespace extensions
+
+namespace settings {
+
+// Settings page UI handler that checks for any extensions that trigger
+// a review by the safety check.
+class SafetyCheckExtensionsHandler : public settings::SettingsPageUIHandler {
+ public:
+ explicit SafetyCheckExtensionsHandler(Profile* profile);
+ ~SafetyCheckExtensionsHandler() override;
+
+ void SetCWSInfoServiceForTest(extensions::CWSInfoService* cws_info_service);
+
+ private:
+ friend class extensions::SafetyCheckExtensionsHandlerTest;
+
+ // Calculate the number of extensions that need to be reviewed by the
+ // user.
+ void HandleGetNumberOfExtensionsThatNeedReview(const base::Value::List& args);
+
+ // Return the number of extensions that should be reviewed by the user.
+ // There are currently three triggers the `SafetyCheckExtensionsHandler`
+ // tracks:
+ // -- Extension Malware Violation
+ // -- Extension Policy Violation
+ // -- Extension Unpublished by the developer
+ int GetNumberOfExtensionsThatNeedReview();
+
+ // SettingsPageUIHandler implementation.
+ void OnJavascriptDisallowed() override;
+ void OnJavascriptAllowed() override;
+
+ // WebUIMessageHandler implementation.
+ void RegisterMessages() override;
+
+ raw_ptr<Profile> profile_ = nullptr;
+ raw_ptr<extensions::CWSInfoService> cws_info_service_ = nullptr;
+ base::WeakPtrFactory<SafetyCheckExtensionsHandler> weak_ptr_factory_{this};
+};
+
+} // namespace settings
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_SAFETY_CHECK_EXTENSIONS_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/safety_check_extensions_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/safety_check_extensions_handler_unittest.cc
new file mode 100644
index 00000000000..665bd203ad6
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/safety_check_extensions_handler_unittest.cc
@@ -0,0 +1,174 @@
+// Copyright 2023 The Chromium Authors
+// 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/safety_check_extensions_handler.h"
+
+#include <string>
+
+#include "chrome/browser/extensions/cws_info_service.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/test/base/testing_profile.h"
+#include "components/crx_file/id_util.h"
+#include "content/public/test/browser_task_environment.h"
+#include "extensions/browser/extension_prefs.h"
+#include "extensions/browser/extension_prefs_factory.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/common/extension_builder.h"
+#include "extensions/common/extension_id.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace extensions {
+
+using mojom::ManifestLocation;
+
+namespace {
+
+const char kAllHostsPermission[] = "*://*/*";
+
+// These `cws_info` variables are used to test the various
+// `safety_check_extensions_handler` states.
+// Will trigger the extension handler due to the malware violation.
+static extensions::CWSInfoService::CWSInfo cws_info_malware{
+ true,
+ false,
+ base::Time::Now(),
+ extensions::CWSInfoService::CWSViolationType::kMalware,
+ false,
+ false};
+// Will trigger the extension handler due to the policy violation.
+static extensions::CWSInfoService::CWSInfo cws_info_policy{
+ true,
+ false,
+ base::Time::Now(),
+ extensions::CWSInfoService::CWSViolationType::kPolicy,
+ false,
+ false};
+// Will trigger the extension handler due to being unpublished.
+static extensions::CWSInfoService::CWSInfo cws_info_unpublished{
+ true,
+ false,
+ base::Time::Now(),
+ extensions::CWSInfoService::CWSViolationType::kNone,
+ true,
+ false};
+// Will trigger the extension handler due to multiple triggers.
+static extensions::CWSInfoService::CWSInfo cws_info_multi{
+ true,
+ false,
+ base::Time::Now(),
+ extensions::CWSInfoService::CWSViolationType::kMalware,
+ true,
+ false};
+// Will not trigger the extension handler.
+static extensions::CWSInfoService::CWSInfo cws_info_no_trigger{
+ true,
+ false,
+ base::Time::Now(),
+ extensions::CWSInfoService::CWSViolationType::kNone,
+ false,
+ false};
+// Will not trigger the extension handler.
+static extensions::CWSInfoService::CWSInfo cws_info_no_data{
+ false,
+ false,
+ base::Time::Now(),
+ extensions::CWSInfoService::CWSViolationType::kMalware,
+ false,
+ false};
+
+class MockCWSInfoService : public extensions::CWSInfoService {
+ public:
+ MOCK_METHOD(absl::optional<bool>,
+ IsLiveInCWS,
+ (const extensions::Extension&),
+ (const, override));
+ MOCK_METHOD(absl::optional<CWSInfoServiceInterface::CWSInfo>,
+ GetCWSInfo,
+ (const extensions::Extension&),
+ (const, override));
+ MOCK_METHOD(void, CheckAndMaybeFetchInfo, (), (override));
+ MOCK_METHOD(void,
+ AddObserver,
+ (CWSInfoServiceInterface::Observer*),
+ (override));
+ MOCK_METHOD(void,
+ RemoveObserver,
+ (CWSInfoServiceInterface::Observer*),
+ (override));
+};
+
+} // namespace
+
+class SafetyCheckExtensionsHandlerTest : public testing::Test {
+ public:
+ void SetUp() override;
+
+ int GetNumberOfExtensionsThatNeedReview() {
+ return safety_check_handler_->GetNumberOfExtensionsThatNeedReview();
+ }
+
+ protected:
+ void AddExtension(const std::string& name, mojom::ManifestLocation location) {
+ const std::string kId = crx_file::id_util::GenerateId(name);
+ scoped_refptr<const Extension> extension =
+ ExtensionBuilder()
+ .SetManifest(base::Value::Dict()
+ .Set("name", name)
+ .Set("description", "an extension")
+ .Set("manifest_version", 3)
+ .Set("version", "1.0.0")
+ .Set("permissions", base::Value::List().Append(
+ kAllHostsPermission)))
+ .SetLocation(location)
+ .SetID(kId)
+ .Build();
+ extensions::ExtensionPrefs::Get(profile_.get())
+ ->OnExtensionInstalled(extension.get(),
+ extensions::Extension::State::ENABLED,
+ syncer::StringOrdinal(), "");
+ extensions::ExtensionRegistry::Get(profile_.get())->AddEnabled(extension);
+ }
+
+ content::BrowserTaskEnvironment browser_task_environment_;
+ std::unique_ptr<TestingProfile> profile_;
+ testing::NiceMock<MockCWSInfoService> mock_cws_info_service_;
+ std::unique_ptr<settings::SafetyCheckExtensionsHandler> safety_check_handler_;
+};
+
+void SafetyCheckExtensionsHandlerTest::SetUp() {
+ TestingProfile::Builder builder;
+ profile_ = builder.Build();
+}
+
+TEST_F(SafetyCheckExtensionsHandlerTest,
+ GetNumberOfExtensionsThatNeedReviewTest) {
+ // Create fake extensions for our pref service to load.
+ AddExtension("TestExtension1", ManifestLocation::kInternal);
+ AddExtension("TestExtension2", ManifestLocation::kInternal);
+ AddExtension("TestExtension3", ManifestLocation::kInternal);
+ AddExtension("TestExtension4", ManifestLocation::kInternal);
+ AddExtension("TestExtension5", ManifestLocation::kInternal);
+ AddExtension("TestExtension6", ManifestLocation::kInternal);
+ // Extensions installed by policies will be ignored by the safety
+ // check. So extension 7 will not trigger the handler.
+ AddExtension("TestExtension7", ManifestLocation::kExternalPolicyDownload);
+ safety_check_handler_ =
+ std::make_unique<settings::SafetyCheckExtensionsHandler>(profile_.get());
+ safety_check_handler_->SetCWSInfoServiceForTest(&mock_cws_info_service_);
+ // Ensure that the mock CWSInfo service returns the needed information.
+ EXPECT_CALL(mock_cws_info_service_, GetCWSInfo)
+ .Times(6)
+ .WillOnce(testing::Return(cws_info_malware))
+ .WillOnce(testing::Return(cws_info_policy))
+ .WillOnce(testing::Return(cws_info_unpublished))
+ .WillOnce(testing::Return(cws_info_multi))
+ .WillOnce(testing::Return(cws_info_no_data))
+ .WillOnce(testing::Return(cws_info_no_trigger));
+ // There should be 4 triggering extensions based on the various cws_info
+ // variables.
+ EXPECT_EQ(4, GetNumberOfExtensionsThatNeedReview());
+}
+
+} // namespace extensions
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 a98a668cebc..d64f64f4fdd 100644
--- a/chromium/chrome/browser/ui/webui/settings/safety_check_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/safety_check_handler.cc
@@ -24,6 +24,7 @@
#include "chrome/browser/ui/webui/version/version_ui.h"
#include "chrome/common/channel_info.h"
#include "chrome/common/chrome_features.h"
+#include "chrome/common/extensions/api/passwords_private.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/chromium_strings.h"
@@ -78,6 +79,9 @@ SafetyCheckHandler::UpdateStatus ConvertToUpdateStatus(
return SafetyCheckHandler::UpdateStatus::kRelaunch;
case VersionUpdater::DISABLED_BY_ADMIN:
return SafetyCheckHandler::UpdateStatus::kDisabledByAdmin;
+ case VersionUpdater::UPDATE_TO_ROLLBACK_VERSION_DISALLOWED:
+ return SafetyCheckHandler::UpdateStatus::
+ kUpdateToRollbackVersionDisallowed;
// The disabled state can only be returned on non Chrome-branded browsers.
case VersionUpdater::DISABLED:
return SafetyCheckHandler::UpdateStatus::kUnknown;
@@ -114,6 +118,16 @@ bool IsCredentialWeak(
});
}
+bool IsCredentialReused(
+ const extensions::api::passwords_private::PasswordUiEntry& entry) {
+ DCHECK(entry.compromised_info);
+ return base::ranges::any_of(
+ entry.compromised_info->compromise_types, [](auto type) {
+ return type ==
+ extensions::api::passwords_private::COMPROMISE_TYPE_REUSED;
+ });
+}
+
} // namespace
base::Time TimestampDelegate::GetSystemTime() {
@@ -147,8 +161,8 @@ void SafetyCheckHandler::SendSafetyCheckStartedWebUiUpdates() {
GetStringForUpdates(update_status_));
FireBasicSafetyCheckWebUiListener(
kPasswordsEvent, static_cast<int>(passwords_status_),
- GetStringForPasswords(passwords_status_, Compromised(0), Weak(0), Done(0),
- Total(0)));
+ GetStringForPasswords(passwords_status_, Compromised(0), Weak(0),
+ Reused(0), Done(0), Total(0)));
FireBasicSafetyCheckWebUiListener(
kSafeBrowsingEvent, static_cast<int>(safe_browsing_status_),
GetStringForSafeBrowsing(safe_browsing_status_));
@@ -350,15 +364,16 @@ void SafetyCheckHandler::OnUpdateCheckResult(UpdateStatus status) {
void SafetyCheckHandler::OnPasswordsCheckResult(PasswordsStatus status,
Compromised compromised,
Weak weak,
+ Reused reused,
Done done,
Total total) {
base::Value::Dict event;
event.Set(kNewState, static_cast<int>(status));
- event.Set(kDisplayString,
- GetStringForPasswords(status, compromised, weak, done, total));
+ event.Set(kDisplayString, GetStringForPasswords(status, compromised, weak,
+ reused, done, total));
FireWebUIListener(kPasswordsEvent, event);
if (status != PasswordsStatus::kChecking) {
- base::UmaHistogramEnumeration("Settings.SafetyCheck.PasswordsResult",
+ base::UmaHistogramEnumeration("Settings.SafetyCheck.PasswordsResult2",
status);
}
passwords_status_ = status;
@@ -416,6 +431,10 @@ std::u16string SafetyCheckHandler::GetStringForUpdates(UpdateStatus status) {
return l10n_util::GetStringFUTF16(
IDS_SETTINGS_SAFETY_CHECK_UPDATES_DISABLED_BY_ADMIN,
base::ASCIIToUTF16(chrome::kWhoIsMyAdministratorHelpURL));
+ // This status is only used in ChromeOS.
+ case UpdateStatus::kUpdateToRollbackVersionDisallowed:
+ return l10n_util::GetStringUTF16(
+ IDS_SETTINGS_UPDATE_TO_ROLLBACK_VERSION_DISALLOWED);
case UpdateStatus::kFailedOffline:
return l10n_util::GetStringUTF16(
IDS_SETTINGS_SAFETY_CHECK_UPDATES_FAILED_OFFLINE);
@@ -464,6 +483,7 @@ std::u16string SafetyCheckHandler::GetStringForPasswords(
PasswordsStatus status,
Compromised compromised,
Weak weak,
+ Reused reused,
Done done,
Total total) {
switch (status) {
@@ -480,25 +500,37 @@ std::u16string SafetyCheckHandler::GetStringForPasswords(
return l10n_util::GetPluralStringFUTF16(
IDS_SETTINGS_COMPROMISED_PASSWORDS_COUNT, 0);
case PasswordsStatus::kCompromisedExist:
- if (weak.value() == 0) {
- // Only compromised passwords, no weak passwords.
- return l10n_util::GetPluralStringFUTF16(
+ case PasswordsStatus::kWeakPasswordsExist:
+ case PasswordsStatus::kReusedPasswordsExist:
+ case PasswordsStatus::kMutedCompromisedExist: {
+ // Keep the order since compromised issues should come first, then weak,
+ // then reused.
+ std::vector<std::u16string> issues;
+ if (compromised.value()) {
+ issues.push_back(l10n_util::GetPluralStringFUTF16(
IDS_SETTINGS_COMPROMISED_PASSWORDS_COUNT_SHORT,
- compromised.value());
- } else {
- // Both compromised and weak passwords.
- return l10n_util::GetStringFUTF16(
- IDS_CONCAT_TWO_STRINGS_WITH_COMMA,
- l10n_util::GetPluralStringFUTF16(
- IDS_SETTINGS_COMPROMISED_PASSWORDS_COUNT_SHORT,
- compromised.value()),
- l10n_util::GetPluralStringFUTF16(
- IDS_SETTINGS_WEAK_PASSWORDS_COUNT_SHORT, weak.value()));
+ compromised.value()));
}
- case PasswordsStatus::kWeakPasswordsExist:
- // Only weak passwords.
- return l10n_util::GetPluralStringFUTF16(
- IDS_SETTINGS_WEAK_PASSWORDS_COUNT_SHORT, weak.value());
+ if (weak.value()) {
+ issues.push_back(l10n_util::GetPluralStringFUTF16(
+ IDS_SETTINGS_WEAK_PASSWORDS_COUNT_SHORT, weak.value()));
+ }
+ if (reused.value()) {
+ issues.push_back(l10n_util::GetPluralStringFUTF16(
+ IDS_SETTINGS_REUSED_PASSWORDS_COUNT_SHORT, reused.value()));
+ }
+
+ CHECK(!issues.empty());
+ if (issues.size() == 1) {
+ return issues[0];
+ }
+ if (issues.size() == 2) {
+ return l10n_util::GetStringFUTF16(IDS_CONCAT_TWO_STRINGS_WITH_COMMA,
+ issues[0], issues[1]);
+ }
+ return l10n_util::GetStringFUTF16(IDS_CONCAT_THREE_STRINGS_WITH_COMMA,
+ issues[0], issues[1], issues[2]);
+ }
case PasswordsStatus::kOffline:
return l10n_util::GetStringUTF16(
IDS_SETTINGS_CHECK_PASSWORDS_ERROR_OFFLINE);
@@ -634,7 +666,7 @@ void SafetyCheckHandler::DetermineIfNoPasswordsOrSafe(
passwords) {
OnPasswordsCheckResult(passwords.empty() ? PasswordsStatus::kNoPasswords
: PasswordsStatus::kSafe,
- Compromised(0), Weak(0), Done(0), Total(0));
+ Compromised(0), Weak(0), Reused(0), Done(0), Total(0));
}
void SafetyCheckHandler::UpdatePasswordsResultOnCheckIdle() {
@@ -643,8 +675,25 @@ void SafetyCheckHandler::UpdatePasswordsResultOnCheckIdle() {
insecure_credentials, &IsUnmutedCompromisedCredential);
size_t num_weak =
base::ranges::count_if(insecure_credentials, &IsCredentialWeak);
+ size_t num_reused =
+ base::ranges::count_if(insecure_credentials, &IsCredentialReused);
- if (num_compromised == 0 && num_weak == 0) {
+ if (num_compromised > 0) {
+ // At least one compromised password. Treat as compromises.
+ OnPasswordsCheckResult(PasswordsStatus::kCompromisedExist,
+ Compromised(num_compromised), Weak(num_weak),
+ Reused(num_reused), Done(0), Total(0));
+ } else if (num_weak > 0) {
+ // No compromised but weak passwords. Treat as weak passwords only.
+ OnPasswordsCheckResult(PasswordsStatus::kWeakPasswordsExist,
+ Compromised(num_compromised), Weak(num_weak),
+ Reused(num_reused), Done(0), Total(0));
+ } else if (num_reused > 0) {
+ // No weak or compromised but reused passwords.
+ OnPasswordsCheckResult(PasswordsStatus::kReusedPasswordsExist,
+ Compromised(num_compromised), Weak(num_weak),
+ Reused(num_reused), Done(0), Total(0));
+ } else {
// If there are no |OnCredentialDone| callbacks with is_leaked = true, no
// need to wait for InsecureCredentialsManager callbacks any longer, since
// there should be none for the current password check.
@@ -654,16 +703,6 @@ void SafetyCheckHandler::UpdatePasswordsResultOnCheckIdle() {
passwords_delegate_->GetSavedPasswordsList(
base::BindOnce(&SafetyCheckHandler::DetermineIfNoPasswordsOrSafe,
base::Unretained(this)));
- } else if (num_compromised > 0) {
- // At least one compromised password. Treat as compromises.
- OnPasswordsCheckResult(PasswordsStatus::kCompromisedExist,
- Compromised(num_compromised), Weak(num_weak),
- Done(0), Total(0));
- } else {
- // No compromised but weak passwords. Treat as weak passwords only.
- OnPasswordsCheckResult(PasswordsStatus::kWeakPasswordsExist,
- Compromised(num_compromised), Weak(num_weak),
- Done(0), Total(0));
}
}
@@ -695,29 +734,30 @@ void SafetyCheckHandler::OnStateChanged(
}
case BulkLeakCheckService::State::kRunning:
OnPasswordsCheckResult(PasswordsStatus::kChecking, Compromised(0),
- Weak(0), Done(0), Total(0));
+ Weak(0), Reused(0), Done(0), Total(0));
// Non-terminal state, so nothing else needs to be done.
return;
case BulkLeakCheckService::State::kSignedOut:
OnPasswordsCheckResult(PasswordsStatus::kSignedOut, Compromised(0),
- Weak(0), Done(0), Total(0));
+ Weak(0), Reused(0), Done(0), Total(0));
break;
case BulkLeakCheckService::State::kNetworkError:
OnPasswordsCheckResult(PasswordsStatus::kOffline, Compromised(0), Weak(0),
- Done(0), Total(0));
+ Reused(0), Done(0), Total(0));
break;
case BulkLeakCheckService::State::kQuotaLimit:
OnPasswordsCheckResult(PasswordsStatus::kQuotaLimit, Compromised(0),
- Weak(0), Done(0), Total(0));
+ Weak(0), Reused(0), Done(0), Total(0));
break;
case BulkLeakCheckService::State::kTokenRequestFailure:
OnPasswordsCheckResult(PasswordsStatus::kFeatureUnavailable,
- Compromised(0), Weak(0), Done(0), Total(0));
+ Compromised(0), Weak(0), Reused(0), Done(0),
+ Total(0));
break;
case BulkLeakCheckService::State::kHashingFailure:
case BulkLeakCheckService::State::kServiceError:
OnPasswordsCheckResult(PasswordsStatus::kError, Compromised(0), Weak(0),
- Done(0), Total(0));
+ Reused(0), Done(0), Total(0));
break;
}
@@ -744,7 +784,7 @@ void SafetyCheckHandler::OnCredentialDone(
Done done = Done(*(status.already_processed));
Total total = Total(*(status.remaining_in_queue) + done.value());
OnPasswordsCheckResult(PasswordsStatus::kChecking, Compromised(0), Weak(0),
- done, total);
+ Reused(0), done, total);
}
}
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 388e6213bb2..cee9b68a3f7 100644
--- a/chromium/chrome/browser/ui/webui/settings/safety_check_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/safety_check_handler.h
@@ -129,6 +129,7 @@ class SafetyCheckHandler
// check methods.
using Compromised = base::StrongAlias<class CompromisedTag, int>;
using Weak = base::StrongAlias<class WeakTag, int>;
+ using Reused = base::StrongAlias<class ReusedTag, int>;
using Done = base::StrongAlias<class DoneTag, int>;
using Total = base::StrongAlias<class TotalTag, int>;
using Blocklisted = base::StrongAlias<class BlocklistedTag, int>;
@@ -160,6 +161,7 @@ class SafetyCheckHandler
void OnPasswordsCheckResult(PasswordsStatus status,
Compromised compromised,
Weak weak,
+ Reused reused,
Done done,
Total total);
void OnExtensionsCheckResult(ExtensionsStatus status,
@@ -175,6 +177,7 @@ class SafetyCheckHandler
std::u16string GetStringForPasswords(PasswordsStatus status,
Compromised compromised,
Weak weak,
+ Reused reused,
Done done,
Total total);
std::u16string GetStringForExtensions(ExtensionsStatus status,
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 fec4bb2ae6b..f38ecf0cc1b 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
@@ -168,6 +168,10 @@ class TestPasswordsDelegate : public extensions::TestPasswordsPrivateDelegate {
weak_password_count_ = weak_password_count;
}
+ void SetNumReusedCredentials(int reused_password_count) {
+ reused_password_count_ = reused_password_count;
+ }
+
void SetPasswordCheckState(
extensions::api::passwords_private::PasswordCheckState state) {
state_ = state;
@@ -218,6 +222,11 @@ class TestPasswordsDelegate : public extensions::TestPasswordsPrivateDelegate {
insecure.size(),
extensions::api::passwords_private::COMPROMISE_TYPE_WEAK));
}
+ for (int i = 0; i < reused_password_count_; ++i) {
+ insecure.push_back(CreateInsecureCredential(
+ insecure.size(),
+ extensions::api::passwords_private::COMPROMISE_TYPE_REUSED));
+ }
return insecure;
}
@@ -245,6 +254,7 @@ class TestPasswordsDelegate : public extensions::TestPasswordsPrivateDelegate {
int muted_leaked_password_count_ = 0;
int phished_password_count_ = 0;
int weak_password_count_ = 0;
+ int reused_password_count_ = 0;
int done_ = 0;
int total_ = 0;
int test_credential_counter_ = 0;
@@ -324,8 +334,9 @@ class SafetyCheckHandlerTest : public testing::Test {
content::BrowserTaskEnvironment browser_task_environment_;
std::unique_ptr<TestingProfile> profile_;
std::unique_ptr<content::WebContents> web_contents_;
- raw_ptr<safety_check::TestUpdateCheckHelper> update_helper_ = nullptr;
- raw_ptr<TestVersionUpdater> version_updater_ = nullptr;
+ raw_ptr<safety_check::TestUpdateCheckHelper, DanglingUntriaged>
+ update_helper_ = nullptr;
+ raw_ptr<TestVersionUpdater, DanglingUntriaged> version_updater_ = nullptr;
std::unique_ptr<password_manager::BulkLeakCheckService> test_leak_service_;
scoped_refptr<TestPasswordsDelegate> test_passwords_delegate_;
raw_ptr<extensions::ExtensionPrefs> test_extension_prefs_ = nullptr;
@@ -584,6 +595,23 @@ TEST_F(SafetyCheckHandlerTest, CheckUpdates_DestroyedOnJavascriptDisallowed) {
EXPECT_TRUE(TestDestructionVersionUpdater::GetDestructorInvoked());
}
+TEST_F(SafetyCheckHandlerTest, CheckUpdates_UpdateToRollbackVersionDisallowed) {
+ version_updater_->SetReturnedStatus(
+ VersionUpdater::Status::UPDATE_TO_ROLLBACK_VERSION_DISALLOWED);
+ safety_check_->PerformSafetyCheck();
+ const base::Value::Dict* event = GetSafetyCheckStatusChangedWithDataIfExists(
+ kUpdates, static_cast<int>(SafetyCheckHandler::UpdateStatus::
+ kUpdateToRollbackVersionDisallowed));
+ ASSERT_TRUE(event);
+ VerifyDisplayString(
+ event,
+ "You reverted to a previous version of ChromeOS. "
+ "To get updates, wait until the next version is available.");
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.UpdatesResult",
+ SafetyCheckHandler::UpdateStatus::kUpdateToRollbackVersionDisallowed, 1);
+}
+
TEST_F(SafetyCheckHandlerTest, CheckSafeBrowsing_EnabledStandard) {
TestingProfile::FromWebUI(&test_web_ui_)
->AsTestingProfile()
@@ -730,7 +758,8 @@ TEST_F(SafetyCheckHandlerTest, CheckPasswords_ObserverRemovedAfterError) {
static_cast<int>(SafetyCheckHandler::PasswordsStatus::kChecking));
ASSERT_TRUE(event);
VerifyDisplayString(event, u"");
- histogram_tester_.ExpectTotalCount("Settings.SafetyCheck.PasswordsResult", 0);
+ histogram_tester_.ExpectTotalCount("Settings.SafetyCheck.PasswordsResult2",
+ 0);
// Second, an "offline" state.
test_leak_service_->set_state_and_notify(
password_manager::BulkLeakCheckService::State::kNetworkError);
@@ -742,7 +771,7 @@ TEST_F(SafetyCheckHandlerTest, CheckPasswords_ObserverRemovedAfterError) {
"Browser can't check your passwords. Try checking your "
"internet connection.");
histogram_tester_.ExpectBucketCount(
- "Settings.SafetyCheck.PasswordsResult",
+ "Settings.SafetyCheck.PasswordsResult2",
SafetyCheckHandler::PasswordsStatus::kOffline, 1);
// Another error, but since the previous state is terminal, the handler
// should no longer be observing the BulkLeakCheckService state.
@@ -753,7 +782,7 @@ TEST_F(SafetyCheckHandlerTest, CheckPasswords_ObserverRemovedAfterError) {
static_cast<int>(SafetyCheckHandler::PasswordsStatus::kOffline));
ASSERT_TRUE(event3);
histogram_tester_.ExpectBucketCount(
- "Settings.SafetyCheck.PasswordsResult",
+ "Settings.SafetyCheck.PasswordsResult2",
SafetyCheckHandler::PasswordsStatus::kOffline, 1);
}
@@ -792,7 +821,7 @@ TEST_F(SafetyCheckHandlerTest, CheckPasswords_InterruptedAndRefreshed) {
"Browser can't check your passwords because you're not "
"signed in");
histogram_tester_.ExpectBucketCount(
- "Settings.SafetyCheck.PasswordsResult",
+ "Settings.SafetyCheck.PasswordsResult2",
SafetyCheckHandler::PasswordsStatus::kSignedOut, 1);
}
@@ -817,7 +846,7 @@ TEST_F(SafetyCheckHandlerTest, CheckPasswords_StartedTwice) {
"Browser can't check your passwords. Try checking your "
"internet connection.");
histogram_tester_.ExpectBucketCount(
- "Settings.SafetyCheck.PasswordsResult",
+ "Settings.SafetyCheck.PasswordsResult2",
SafetyCheckHandler::PasswordsStatus::kOffline, 1);
}
@@ -855,7 +884,7 @@ TEST_F(SafetyCheckHandlerTest, CheckPasswords_Safe) {
EXPECT_TRUE(event);
VerifyDisplayString(event, "No compromised passwords found");
histogram_tester_.ExpectBucketCount(
- "Settings.SafetyCheck.PasswordsResult",
+ "Settings.SafetyCheck.PasswordsResult2",
SafetyCheckHandler::PasswordsStatus::kSafe, 1);
}
@@ -955,7 +984,7 @@ TEST_F(SafetyCheckHandlerTest, CheckPasswords_OnlyLeakedExist) {
VerifyDisplayString(event2,
base::NumberToString(kLeaked) + " compromised passwords");
histogram_tester_.ExpectBucketCount(
- "Settings.SafetyCheck.PasswordsResult",
+ "Settings.SafetyCheck.PasswordsResult2",
SafetyCheckHandler::PasswordsStatus::kCompromisedExist, 1);
}
@@ -979,7 +1008,7 @@ TEST_F(SafetyCheckHandlerTest, CheckPasswords_OnlyPhishedExist) {
VerifyDisplayString(
event2, base::NumberToString(kPhished) + " compromised passwords");
histogram_tester_.ExpectBucketCount(
- "Settings.SafetyCheck.PasswordsResult",
+ "Settings.SafetyCheck.PasswordsResult2",
SafetyCheckHandler::PasswordsStatus::kCompromisedExist, 1);
}
@@ -1004,7 +1033,7 @@ TEST_F(SafetyCheckHandlerTest, CheckPasswords_LeakedAndPhishedExist) {
VerifyDisplayString(event2, base::NumberToString(kLeaked + kPhished) +
" compromised passwords");
histogram_tester_.ExpectBucketCount(
- "Settings.SafetyCheck.PasswordsResult",
+ "Settings.SafetyCheck.PasswordsResult2",
SafetyCheckHandler::PasswordsStatus::kCompromisedExist, 1);
}
@@ -1031,10 +1060,96 @@ TEST_F(SafetyCheckHandlerTest, CheckPasswords_CompromisedAndWeakExist) {
event2, base::NumberToString(kCompromised) + " compromised passwords, " +
base::NumberToString(kWeak) + " weak passwords");
histogram_tester_.ExpectBucketCount(
- "Settings.SafetyCheck.PasswordsResult",
+ "Settings.SafetyCheck.PasswordsResult2",
+ SafetyCheckHandler::PasswordsStatus::kCompromisedExist, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest, CheckPasswords_CompromisedAndReusedExist) {
+ constexpr int kCompromised = 7;
+ constexpr int kReused = 13;
+ test_passwords_delegate_->SetNumLeakedCredentials(kCompromised);
+ test_passwords_delegate_->SetNumReusedCredentials(kReused);
+ safety_check_->PerformSafetyCheck();
+ // First, a "running" change of state.
+ test_leak_service_->set_state_and_notify(
+ password_manager::BulkLeakCheckService::State::kRunning);
+ EXPECT_TRUE(GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(SafetyCheckHandler::PasswordsStatus::kChecking)));
+ // Compromised passwords found state.
+ test_leak_service_->set_state_and_notify(
+ password_manager::BulkLeakCheckService::State::kIdle);
+ const base::Value::Dict* event2 = GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(SafetyCheckHandler::PasswordsStatus::kCompromisedExist));
+ ASSERT_TRUE(event2);
+ VerifyDisplayString(
+ event2, base::NumberToString(kCompromised) + " compromised passwords, " +
+ base::NumberToString(kReused) + " reused passwords");
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.PasswordsResult2",
+ SafetyCheckHandler::PasswordsStatus::kCompromisedExist, 1);
+}
+
+TEST_F(SafetyCheckHandlerTest,
+ CheckPasswords_CompromisedAndWeakAndReusedExist) {
+ constexpr int kCompromised = 7;
+ constexpr int kWeak = 13;
+ constexpr int kReused = 6;
+ test_passwords_delegate_->SetNumLeakedCredentials(kCompromised);
+ test_passwords_delegate_->SetNumWeakCredentials(kWeak);
+ test_passwords_delegate_->SetNumReusedCredentials(kReused);
+ safety_check_->PerformSafetyCheck();
+ // First, a "running" change of state.
+ test_leak_service_->set_state_and_notify(
+ password_manager::BulkLeakCheckService::State::kRunning);
+ EXPECT_TRUE(GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(SafetyCheckHandler::PasswordsStatus::kChecking)));
+ // Compromised passwords found state.
+ test_leak_service_->set_state_and_notify(
+ password_manager::BulkLeakCheckService::State::kIdle);
+ const base::Value::Dict* event2 = GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(SafetyCheckHandler::PasswordsStatus::kCompromisedExist));
+ ASSERT_TRUE(event2);
+ VerifyDisplayString(
+ event2, base::NumberToString(kCompromised) + " compromised passwords, " +
+ base::NumberToString(kWeak) + " weak passwords, " +
+ base::NumberToString(kReused) + " reused passwords");
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.PasswordsResult2",
SafetyCheckHandler::PasswordsStatus::kCompromisedExist, 1);
}
+TEST_F(SafetyCheckHandlerTest, CheckPasswords_WeakAndReusedExist) {
+ constexpr int kWeak = 13;
+ constexpr int kReused = 6;
+ test_passwords_delegate_->SetNumWeakCredentials(kWeak);
+ test_passwords_delegate_->SetNumReusedCredentials(kReused);
+ safety_check_->PerformSafetyCheck();
+ // First, a "running" change of state.
+ test_leak_service_->set_state_and_notify(
+ password_manager::BulkLeakCheckService::State::kRunning);
+ EXPECT_TRUE(GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(SafetyCheckHandler::PasswordsStatus::kChecking)));
+ // Compromised passwords found state.
+ test_leak_service_->set_state_and_notify(
+ password_manager::BulkLeakCheckService::State::kIdle);
+ const base::Value::Dict* event2 = GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(
+ SafetyCheckHandler::PasswordsStatus::kWeakPasswordsExist));
+ ASSERT_TRUE(event2);
+ VerifyDisplayString(event2,
+ base::NumberToString(kWeak) + " weak passwords, " +
+ base::NumberToString(kReused) + " reused passwords");
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.PasswordsResult2",
+ SafetyCheckHandler::PasswordsStatus::kWeakPasswordsExist, 1);
+}
+
TEST_F(SafetyCheckHandlerTest, CheckPasswords_OnlyWeakExist) {
constexpr int kWeak = 13;
test_passwords_delegate_->SetNumWeakCredentials(kWeak);
@@ -1055,10 +1170,35 @@ TEST_F(SafetyCheckHandlerTest, CheckPasswords_OnlyWeakExist) {
ASSERT_TRUE(event2);
VerifyDisplayString(event2, base::NumberToString(kWeak) + " weak passwords");
histogram_tester_.ExpectBucketCount(
- "Settings.SafetyCheck.PasswordsResult",
+ "Settings.SafetyCheck.PasswordsResult2",
SafetyCheckHandler::PasswordsStatus::kWeakPasswordsExist, 1);
}
+TEST_F(SafetyCheckHandlerTest, CheckPasswords_OnlyReusedExist) {
+ constexpr int kReused = 13;
+ test_passwords_delegate_->SetNumReusedCredentials(kReused);
+ safety_check_->PerformSafetyCheck();
+ // First, a "running" change of state.
+ test_leak_service_->set_state_and_notify(
+ password_manager::BulkLeakCheckService::State::kRunning);
+ EXPECT_TRUE(GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(SafetyCheckHandler::PasswordsStatus::kChecking)));
+ // Compromised passwords found state.
+ test_leak_service_->set_state_and_notify(
+ password_manager::BulkLeakCheckService::State::kIdle);
+ const base::Value::Dict* event = GetSafetyCheckStatusChangedWithDataIfExists(
+ kPasswords,
+ static_cast<int>(
+ SafetyCheckHandler::PasswordsStatus::kReusedPasswordsExist));
+ ASSERT_TRUE(event);
+ VerifyDisplayString(event,
+ base::NumberToString(kReused) + " reused passwords");
+ histogram_tester_.ExpectBucketCount(
+ "Settings.SafetyCheck.PasswordsResult2",
+ SafetyCheckHandler::PasswordsStatus::kReusedPasswordsExist, 1);
+}
+
TEST_F(SafetyCheckHandlerTest, CheckPasswords_Error) {
safety_check_->PerformSafetyCheck();
EXPECT_TRUE(test_passwords_delegate_->StartPasswordCheckTriggered());
@@ -1074,7 +1214,7 @@ TEST_F(SafetyCheckHandlerTest, CheckPasswords_Error) {
"Browser can't check your passwords. Try again "
"later.");
histogram_tester_.ExpectBucketCount(
- "Settings.SafetyCheck.PasswordsResult",
+ "Settings.SafetyCheck.PasswordsResult2",
SafetyCheckHandler::PasswordsStatus::kError, 1);
}
@@ -1099,7 +1239,7 @@ TEST_F(SafetyCheckHandlerTest, CheckPasswords_MutedCompromisedExist) {
VerifyDisplayString(event2, base::NumberToString(kCompromised - kMuted) +
" compromised passwords");
histogram_tester_.ExpectBucketCount(
- "Settings.SafetyCheck.PasswordsResult",
+ "Settings.SafetyCheck.PasswordsResult2",
SafetyCheckHandler::PasswordsStatus::kCompromisedExist, 1);
}
@@ -1120,7 +1260,7 @@ TEST_F(SafetyCheckHandlerTest, CheckPasswords_AllMutedCompromisedCredentials) {
kPasswords, static_cast<int>(SafetyCheckHandler::PasswordsStatus::kSafe));
ASSERT_TRUE(event);
histogram_tester_.ExpectBucketCount(
- "Settings.SafetyCheck.PasswordsResult",
+ "Settings.SafetyCheck.PasswordsResult2",
SafetyCheckHandler::PasswordsStatus::kSafe, 1);
}
@@ -1139,7 +1279,7 @@ TEST_F(SafetyCheckHandlerTest, CheckPasswords_Error_FutureEventsIgnored) {
"Browser can't check your passwords. Try again "
"later.");
histogram_tester_.ExpectBucketCount(
- "Settings.SafetyCheck.PasswordsResult",
+ "Settings.SafetyCheck.PasswordsResult2",
SafetyCheckHandler::PasswordsStatus::kError, 1);
// At some point later, the service discovers compromised passwords and goes
// idle.
@@ -1176,7 +1316,7 @@ TEST_F(SafetyCheckHandlerTest, CheckPasswords_FeatureUnavailable) {
ASSERT_TRUE(event);
VerifyDisplayString(event, "Password check is not available in Chromium");
histogram_tester_.ExpectBucketCount(
- "Settings.SafetyCheck.PasswordsResult",
+ "Settings.SafetyCheck.PasswordsResult2",
SafetyCheckHandler::PasswordsStatus::kFeatureUnavailable, 1);
}
@@ -1193,7 +1333,7 @@ TEST_F(SafetyCheckHandlerTest, CheckPasswords_RunningOneCompromised) {
ASSERT_TRUE(event);
VerifyDisplayString(event, "1 compromised password");
histogram_tester_.ExpectBucketCount(
- "Settings.SafetyCheck.PasswordsResult",
+ "Settings.SafetyCheck.PasswordsResult2",
SafetyCheckHandler::PasswordsStatus::kCompromisedExist, 1);
}
@@ -1210,7 +1350,7 @@ TEST_F(SafetyCheckHandlerTest, CheckPasswords_NoPasswords) {
"No saved passwords. Chrome can check your passwords "
"when you save them.");
histogram_tester_.ExpectBucketCount(
- "Settings.SafetyCheck.PasswordsResult",
+ "Settings.SafetyCheck.PasswordsResult2",
SafetyCheckHandler::PasswordsStatus::kNoPasswords, 1);
}
diff --git a/chromium/chrome/browser/ui/webui/settings/safety_hub_handler.cc b/chromium/chrome/browser/ui/webui/settings/safety_hub_handler.cc
new file mode 100644
index 00000000000..b29fba3d6b1
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/safety_hub_handler.cc
@@ -0,0 +1,424 @@
+// Copyright 2022 The Chromium Authors
+// 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/safety_hub_handler.h"
+#include <memory>
+
+#include "base/check.h"
+#include "base/json/values_util.h"
+#include "base/metrics/histogram_functions.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/threading/thread_checker.h"
+#include "base/time/default_clock.h"
+#include "base/time/time.h"
+#include "base/values.h"
+#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
+#include "chrome/browser/permissions/notification_permission_review_service_factory.h"
+#include "chrome/browser/permissions/unused_site_permissions_service_factory.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/webui/settings/site_settings_helper.h"
+#include "chrome/common/chrome_features.h"
+#include "chrome/grit/generated_resources.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/features.h"
+#include "components/permissions/constants.h"
+#include "components/permissions/unused_site_permissions_service.h"
+#include "components/site_engagement/content/site_engagement_service.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "url/gurl.h"
+
+namespace {
+// Key of the expiration time in the |UnusedSitePermissions| object. Indicates
+// the time after which the associated origin and permissions are no longer
+// shown in the UI.
+constexpr char kExpirationKey[] = "expiration";
+// Key of the lifetime in the |UnusedSitePermissions| object.
+constexpr char kLifetimeKey[] = "lifetime";
+
+// Get values from |UnusedSitePermission| object in
+// safety_hub_browser_proxy.ts.
+std::tuple<url::Origin,
+ std::set<ContentSettingsType>,
+ content_settings::ContentSettingConstraints>
+GetUnusedSitePermissionsFromDict(
+ const base::Value::Dict& unused_site_permissions) {
+ const std::string* origin_str =
+ unused_site_permissions.FindString(site_settings::kOrigin);
+ CHECK(origin_str);
+ const auto url = GURL(*origin_str);
+ CHECK(url.is_valid());
+ const url::Origin origin = url::Origin::Create(url);
+
+ const base::Value::List* permissions =
+ unused_site_permissions.FindList(site_settings::kPermissions);
+ CHECK(permissions);
+ std::set<ContentSettingsType> permission_types;
+ for (const auto& permission : *permissions) {
+ CHECK(permission.is_string());
+ const std::string& type_string = permission.GetString();
+ ContentSettingsType type =
+ site_settings::ContentSettingsTypeFromGroupName(type_string);
+ CHECK(type != ContentSettingsType::DEFAULT)
+ << type_string << " is not expected to have a UI representation.";
+ permission_types.insert(type);
+ }
+
+ const base::Value* js_expiration =
+ unused_site_permissions.Find(kExpirationKey);
+ CHECK(js_expiration);
+ base::Time expiration = base::ValueToTime(js_expiration).value();
+
+ const base::Value* js_lifetime = unused_site_permissions.Find(kLifetimeKey);
+ // TODO(https://crbug.com/1455435): The use of ComputeLifetime here should be
+ // temporary. Once all persisted RuleMetaData instances include lifetimes, we
+ // can remove this, and just use the stored lifetime directly. We can do this
+ // after all lifetime-less settings have expired. Realistically this will take
+ // only one or two milestones, so this can safely be removed in M118 or M119.
+ base::TimeDelta lifetime = content_settings::RuleMetaData::ComputeLifetime(
+ /*lifetime=*/js_lifetime ? base::ValueToTimeDelta(js_lifetime).value()
+ : base::TimeDelta(),
+ /*expiration=*/expiration);
+
+ content_settings::ContentSettingConstraints constraints =
+ content_settings::ContentSettingConstraints(expiration - lifetime);
+ constraints.set_lifetime(lifetime);
+
+ return std::make_tuple(origin, permission_types, constraints);
+}
+} // namespace
+
+SafetyHubHandler::SafetyHubHandler(Profile* profile)
+ : profile_(profile), clock_(base::DefaultClock::GetInstance()) {}
+SafetyHubHandler::~SafetyHubHandler() = default;
+
+// static
+std::unique_ptr<SafetyHubHandler> SafetyHubHandler::GetForProfile(
+ Profile* profile) {
+ return std::make_unique<SafetyHubHandler>(profile);
+}
+
+void SafetyHubHandler::HandleGetRevokedUnusedSitePermissionsList(
+ const base::Value::List& args) {
+ AllowJavascript();
+
+ CHECK_EQ(1U, args.size());
+ const base::Value& callback_id = args[0];
+
+ base::Value::List result = PopulateUnusedSitePermissionsData();
+
+ ResolveJavascriptCallback(callback_id, base::Value(std::move(result)));
+}
+
+void SafetyHubHandler::HandleAllowPermissionsAgainForUnusedSite(
+ const base::Value::List& args) {
+ CHECK_EQ(1U, args.size());
+ CHECK(args[0].is_string());
+ const std::string& origin_str = args[0].GetString();
+
+ permissions::UnusedSitePermissionsService* service =
+ UnusedSitePermissionsServiceFactory::GetForProfile(profile_);
+
+ url::Origin origin = url::Origin::Create(GURL(origin_str));
+
+ service->RegrantPermissionsForOrigin(origin);
+ SendUnusedSitePermissionsReviewList();
+}
+
+void SafetyHubHandler::HandleUndoAllowPermissionsAgainForUnusedSite(
+ const base::Value::List& args) {
+ CHECK_EQ(1U, args.size());
+ CHECK(args[0].is_dict());
+
+ auto [origin, permissions, constraints] =
+ GetUnusedSitePermissionsFromDict(args[0].GetDict());
+ permissions::UnusedSitePermissionsService* service =
+ UnusedSitePermissionsServiceFactory::GetForProfile(profile_);
+
+ service->UndoRegrantPermissionsForOrigin(permissions, constraints, origin);
+
+ SendUnusedSitePermissionsReviewList();
+}
+
+void SafetyHubHandler::HandleAcknowledgeRevokedUnusedSitePermissionsList(
+ const base::Value::List& args) {
+ permissions::UnusedSitePermissionsService* service =
+ UnusedSitePermissionsServiceFactory::GetForProfile(profile_);
+ service->ClearRevokedPermissionsList();
+
+ SendUnusedSitePermissionsReviewList();
+}
+
+void SafetyHubHandler::HandleUndoAcknowledgeRevokedUnusedSitePermissionsList(
+ const base::Value::List& args) {
+ CHECK_EQ(1U, args.size());
+ CHECK(args[0].is_list());
+
+ const base::Value::List& unused_site_permissions_list = args[0].GetList();
+ permissions::UnusedSitePermissionsService* service =
+ UnusedSitePermissionsServiceFactory::GetForProfile(profile_);
+
+ for (const auto& unused_site_permissions_js : unused_site_permissions_list) {
+ CHECK(unused_site_permissions_js.is_dict());
+ auto [origin, permissions, constraints] =
+ GetUnusedSitePermissionsFromDict(unused_site_permissions_js.GetDict());
+
+ service->StorePermissionInRevokedPermissionSetting(permissions, constraints,
+ origin);
+ }
+
+ SendUnusedSitePermissionsReviewList();
+}
+
+base::Value::List SafetyHubHandler::PopulateUnusedSitePermissionsData() {
+ base::Value::List result;
+ if (!base::FeatureList::IsEnabled(
+ content_settings::features::kSafetyCheckUnusedSitePermissions)) {
+ return result;
+ }
+
+ HostContentSettingsMap* hcsm =
+ HostContentSettingsMapFactory::GetForProfile(profile_);
+
+ ContentSettingsForOneType settings;
+ hcsm->GetSettingsForOneType(
+ ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS, &settings);
+
+ for (const auto& revoked_permissions : settings) {
+ base::Value::Dict revoked_permission_value;
+ revoked_permission_value.Set(
+ site_settings::kOrigin, revoked_permissions.primary_pattern.ToString());
+ const base::Value& stored_value = revoked_permissions.setting_value;
+ DCHECK(stored_value.is_dict());
+
+ // The revoked permissions list should be reachable by given key.
+ DCHECK(stored_value.GetDict().FindList(permissions::kRevokedKey));
+
+ auto type_list =
+ stored_value.GetDict().FindList(permissions::kRevokedKey)->Clone();
+ base::Value::List permissions_value_list;
+ for (base::Value& type : type_list) {
+ base::StringPiece permission_str =
+ site_settings::ContentSettingsTypeToGroupName(
+ static_cast<ContentSettingsType>(type.GetInt()));
+ if (!permission_str.empty()) {
+ permissions_value_list.Append(permission_str);
+ }
+ }
+
+ // Some permissions have no readable name, although Safety Hub revokes them.
+ // To prevent crashes, if there is no permission to be shown in the UI, the
+ // origin will not be added to the revoked permissions list.
+ // TODO(crbug.com/1459305): Remove this after adding check for
+ // ContentSettingsTypeToGroupName.
+ if (permissions_value_list.empty()) {
+ continue;
+ }
+
+ revoked_permission_value.Set(
+ site_settings::kPermissions,
+ base::Value(std::move(permissions_value_list)));
+
+ revoked_permission_value.Set(
+ kExpirationKey,
+ base::TimeToValue(revoked_permissions.metadata.expiration()));
+
+ revoked_permission_value.Set(
+ kLifetimeKey,
+ base::TimeDeltaToValue(revoked_permissions.metadata.lifetime()));
+
+ result.Append(std::move(revoked_permission_value));
+ }
+ return result;
+}
+
+void SafetyHubHandler::HandleGetNotificationPermissionReviewList(
+ const base::Value::List& args) {
+ AllowJavascript();
+
+ const base::Value& callback_id = args[0];
+
+ base::Value::List result =
+ site_settings::PopulateNotificationPermissionReviewData(profile_);
+
+ ResolveJavascriptCallback(callback_id, base::Value(std::move(result)));
+}
+
+void SafetyHubHandler::HandleIgnoreOriginsForNotificationPermissionReview(
+ const base::Value::List& args) {
+ CHECK_EQ(1U, args.size());
+ const base::Value::List& origins = args[0].GetList();
+
+ auto* service =
+ NotificationPermissionsReviewServiceFactory::GetForProfile(profile_);
+ DCHECK(service);
+
+ for (const auto& origin : origins) {
+ const ContentSettingsPattern primary_pattern =
+ ContentSettingsPattern::FromString(origin.GetString());
+ service->AddPatternToNotificationPermissionReviewBlocklist(
+ primary_pattern, ContentSettingsPattern::Wildcard());
+ }
+
+ SendNotificationPermissionReviewList();
+}
+
+void SafetyHubHandler::HandleResetNotificationPermissionForOrigins(
+ const base::Value::List& args) {
+ CHECK_EQ(1U, args.size());
+
+ const base::Value::List& origins = args[0].GetList();
+
+ HostContentSettingsMap* map =
+ HostContentSettingsMapFactory::GetForProfile(profile_);
+
+ for (const auto& origin : origins) {
+ map->SetContentSettingCustomScope(
+ ContentSettingsPattern::FromString(origin.GetString()),
+ ContentSettingsPattern::Wildcard(), ContentSettingsType::NOTIFICATIONS,
+ CONTENT_SETTING_DEFAULT);
+ }
+
+ SendNotificationPermissionReviewList();
+}
+
+void SafetyHubHandler::HandleBlockNotificationPermissionForOrigins(
+ const base::Value::List& args) {
+ CHECK_EQ(1U, args.size());
+ const base::Value::List& origins = args[0].GetList();
+
+ HostContentSettingsMap* map =
+ HostContentSettingsMapFactory::GetForProfile(profile_);
+ for (const auto& origin : origins) {
+ map->SetContentSettingCustomScope(
+ ContentSettingsPattern::FromString(origin.GetString()),
+ ContentSettingsPattern::Wildcard(), ContentSettingsType::NOTIFICATIONS,
+ CONTENT_SETTING_BLOCK);
+ }
+
+ SendNotificationPermissionReviewList();
+}
+
+void SafetyHubHandler::HandleAllowNotificationPermissionForOrigins(
+ const base::Value::List& args) {
+ CHECK_EQ(1U, args.size());
+ const base::Value::List& origins = args[0].GetList();
+
+ HostContentSettingsMap* map =
+ HostContentSettingsMapFactory::GetForProfile(profile_);
+
+ for (const auto& origin : origins) {
+ map->SetContentSettingCustomScope(
+ ContentSettingsPattern::FromString(origin.GetString()),
+ ContentSettingsPattern::Wildcard(), ContentSettingsType::NOTIFICATIONS,
+ CONTENT_SETTING_ALLOW);
+ }
+
+ SendNotificationPermissionReviewList();
+}
+
+void SafetyHubHandler::HandleUndoIgnoreOriginsForNotificationPermissionReview(
+ const base::Value::List& args) {
+ CHECK_EQ(1U, args.size());
+ const base::Value::List& origins = args[0].GetList();
+ auto* service =
+ NotificationPermissionsReviewServiceFactory::GetForProfile(profile_);
+ DCHECK(service);
+
+ for (const auto& origin : origins) {
+ const ContentSettingsPattern& primary_pattern =
+ ContentSettingsPattern::FromString(origin.GetString());
+ service->RemovePatternFromNotificationPermissionReviewBlocklist(
+ primary_pattern, ContentSettingsPattern::Wildcard());
+ }
+ SendNotificationPermissionReviewList();
+}
+
+void SafetyHubHandler::RegisterMessages() {
+ // Usage of base::Unretained(this) is safe, because web_ui() owns `this` and
+ // won't release ownership until destruction.
+ web_ui()->RegisterMessageCallback(
+ "getRevokedUnusedSitePermissionsList",
+ base::BindRepeating(
+ &SafetyHubHandler::HandleGetRevokedUnusedSitePermissionsList,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "allowPermissionsAgainForUnusedSite",
+ base::BindRepeating(
+ &SafetyHubHandler::HandleAllowPermissionsAgainForUnusedSite,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "undoAllowPermissionsAgainForUnusedSite",
+ base::BindRepeating(
+ &SafetyHubHandler::HandleUndoAllowPermissionsAgainForUnusedSite,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "acknowledgeRevokedUnusedSitePermissionsList",
+ base::BindRepeating(
+ &SafetyHubHandler::HandleAcknowledgeRevokedUnusedSitePermissionsList,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "undoAcknowledgeRevokedUnusedSitePermissionsList",
+ base::BindRepeating(
+ &SafetyHubHandler::
+ HandleUndoAcknowledgeRevokedUnusedSitePermissionsList,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "getNotificationPermissionReview",
+ base::BindRepeating(
+ &SafetyHubHandler::HandleGetNotificationPermissionReviewList,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "ignoreNotificationPermissionReviewForOrigins",
+ base::BindRepeating(
+ &SafetyHubHandler::HandleIgnoreOriginsForNotificationPermissionReview,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "resetNotificationPermissionForOrigins",
+ base::BindRepeating(
+ &SafetyHubHandler::HandleResetNotificationPermissionForOrigins,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "blockNotificationPermissionForOrigins",
+ base::BindRepeating(
+ &SafetyHubHandler::HandleBlockNotificationPermissionForOrigins,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "allowNotificationPermissionForOrigins",
+ base::BindRepeating(
+ &SafetyHubHandler::HandleAllowNotificationPermissionForOrigins,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "undoIgnoreNotificationPermissionReviewForOrigins",
+ base::BindRepeating(
+ &SafetyHubHandler::
+ HandleUndoIgnoreOriginsForNotificationPermissionReview,
+ base::Unretained(this)));
+}
+
+void SafetyHubHandler::SendUnusedSitePermissionsReviewList() {
+ // Notify observers that the unused site permission review list could have
+ // changed. Note that the list is not guaranteed to have changed. In places
+ // where determining whether the list has changed is cause for performance
+ // concerns, an unchanged list may be sent.
+ FireWebUIListener("unused-permission-review-list-maybe-changed",
+ PopulateUnusedSitePermissionsData());
+}
+
+void SafetyHubHandler::SendNotificationPermissionReviewList() {
+ // Notify observers that the permission review list could have changed. Note
+ // that the list is not guaranteed to have changed.
+ FireWebUIListener(
+ site_settings::kNotificationPermissionsReviewListMaybeChangedEvent,
+ site_settings::PopulateNotificationPermissionReviewData(profile_));
+}
+
+void SafetyHubHandler::SetClockForTesting(base::Clock* clock) {
+ clock_ = clock;
+}
+
+void SafetyHubHandler::OnJavascriptAllowed() {}
+
+void SafetyHubHandler::OnJavascriptDisallowed() {}
diff --git a/chromium/chrome/browser/ui/webui/settings/safety_hub_handler.h b/chromium/chrome/browser/ui/webui/settings/safety_hub_handler.h
new file mode 100644
index 00000000000..c073b42d778
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/safety_hub_handler.h
@@ -0,0 +1,132 @@
+// Copyright 2022 The Chromium Authors
+// 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_SAFETY_HUB_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_SAFETY_HUB_HANDLER_H_
+
+#include "base/gtest_prod_util.h"
+#include "base/memory/raw_ptr.h"
+#include "base/time/clock.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+#include "components/content_settings/core/common/content_settings_constraints.h"
+#include "components/content_settings/core/common/content_settings_types.h"
+#include "url/origin.h"
+
+/**
+ * This handler deals with the permission-related operations on the site
+ * settings page.
+ */
+
+class SafetyHubHandler : public settings::SettingsPageUIHandler {
+ public:
+ explicit SafetyHubHandler(Profile* profile);
+
+ ~SafetyHubHandler() override;
+
+ static std::unique_ptr<SafetyHubHandler> GetForProfile(Profile* profile);
+
+ private:
+ friend class SafetyHubHandlerTest;
+ FRIEND_TEST_ALL_PREFIXES(SafetyHubHandlerTest,
+ PopulateUnusedSitePermissionsData);
+ FRIEND_TEST_ALL_PREFIXES(SafetyHubHandlerTest,
+ HandleAllowPermissionsAgainForUnusedSite);
+ FRIEND_TEST_ALL_PREFIXES(SafetyHubHandlerTest,
+ HandleAcknowledgeRevokedUnusedSitePermissionsList);
+ FRIEND_TEST_ALL_PREFIXES(SafetyHubHandlerTest,
+ HandleIgnoreOriginsForNotificationPermissionReview);
+ FRIEND_TEST_ALL_PREFIXES(SafetyHubHandlerTest,
+ HandleBlockNotificationPermissionForOrigins);
+ FRIEND_TEST_ALL_PREFIXES(SafetyHubHandlerTest,
+ HandleAllowNotificationPermissionForOrigins);
+ FRIEND_TEST_ALL_PREFIXES(SafetyHubHandlerTest,
+ HandleResetNotificationPermissionForOrigins);
+ FRIEND_TEST_ALL_PREFIXES(SafetyHubHandlerTest,
+ PopulateNotificationPermissionReviewData);
+ FRIEND_TEST_ALL_PREFIXES(
+ SafetyHubHandlerTest,
+ HandleUndoIgnoreOriginsForNotificationPermissionReview);
+ FRIEND_TEST_ALL_PREFIXES(SafetyHubHandlerTest,
+ SendNotificationPermissionReviewList_FeatureEnabled);
+ FRIEND_TEST_ALL_PREFIXES(
+ SafetyHubHandlerTest,
+ SendNotificationPermissionReviewList_FeatureDisabled);
+ FRIEND_TEST_ALL_PREFIXES(SafetyHubHandlerTest, RevokeAllContentSettingTypes);
+
+ // SettingsPageUIHandler implementation.
+ void OnJavascriptAllowed() override;
+ void OnJavascriptDisallowed() override;
+
+ // WebUIMessageHandler implementation.
+ void RegisterMessages() override;
+
+ // Returns the list of revoked permissions to be used in
+ // "Unused site permissions" module.
+ void HandleGetRevokedUnusedSitePermissionsList(const base::Value::List& args);
+
+ // Re-grant the revoked permissions and remove the given origin from the
+ // revoked permissions list.
+ void HandleAllowPermissionsAgainForUnusedSite(const base::Value::List& args);
+
+ // Reverse the changes made by |HandleAllowPermissionsAgainForUnusedSite| for
+ // the given |UnusedSitePermission| object.
+ void HandleUndoAllowPermissionsAgainForUnusedSite(
+ const base::Value::List& args);
+
+ // Clear the list of revoked permissions so they are not shown again.
+ // Permission settings themselves are not affected by this.
+ void HandleAcknowledgeRevokedUnusedSitePermissionsList(
+ const base::Value::List& args);
+
+ // Reverse the changes made by
+ // |HandleAcknowledgeRevokedUnusedSitePermissionsList| for the given list of
+ // |UnusedSitePermission| objects. List of revoked
+ // permissions is repopulated. Permission settings are not changed.
+ void HandleUndoAcknowledgeRevokedUnusedSitePermissionsList(
+ const base::Value::List& args);
+
+ // Returns the list of revoked permissions that belongs to origins which
+ // haven't been visited recently.
+ base::Value::List PopulateUnusedSitePermissionsData();
+
+ // Sends the list of unused site permissions to review to the WebUI.
+ void SendUnusedSitePermissionsReviewList();
+
+ // Returns the list of notification permissions that needs to be reviewed.
+ void HandleGetNotificationPermissionReviewList(const base::Value::List& args);
+
+ // Handles ignoring origins for the review notification permissions feature.
+ void HandleIgnoreOriginsForNotificationPermissionReview(
+ const base::Value::List& args);
+
+ // Handles resetting a notification permission for given origins.
+ void HandleResetNotificationPermissionForOrigins(
+ const base::Value::List& args);
+
+ // Handles blocking notification permissions for multiple origins.
+ void HandleBlockNotificationPermissionForOrigins(
+ const base::Value::List& args);
+
+ // Handles allowing notification permissions for multiple origins.
+ void HandleAllowNotificationPermissionForOrigins(
+ const base::Value::List& args);
+
+ // Handles reverting the action of ignoring origins for review notification
+ // permissions feature by removing them from the notification permission
+ // verification blocklist.
+ void HandleUndoIgnoreOriginsForNotificationPermissionReview(
+ const base::Value::List& args);
+
+ // Sends the list of notification permissions to review to the WebUI.
+ void SendNotificationPermissionReviewList();
+
+ const raw_ptr<Profile, DanglingUntriaged> profile_;
+
+ raw_ptr<base::Clock> clock_;
+
+ void SetClockForTesting(base::Clock* clock);
+};
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_SAFETY_HUB_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/safety_hub_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/safety_hub_handler_unittest.cc
new file mode 100644
index 00000000000..eff41a3c8b1
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/safety_hub_handler_unittest.cc
@@ -0,0 +1,390 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <ctime>
+#include <memory>
+
+#include "base/memory/scoped_refptr.h"
+#include "base/test/simple_test_clock.h"
+#include "base/time/clock.h"
+#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
+#include "chrome/browser/history/history_service_factory.h"
+#include "chrome/browser/permissions/notification_permission_review_service_factory.h"
+#include "chrome/browser/ui/webui/settings/safety_hub_handler.h"
+#include "chrome/browser/ui/webui/settings/site_settings_helper.h"
+#include "chrome/common/chrome_features.h"
+#include "chrome/test/base/testing_profile.h"
+#include "components/content_settings/core/browser/content_settings_registry.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_types.h"
+#include "components/content_settings/core/common/features.h"
+#include "components/permissions/constants.h"
+#include "components/permissions/unused_site_permissions_service.h"
+#include "content/public/browser/storage_partition.h"
+#include "content/public/common/content_features.h"
+#include "content/public/test/browser_task_environment.h"
+#include "content/public/test/test_web_ui.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+constexpr char kUnusedTestSite[] = "https://example1.com";
+constexpr char kUsedTestSite[] = "https://example2.com";
+constexpr ContentSettingsType kUnusedPermission =
+ ContentSettingsType::GEOLOCATION;
+
+class SafetyHubHandlerTest : public testing::Test {
+ public:
+ SafetyHubHandlerTest() {
+ feature_list_.InitAndEnableFeature(
+ content_settings::features::kSafetyCheckUnusedSitePermissions);
+ }
+
+ void SetUp() override {
+ // Fully initialize |profile_| in the constructor since some children
+ // classes need it right away for SetUp().
+ TestingProfile::Builder profile_builder;
+ profile_builder.AddTestingFactory(
+ HistoryServiceFactory::GetInstance(),
+ HistoryServiceFactory::GetDefaultFactory());
+ profile_ = profile_builder.Build();
+
+ // Set clock for HostContentSettingsMap.
+ base::Time time;
+ ASSERT_TRUE(base::Time::FromString("2022-09-07 13:00", &time));
+ clock_.SetNow(time);
+ hcsm_ = HostContentSettingsMapFactory::GetForProfile(profile());
+ hcsm_->SetClockForTesting(&clock_);
+
+ handler_ = std::make_unique<SafetyHubHandler>(profile());
+ handler()->set_web_ui(web_ui());
+ handler()->AllowJavascript();
+
+ // Create a revoked permission.
+ base::Value::Dict dict = base::Value::Dict();
+ base::Value::List permission_type_list = base::Value::List();
+ permission_type_list.Append(
+ static_cast<int32_t>(ContentSettingsType::GEOLOCATION));
+ dict.Set(permissions::kRevokedKey,
+ base::Value::List(std::move(permission_type_list)));
+
+ hcsm()->SetWebsiteSettingDefaultScope(
+ GURL(kUnusedTestSite), GURL(kUnusedTestSite),
+ ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS,
+ base::Value(dict.Clone()));
+
+ // There should be only an unused URL in the revoked permissions list.
+ const auto& revoked_permissions =
+ handler()->PopulateUnusedSitePermissionsData();
+ EXPECT_EQ(revoked_permissions.size(), 1UL);
+ EXPECT_EQ(GURL(kUnusedTestSite),
+ GURL(*revoked_permissions[0].GetDict().FindString(
+ site_settings::kOrigin)));
+ }
+
+ void TearDown() override {
+ if (profile_) {
+ auto* partition = profile_->GetDefaultStoragePartition();
+ if (partition) {
+ partition->WaitForDeletionTasksForTesting();
+ }
+ }
+ }
+
+ void ExpectRevokedPermission() {
+ ContentSettingsForOneType revoked_permissions_list;
+ hcsm()->GetSettingsForOneType(
+ ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS,
+ &revoked_permissions_list);
+ EXPECT_EQ(1U, revoked_permissions_list.size());
+ EXPECT_EQ(
+ ContentSetting::CONTENT_SETTING_ASK,
+ hcsm()->GetContentSetting(GURL(kUnusedTestSite), GURL(kUnusedTestSite),
+ kUnusedPermission));
+ }
+
+ void ValidateNotificationPermissionUpdate() {
+ const content::TestWebUI::CallData& data = *web_ui()->call_data().back();
+ EXPECT_EQ("cr.webUIListenerCallback", data.function_name());
+
+ ASSERT_TRUE(data.arg1()->is_string());
+ EXPECT_EQ("notification-permission-review-list-maybe-changed",
+ data.arg1()->GetString());
+
+ ASSERT_TRUE(data.arg2()->is_list());
+ }
+
+ base::Value::List GetOriginList(int size) {
+ base::Value::List origins;
+ for (int i = 0; i < size; i++) {
+ origins.Append("https://example" + base::NumberToString(i) + ".org:443");
+ }
+ return origins;
+ }
+
+ TestingProfile* profile() { return profile_.get(); }
+ content::TestWebUI* web_ui() { return &web_ui_; }
+ SafetyHubHandler* handler() { return handler_.get(); }
+ HostContentSettingsMap* hcsm() { return hcsm_.get(); }
+ base::SimpleTestClock* clock() { return &clock_; }
+
+ private:
+ base::test::ScopedFeatureList feature_list_;
+ content::BrowserTaskEnvironment task_environment_;
+ std::unique_ptr<SafetyHubHandler> handler_;
+ std::unique_ptr<TestingProfile> profile_;
+ content::TestWebUI web_ui_;
+ scoped_refptr<HostContentSettingsMap> hcsm_;
+ base::SimpleTestClock clock_;
+};
+
+TEST_F(SafetyHubHandlerTest, PopulateUnusedSitePermissionsData) {
+ // Add GEOLOCATION setting for url but do not add to revoked list.
+ content_settings::ContentSettingConstraints constraint;
+ constraint.set_track_last_visit_for_autoexpiration(true);
+ hcsm()->SetContentSettingDefaultScope(
+ GURL(kUsedTestSite), GURL(kUsedTestSite),
+ ContentSettingsType::GEOLOCATION, ContentSetting::CONTENT_SETTING_ALLOW,
+ constraint);
+
+ // Revoked permissions list should still only contain the initial unused site.
+ const auto& revoked_permissions =
+ handler()->PopulateUnusedSitePermissionsData();
+ EXPECT_EQ(revoked_permissions.size(), 1UL);
+ EXPECT_EQ(GURL(kUnusedTestSite),
+ GURL(*revoked_permissions[0].GetDict().FindString(
+ site_settings::kOrigin)));
+}
+
+TEST_F(SafetyHubHandlerTest, HandleAllowPermissionsAgainForUnusedSite) {
+ base::Value::List initial_unused_site_permissions =
+ handler()->PopulateUnusedSitePermissionsData();
+ ExpectRevokedPermission();
+
+ // Allow the revoked permission for the unused site again.
+ base::Value::List args;
+ args.Append(base::Value(kUnusedTestSite));
+ handler()->HandleAllowPermissionsAgainForUnusedSite(args);
+
+ // Check there is no origin in revoked permissions list.
+ ContentSettingsForOneType revoked_permissions_list;
+ hcsm()->GetSettingsForOneType(
+ ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS,
+ &revoked_permissions_list);
+ EXPECT_EQ(0U, revoked_permissions_list.size());
+ // Check if the permissions of url is regranted.
+ EXPECT_EQ(
+ ContentSetting::CONTENT_SETTING_ALLOW,
+ hcsm()->GetContentSetting(GURL(kUnusedTestSite), GURL(kUnusedTestSite),
+ kUnusedPermission));
+
+ // Undoing restores the initial state.
+ handler()->HandleUndoAllowPermissionsAgainForUnusedSite(
+ std::move(initial_unused_site_permissions));
+ ExpectRevokedPermission();
+}
+
+TEST_F(SafetyHubHandlerTest,
+ HandleAcknowledgeRevokedUnusedSitePermissionsList) {
+ const auto& revoked_permissions_before =
+ handler()->PopulateUnusedSitePermissionsData();
+ EXPECT_GT(revoked_permissions_before.size(), 0U);
+ // Acknowledging revoked permissions from unused sites clears the list.
+ base::Value::List args;
+ handler()->HandleAcknowledgeRevokedUnusedSitePermissionsList(args);
+ const auto& revoked_permissions_after =
+ handler()->PopulateUnusedSitePermissionsData();
+ EXPECT_EQ(revoked_permissions_after.size(), 0U);
+
+ // Undo reverts the list to its initial state.
+ base::Value::List undo_args;
+ undo_args.Append(revoked_permissions_before.Clone());
+ handler()->HandleUndoAcknowledgeRevokedUnusedSitePermissionsList(undo_args);
+ EXPECT_EQ(revoked_permissions_before,
+ handler()->PopulateUnusedSitePermissionsData());
+}
+
+TEST_F(SafetyHubHandlerTest,
+ HandleIgnoreOriginsForNotificationPermissionReview) {
+ base::test::ScopedFeatureList scoped_feature;
+ scoped_feature.InitAndEnableFeature(
+ ::features::kSafetyCheckNotificationPermissions);
+
+ HostContentSettingsMap* content_settings =
+ HostContentSettingsMapFactory::GetForProfile(profile());
+ ContentSettingsForOneType ignored_patterns;
+ content_settings->GetSettingsForOneType(
+ ContentSettingsType::NOTIFICATION_PERMISSION_REVIEW, &ignored_patterns);
+ ASSERT_EQ(0U, ignored_patterns.size());
+
+ base::Value::List args;
+ args.Append(GetOriginList(1));
+ handler()->HandleIgnoreOriginsForNotificationPermissionReview(args);
+
+ // Check there is 1 origin in ignore list.
+ content_settings->GetSettingsForOneType(
+ ContentSettingsType::NOTIFICATION_PERMISSION_REVIEW, &ignored_patterns);
+ ASSERT_EQ(1U, ignored_patterns.size());
+
+ ValidateNotificationPermissionUpdate();
+}
+
+TEST_F(SafetyHubHandlerTest,
+ HandleUndoIgnoreOriginsForNotificationPermissionReview) {
+ base::Value::List args;
+ args.Append(GetOriginList(1));
+ handler()->HandleIgnoreOriginsForNotificationPermissionReview(args);
+
+ // Check there is 1 origin in ignore list.
+ HostContentSettingsMap* content_settings =
+ HostContentSettingsMapFactory::GetForProfile(profile());
+ ContentSettingsForOneType ignored_patterns;
+ ASSERT_EQ(0U, ignored_patterns.size());
+ content_settings->GetSettingsForOneType(
+ ContentSettingsType::NOTIFICATION_PERMISSION_REVIEW, &ignored_patterns);
+ ASSERT_EQ(1U, ignored_patterns.size());
+
+ // Check there are no origins in ignore list.
+ handler()->HandleUndoIgnoreOriginsForNotificationPermissionReview(args);
+ content_settings->GetSettingsForOneType(
+ ContentSettingsType::NOTIFICATION_PERMISSION_REVIEW, &ignored_patterns);
+ ASSERT_EQ(0U, ignored_patterns.size());
+}
+
+TEST_F(SafetyHubHandlerTest, HandleAllowNotificationPermissionForOrigins) {
+ base::test::ScopedFeatureList scoped_feature;
+ scoped_feature.InitAndEnableFeature(
+ ::features::kSafetyCheckNotificationPermissions);
+
+ base::Value::List args;
+ base::Value::List origins = GetOriginList(2);
+ args.Append(origins.Clone());
+ handler()->HandleAllowNotificationPermissionForOrigins(args);
+
+ // Check the permission for the two origins is allow.
+ HostContentSettingsMap* content_settings =
+ HostContentSettingsMapFactory::GetForProfile(profile());
+ ContentSettingsForOneType notification_permissions;
+ content_settings->GetSettingsForOneType(ContentSettingsType::NOTIFICATIONS,
+ &notification_permissions);
+ auto type = content_settings->GetContentSetting(
+ GURL(origins[0].GetString()), GURL(), ContentSettingsType::NOTIFICATIONS);
+ ASSERT_EQ(CONTENT_SETTING_ALLOW, type);
+
+ type = content_settings->GetContentSetting(
+ GURL(origins[1].GetString()), GURL(), ContentSettingsType::NOTIFICATIONS);
+ ASSERT_EQ(CONTENT_SETTING_ALLOW, type);
+
+ ValidateNotificationPermissionUpdate();
+}
+
+TEST_F(SafetyHubHandlerTest, HandleBlockNotificationPermissionForOrigins) {
+ base::test::ScopedFeatureList scoped_feature;
+ scoped_feature.InitAndEnableFeature(
+ ::features::kSafetyCheckNotificationPermissions);
+
+ base::Value::List args;
+ base::Value::List origins = GetOriginList(2);
+ args.Append(origins.Clone());
+
+ handler()->HandleBlockNotificationPermissionForOrigins(args);
+
+ // Check the permission for the two origins is block.
+ HostContentSettingsMap* content_settings =
+ HostContentSettingsMapFactory::GetForProfile(profile());
+ ContentSettingsForOneType notification_permissions;
+ content_settings->GetSettingsForOneType(ContentSettingsType::NOTIFICATIONS,
+ &notification_permissions);
+ auto type = content_settings->GetContentSetting(
+ GURL(origins[0].GetString()), GURL(), ContentSettingsType::NOTIFICATIONS);
+ ASSERT_EQ(CONTENT_SETTING_BLOCK, type);
+
+ type = content_settings->GetContentSetting(
+ GURL(origins[1].GetString()), GURL(), ContentSettingsType::NOTIFICATIONS);
+ ASSERT_EQ(CONTENT_SETTING_BLOCK, type);
+
+ ValidateNotificationPermissionUpdate();
+}
+
+TEST_F(SafetyHubHandlerTest, HandleResetNotificationPermissionForOrigins) {
+ base::test::ScopedFeatureList scoped_feature;
+ scoped_feature.InitAndEnableFeature(
+ ::features::kSafetyCheckNotificationPermissions);
+
+ HostContentSettingsMap* content_settings =
+ HostContentSettingsMapFactory::GetForProfile(profile());
+ base::Value::List args;
+ base::Value::List origins = GetOriginList(1);
+ args.Append(origins.Clone());
+
+ content_settings->SetContentSettingCustomScope(
+ ContentSettingsPattern::FromString(origins[0].GetString()),
+ ContentSettingsPattern::Wildcard(), ContentSettingsType::NOTIFICATIONS,
+ CONTENT_SETTING_ALLOW);
+
+ handler()->HandleResetNotificationPermissionForOrigins(args);
+
+ // Check the permission for the origin is reset.
+ auto type = content_settings->GetContentSetting(
+ GURL(origins[0].GetString()), GURL(), ContentSettingsType::NOTIFICATIONS);
+ ASSERT_EQ(CONTENT_SETTING_ASK, type);
+
+ ValidateNotificationPermissionUpdate();
+}
+
+// Test that revocation is happen correctly for all content setting types.
+TEST_F(SafetyHubHandlerTest, RevokeAllContentSettingTypes) {
+ // TODO(crbug.com/1459305): Remove this after adding names for those
+ // types.
+ std::list<ContentSettingsType> no_name_types = {
+ ContentSettingsType::MIDI,
+ ContentSettingsType::DURABLE_STORAGE,
+ ContentSettingsType::ACCESSIBILITY_EVENTS,
+ ContentSettingsType::NFC,
+ ContentSettingsType::FILE_SYSTEM_READ_GUARD,
+ ContentSettingsType::CAMERA_PAN_TILT_ZOOM,
+ ContentSettingsType::TOP_LEVEL_STORAGE_ACCESS};
+
+ // Add all content settings in the content setting registry to revoked
+ // permissions list.
+ auto* content_settings_registry =
+ content_settings::ContentSettingsRegistry::GetInstance();
+ for (const content_settings::ContentSettingsInfo* info :
+ *content_settings_registry) {
+ ContentSettingsType type = info->website_settings_info()->type();
+
+ // If the permission can not be tracked, then also can not be revoked.
+ if (!content_settings::CanTrackLastVisit(type)) {
+ continue;
+ }
+
+ // If the permission can not set to ALLOW, then also can not be revoked.
+ if (!content_settings_registry->Get(type)->IsSettingValid(
+ ContentSetting::CONTENT_SETTING_ALLOW)) {
+ continue;
+ }
+
+ // Add the permission to revoked permission list.
+ auto dict = base::Value::Dict().Set(
+ permissions::kRevokedKey,
+ base::Value::List().Append(static_cast<int32_t>(type)));
+ hcsm()->SetWebsiteSettingDefaultScope(
+ GURL(kUnusedTestSite), GURL(kUnusedTestSite),
+ ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS,
+ base::Value(dict.Clone()));
+
+ // Unless the permission in no_name_types, it should be shown on the UI.
+ const auto& revoked_permissions =
+ handler()->PopulateUnusedSitePermissionsData();
+ bool is_no_name_type =
+ (std::find(no_name_types.begin(), no_name_types.end(), type) !=
+ no_name_types.end());
+ if (is_no_name_type) {
+ EXPECT_EQ(revoked_permissions.size(), 0U);
+ } else {
+ EXPECT_EQ(revoked_permissions.size(), 1U);
+ }
+ }
+}
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 dfa635a69b8..8a977423e5e 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
@@ -239,6 +239,9 @@ void ClearBrowsingDataHandler::HandleClearBrowsingData(
"History.ClearBrowsingData.UserDeletedCookieOrCacheFromDialog", choice,
content::BrowsingDataRemover::MAX_CHOICE_VALUE);
+ browsing_data::RecordDeleteBrowsingDataAction(
+ browsing_data::DeleteBrowsingDataAction::kClearBrowsingDataDialog);
+
// Record the circumstances under which passwords are deleted.
if (data_types.find(BrowsingDataType::PASSWORDS) != data_types.end()) {
static const BrowsingDataType other_types[] = {
diff --git a/chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h b/chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h
index 9848f2bedef..6f83a03a224 100644
--- a/chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h
@@ -22,7 +22,7 @@
#include "components/search/search_provider_observer.h"
#include "components/search_engines/template_url_service_observer.h"
#include "components/signin/core/browser/account_reconcilor.h"
-#include "components/sync/driver/sync_service.h"
+#include "components/sync/service/sync_service.h"
namespace content {
class WebUI;
diff --git a/chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler_unittest.cc
index 66e526091c4..6b6e8750c81 100644
--- a/chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler_unittest.cc
@@ -6,6 +6,7 @@
#include "base/memory/raw_ptr.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/search_engines/template_url_service_factory_test_util.h"
@@ -64,6 +65,10 @@ class ClearBrowsingDataHandlerUnitTest : public testing::Test {
std::unique_ptr<TestingClearBrowsingDataHandler> handler_;
std::unique_ptr<TemplateURLServiceFactoryTestUtil> dse_factory_util_;
raw_ptr<TemplateURLService> template_url_service;
+
+ const content::TestWebUI::CallData& GetCallData() {
+ return *test_web_ui_.call_data().back();
+ }
};
void ClearBrowsingDataHandlerUnitTest::SetUp() {
@@ -85,6 +90,7 @@ void ClearBrowsingDataHandlerUnitTest::SetUp() {
handler_ = std::make_unique<TestingClearBrowsingDataHandler>(&test_web_ui_,
profile_.get());
handler_->set_web_ui(&test_web_ui_);
+ handler_->RegisterMessages();
handler_->AllowJavascript();
browser_task_environment_.RunUntilIdle();
@@ -144,6 +150,25 @@ TemplateURL* ClearBrowsingDataHandlerUnitTest::AddSearchEngine(
return url;
}
+TEST_F(ClearBrowsingDataHandlerUnitTest,
+ ClearBrowsingData_EmmitsDeleteMetrics) {
+ base::HistogramTester histogram_tester;
+ base::Value::List args;
+
+ args.Append("fooCallback");
+ args.Append(base::Value::List());
+ args.Append(1);
+
+ test_web_ui_.HandleReceivedMessage("clearBrowsingData", args);
+
+ const content::TestWebUI::CallData& call_data = GetCallData();
+ ASSERT_EQ(3u, call_data.args().size());
+
+ histogram_tester.ExpectBucketCount(
+ "Privacy.DeleteBrowsingData.Action",
+ browsing_data::DeleteBrowsingDataAction::kClearBrowsingDataDialog, 1);
+}
+
TEST_F(ClearBrowsingDataHandlerUnitTest, UpdateSyncState_GoogleDse) {
handler_->UpdateSyncState();
VerifySearchHistoryWebUIUpdate(false, u"");
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 6d488e842bb..ba144779fd6 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
@@ -36,6 +36,7 @@
#include "chrome/browser/signin/account_consistency_mode_manager_factory.h"
#include "chrome/browser/signin/signin_features.h"
#include "chrome/browser/sync/sync_service_factory.h"
+#include "chrome/browser/ui/managed_ui.h"
#include "chrome/browser/ui/passwords/ui_utils.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/webui/management/management_ui.h"
@@ -70,10 +71,12 @@
#include "components/device_reauth/device_authenticator.h"
#include "components/dom_distiller/core/dom_distiller_features.h"
#include "components/google/core/common/google_util.h"
+#include "components/history/core/common/pref_names.h"
#include "components/omnibox/common/omnibox_features.h"
#include "components/password_manager/core/browser/leak_detection_dialog_utils.h"
#include "components/password_manager/core/browser/manage_passwords_referrer.h"
#include "components/password_manager/core/common/password_manager_features.h"
+#include "components/performance_manager/public/features.h"
#include "components/prefs/pref_service.h"
#include "components/privacy_sandbox/privacy_sandbox_features.h"
#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
@@ -82,10 +85,11 @@
#include "components/strings/grit/components_chromium_strings.h"
#include "components/strings/grit/components_strings.h"
#include "components/subresource_filter/core/browser/subresource_filter_features.h"
+#include "components/supervised_user/core/common/features.h"
#include "components/sync/base/features.h"
-#include "components/sync/driver/sync_service.h"
-#include "components/sync/driver/sync_service_utils.h"
-#include "components/sync/driver/sync_user_settings.h"
+#include "components/sync/service/sync_service.h"
+#include "components/sync/service/sync_service_utils.h"
+#include "components/sync/service/sync_user_settings.h"
#include "components/zoom/page_zoom_constants.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui_data_source.h"
@@ -102,6 +106,7 @@
#include "ui/accessibility/accessibility_switches.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/l10n/time_format.h"
#include "ui/base/webui/web_ui_util.h"
#include "ui/strings/grit/ui_strings.h"
@@ -158,6 +163,11 @@
#include "net/base/features.h"
#endif
+#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
+#include "chrome/browser/supervised_user/supervised_user_service_factory.h"
+#include "components/supervised_user/core/browser/supervised_user_service.h"
+#endif
+
namespace settings {
namespace {
@@ -238,6 +248,12 @@ void AddCommonStrings(content::WebUIDataSource* html_source, Profile* profile) {
#endif
html_source->AddBoolean("isChildAccount", profile->IsChild());
+
+ html_source->AddBoolean(
+ "clearingCookiesKeepsSupervisedUsersSignedIn",
+ base::FeatureList::IsEnabled(
+ supervised_user::kClearingCookiesKeepsSupervisedUsersSignedIn));
+
#if BUILDFLAG(IS_LINUX)
bool allow_qt_theme = base::FeatureList::IsEnabled(ui::kAllowQt);
#else
@@ -314,8 +330,16 @@ void AddAboutStrings(content::WebUIDataSource* html_source, Profile* profile) {
};
html_source->AddLocalizedStrings(kLocalizedStrings);
- html_source->AddString("managementPage",
- ManagementUI::GetManagementPageSubtitle(profile));
+ html_source->AddString(
+ "managementPage",
+#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
+ base::FeatureList::IsEnabled(supervised_user::kEnableManagedByParentUi)
+ ? chrome::GetDeviceManagedUiHelpLabel(profile)
+ : ManagementUI::GetManagementPageSubtitle(profile)
+#else
+ ManagementUI::GetManagementPageSubtitle(profile)
+#endif
+ );
html_source->AddString(
"aboutUpgradeUpToDate",
#if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -366,6 +390,7 @@ void AddAppearanceStrings(content::WebUIDataSource* html_source,
{"chromeColors", IDS_SETTINGS_CHROME_COLORS},
{"showHomeButton", IDS_SETTINGS_SHOW_HOME_BUTTON},
{"showBookmarksBar", IDS_SETTINGS_SHOW_BOOKMARKS_BAR},
+ {"showHoverCardImages", IDS_SETTINGS_SHOW_HOVER_CARD_IMAGES},
{"sidePanel", IDS_SETTINGS_SIDE_PANEL},
{"homePageNtp", IDS_SETTINGS_HOME_PAGE_NTP},
{"changeHomePage", IDS_SETTINGS_CHANGE_HOME_PAGE},
@@ -413,6 +438,9 @@ void AddAppearanceStrings(content::WebUIDataSource* html_source,
html_source->AddBoolean("showReaderModeOption",
dom_distiller::OfferReaderModeInSettings());
html_source->AddBoolean("showSidePanelOptions", true);
+ html_source->AddBoolean(
+ "showHoverCardImagesOption",
+ base::FeatureList::IsEnabled(features::kTabHoverCardImageSettings));
// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
// of lacros-chrome is complete.
@@ -451,6 +479,8 @@ void AddClearBrowsingDataStrings(content::WebUIDataSource* html_source,
{"clearCookiesSummarySignedInMainProfile",
IDS_SETTINGS_CLEAR_COOKIES_AND_SITE_DATA_SUMMARY_BASIC_MAIN_PROFILE},
#endif
+ {"clearCookiesSummarySignedInSupervisedProfile",
+ IDS_SETTINGS_CLEAR_COOKIES_AND_SITE_DATA_SUMMARY_BASIC_SUPERVISED_PROFILE},
{"clearCookiesCounter", IDS_DEL_COOKIES_COUNTER},
{"clearPasswords", IDS_SETTINGS_CLEAR_PASSWORDS},
{"clearFormData", IDS_SETTINGS_CLEAR_FORM_DATA},
@@ -544,98 +574,6 @@ void AddGetTheMostOutOfChromeStrings(content::WebUIDataSource* html_source) {
#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
-void AddChromeCleanupStrings(content::WebUIDataSource* html_source) {
- const char16_t kUnwantedSoftwareProtectionWhitePaperUrl[] =
- u"https://www.google.ca/chrome/browser/privacy/"
- u"whitepaper.html#unwantedsoftware";
-
- static constexpr webui::LocalizedString kLocalizedStrings[] = {
- {"chromeCleanupPageTitle",
- IDS_SETTINGS_RESET_CLEAN_UP_COMPUTER_PAGE_TITLE},
- {"chromeCleanupDetailsFilesAndPrograms",
- IDS_SETTINGS_RESET_CLEANUP_DETAILS_FILES_AND_PROGRAMS},
- {"chromeCleanupDetailsRegistryEntries",
- IDS_SETTINGS_RESET_CLEANUP_DETAILS_REGISTRY_ENTRIES},
- {"chromeCleanupExplanationCleanupError",
- IDS_SETTINGS_RESET_CLEANUP_EXPLANATION_CLEANUP_ERROR},
- {"chromeCleanupExplanationFindAndRemove",
- IDS_SETTINGS_RESET_CLEANUP_EXPLANATION_FIND_AND_REMOVE},
- {"chromeCleanupExplanationNoInternet",
- IDS_SETTINGS_RESET_CLEANUP_EXPLANATION_NO_INTERNET_CONNECTION},
- {"chromeCleanupExplanationPermissionsNeeded",
- IDS_SETTINGS_RESET_CLEANUP_EXPLANATION_PERMISSIONS_NEEDED},
- {"chromeCleanupExplanationRemove",
- // Note: removal explanation should be the same as used in the prompt
- // dialog. Reusing the string to ensure they will not diverge.
- IDS_CHROME_CLEANUP_PROMPT_EXPLANATION},
- {"chromeCleanupExplanationRemoving",
- IDS_SETTINGS_RESET_CLEANUP_EXPLANATION_CURRENTLY_REMOVING},
- {"chromeCleanupExplanationScanError",
- IDS_SETTINGS_RESET_CLEANUP_EXPLANATION_SCAN_ERROR},
- {"chromeCleanupFindButtonLabel",
- IDS_SETTINGS_RESET_CLEANUP_FIND_BUTTON_LABEL},
- {"chromeCleanupLinkShowItems",
- IDS_SETTINGS_RESET_CLEANUP_LINK_SHOW_FILES},
- {"chromeCleanupRemoveButtonLabel",
- IDS_SETTINGS_RESET_CLEANUP_REMOVE_BUTTON_LABEL},
- {"chromeCleanupRestartButtonLabel",
- IDS_SETTINGS_RESET_CLEANUP_RESTART_BUTTON_LABEL},
- {"chromeCleanupTitleErrorCantRemove",
- IDS_SETTINGS_RESET_CLEANUP_TITLE_ERROR_CANT_REMOVE},
- {"chromeCleanupTitleErrorPermissions",
- IDS_SETTINGS_RESET_CLEANUP_TITLE_ERROR_PERMISSIONS_NEEDED},
- {"chromeCleanupTitleFindAndRemove",
- IDS_SETTINGS_RESET_CLEANUP_TITLE_FIND_HARMFUL_SOFTWARE},
- {"chromeCleanupTitleNoInternet",
- IDS_SETTINGS_RESET_CLEANUP_TITLE_NO_INTERNET_CONNECTION},
- {"chromeCleanupTitleNothingFound",
- IDS_SETTINGS_RESET_CLEANUP_TITLE_NOTHING_FOUND},
- {"chromeCleanupTitleRemove", IDS_SETTINGS_RESET_CLEANUP_TITLE_REMOVE},
- {"chromeCleanupTitleRemoved", IDS_SETTINGS_RESET_CLEANUP_TITLE_DONE},
- {"chromeCleanupTitleRemoving", IDS_SETTINGS_RESET_CLEANUP_TITLE_REMOVING},
- {"chromeCleanupTitleRestart", IDS_SETTINGS_RESET_CLEANUP_TITLE_RESTART},
- {"chromeCleanupTitleScanning", IDS_SETTINGS_RESET_CLEANUP_TITLE_SCANNING},
- {"chromeCleanupTitleScanningFailed",
- IDS_SETTINGS_RESET_CLEANUP_TITLE_ERROR_SCANNING_FAILED},
- {"chromeCleanupTitleTryAgainButtonLabel",
- IDS_SETTINGS_RESET_CLEANUP_TRY_AGAIN_BUTTON_LABEL},
- {"chromeCleanupExplanationLogsPermissionPref",
- IDS_SETTINGS_RESET_CLEANUP_LOGS_PERMISSION_PREF},
- {"chromeCleanupTitleCleanupUnavailable",
- IDS_SETTINGS_RESET_CLEANUP_TITLE_CLEANUP_UNAVAILABLE},
- {"chromeCleanupExplanationCleanupUnavailable",
- IDS_SETTINGS_RESET_CLEANUP_EXPLANATION_CLEANUP_UNAVAILABLE},
- };
-
- html_source->AddLocalizedStrings(kLocalizedStrings);
- const std::string cleanup_learn_more_url =
- google_util::AppendGoogleLocaleParam(
- GURL(chrome::kChromeCleanerLearnMoreURL),
- g_browser_process->GetApplicationLocale())
- .spec();
- html_source->AddString("chromeCleanupLearnMoreUrl", cleanup_learn_more_url);
-
- // The "powered by" footer contains an HTML fragment with the SVG logo of the
- // partner. The logo is added directly to the DOM, rather than as an <img>
- // src, to make sure that screen readers can find accessibility tags inside
- // the SVG.
- const std::string powered_by_element = base::StrCat(
- {"<span id='powered-by-logo'>",
- ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(
- IDR_CHROME_CLEANUP_PARTNER),
- "</span>"});
- const std::u16string powered_by_html =
- l10n_util::GetStringFUTF16(IDS_SETTINGS_RESET_CLEANUP_FOOTER_POWERED_BY,
- base::UTF8ToUTF16(powered_by_element));
- html_source->AddString("chromeCleanupPoweredByHtml", powered_by_html);
-
- const std::u16string cleanup_details_explanation =
- l10n_util::GetStringFUTF16(IDS_SETTINGS_RESET_CLEANUP_DETAILS_EXPLANATION,
- kUnwantedSoftwareProtectionWhitePaperUrl);
- html_source->AddString("chromeCleanupDetailsExplanation",
- cleanup_details_explanation);
-}
-
void AddIncompatibleApplicationsStrings(content::WebUIDataSource* html_source) {
static constexpr webui::LocalizedString kLocalizedStrings[] = {
{"incompatibleApplicationsResetCardTitle",
@@ -739,6 +677,16 @@ void AddPerformanceStrings(content::WebUIDataSource* html_source) {
IDS_SETTINGS_PERFORMANCE_HIGH_EFFICIENCY_MODE_SETTING},
{"highEfficiencyModeDescription",
IDS_SETTINGS_PERFORMANCE_HIGH_EFFICIENCY_MODE_SETTING_DESCRIPTION},
+ {"highEfficiencyModeHeuristicsLabel",
+ IDS_SETTINGS_PERFORMANCE_HIGH_EFFICIENCY_MODE_HEURISTICS_LABEL},
+ {"highEfficiencyModeRecommendedBadge",
+ IDS_SETTINGS_PERFORMANCE_HIGH_EFFICIENCY_MODE_RECOMMENDED_BADGE},
+ {"highEfficiencyModeOnTimerLabel",
+ IDS_SETTINGS_PERFORMANCE_HIGH_EFFICIENCY_MODE_ON_TIMER_LABEL},
+ {"highEfficiencyModeRadioGroupAriaLabel",
+ IDS_SETTINGS_PERFORMANCE_HIGH_EFFICIENCY_MODE_RADIO_GROUP_ARIA_LABEL},
+ {"highEfficiencyChooseDiscardTimeAriaLabel",
+ IDS_SETTINGS_PERFORMANCE_HIGH_EFFICIENCY_MODE_CHOOSE_DISCARD_TIME_ARIA_LABEL},
{"batteryPageTitle", IDS_SETTINGS_BATTERY_PAGE_TITLE},
{"batterySaverModeLabel",
IDS_SETTINGS_PERFORMANCE_BATTERY_SAVER_MODE_SETTING},
@@ -756,9 +704,56 @@ void AddPerformanceStrings(content::WebUIDataSource* html_source) {
IDS_SETTINGS_PERFORMANCE_TAB_DISCARDING_EXCEPTIONS_HEADER},
{"tabDiscardingExceptionsAdditionalSites",
IDS_SETTINGS_PERFORMANCE_TAB_DISCARDING_EXCEPTIONS_ADDITIONAL_SITES},
+ {"tabDiscardingExceptionsAddDialogCurrentTabs",
+ IDS_SETTINGS_PERFORMANCE_TAB_DISCARDING_EXCEPTIONS_ADD_DIALOG_CURRENT_TABS},
+ {"tabDiscardingExceptionsAddDialogManual",
+ IDS_SETTINGS_PERFORMANCE_TAB_DISCARDING_EXCEPTIONS_ADD_DIALOG_MANUAL},
+ {"tabDiscardingExceptionsActiveSiteAriaDescription",
+ IDS_SETTINGS_PERFORMANCE_TAB_DISCARDING_EXCEPTIONS_ACTIVE_SITE_ARIA_DESCRIPTION},
};
html_source->AddLocalizedStrings(kLocalizedStrings);
+ html_source->AddBoolean(
+ "highEfficiencyDefaultHeuristicMode",
+ performance_manager::features::kHighEfficiencyDefaultHeuristicMode.Get());
+
+ html_source->AddString(
+ "tabDiscardTimerFiveMinutes",
+ ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_DURATION,
+ ui::TimeFormat::LENGTH_LONG, base::Minutes(5)));
+ html_source->AddString(
+ "tabDiscardTimerFifteenMinutes",
+ ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_DURATION,
+ ui::TimeFormat::LENGTH_LONG, base::Minutes(15)));
+ html_source->AddString(
+ "tabDiscardTimerThirtyMinutes",
+ ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_DURATION,
+ ui::TimeFormat::LENGTH_LONG, base::Minutes(30)));
+ html_source->AddString(
+ "tabDiscardTimerOneHour",
+ ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_DURATION,
+ ui::TimeFormat::LENGTH_LONG, base::Hours(1)));
+ html_source->AddString(
+ "tabDiscardTimerTwoHours",
+ ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_DURATION,
+ ui::TimeFormat::LENGTH_LONG, base::Hours(2)));
+ html_source->AddString(
+ "tabDiscardTimerFourHours",
+ ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_DURATION,
+ ui::TimeFormat::LENGTH_LONG, base::Hours(4)));
+ html_source->AddString(
+ "tabDiscardTimerEightHours",
+ ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_DURATION,
+ ui::TimeFormat::LENGTH_LONG, base::Hours(8)));
+ html_source->AddString(
+ "tabDiscardTimerSixteenHours",
+ ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_DURATION,
+ ui::TimeFormat::LENGTH_LONG, base::Hours(16)));
+ html_source->AddString(
+ "tabDiscardTimerTwentyFourHours",
+ ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_DURATION,
+ ui::TimeFormat::LENGTH_LONG, base::Hours(24)));
+
html_source->AddString(
"batterySaverModeEnabledBelowThresholdLabel",
l10n_util::GetStringFUTF16(
@@ -766,6 +761,11 @@ void AddPerformanceStrings(content::WebUIDataSource* html_source) {
base::NumberToString16(
performance_manager::user_tuning::UserPerformanceTuningManager::
kLowBatteryThresholdPercent)));
+ html_source->AddString(
+ "tabDiscardingExceptionsAddDialogHelp",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_PERFORMANCE_TAB_DISCARDING_EXCEPTIONS_ADD_DIALOG_HELP,
+ base::ASCIIToUTF16(chrome::kHighEfficiencyModeTabDiscardingHelpUrl)));
html_source->AddString("highEfficiencyLearnMoreUrl",
chrome::kHighEfficiencyModeLearnMoreUrl);
@@ -1011,11 +1011,13 @@ void AddAutofillStrings(content::WebUIDataSource* html_source,
{"addressPhone", IDS_SETTINGS_AUTOFILL_ADDRESSES_PHONE},
{"addressEmail", IDS_SETTINGS_AUTOFILL_ADDRESSES_EMAIL},
{"honorificLabel", IDS_SETTINGS_AUTOFILL_ADDRESS_HONORIFIC_LABEL},
+ {"creditCardDescription", IDS_SETTINGS_AUTOFILL_CARD_DESCRIPTION},
+ {"creditCardA11yLabeled", IDS_SETTINGS_AUTOFILL_CARD_A11Y_LABELED},
+ {"creditCardExpDateA11yLabeled",
+ IDS_SETTINGS_AUTOFILL_CARD_EXP_DATE_A11Y_LABELED},
{"moreActionsForAddress", IDS_SETTINGS_AUTOFILL_MORE_ACTIONS_FOR_ADDRESS},
{"moreActionsForCreditCard",
IDS_SETTINGS_AUTOFILL_MORE_ACTIONS_FOR_CREDIT_CARD},
- {"moreActionsCreditCardDescription",
- IDS_SETTINGS_AUTOFILL_MORE_ACTIONS_CARD_DESCRIPTION},
{"removeAddress", IDS_SETTINGS_ADDRESS_REMOVE},
{"removeAddressConfirmationTitle",
IDS_SETTINGS_ADDRESS_REMOVE_CONFIRMATION_TITLE},
@@ -1159,18 +1161,10 @@ void AddAutofillStrings(content::WebUIDataSource* html_source,
IDS_SETTINGS_PASSWORD_MOVE_PASSWORDS_TO_ACCOUNT_DIALOG_BODY_TEXT},
{"passwordMovePasswordsToAccountDialogTitle",
IDS_SETTINGS_PASSWORD_MOVE_PASSWORDS_TO_ACCOUNT_DIALOG_TITLE},
- {"passwordMoveToAccountDialogTitle",
- IDS_SETTINGS_PASSWORD_MOVE_TO_ACCOUNT_DIALOG_TITLE},
- {"passwordMoveToAccountDialogBody",
- IDS_SETTINGS_PASSWORD_MOVE_TO_ACCOUNT_DIALOG_BODY},
{"passwordMoveMultiplePasswordsToAccountDialogMoveButtonText",
IDS_SETTINGS_PASSWORD_MOVE_MULTIPLE_PASSWORDS_TO_ACCOUNT_DIALOG_MOVE_BUTTON_TEXT},
{"passwordMoveMultiplePasswordsToAccountDialogCancelButtonText",
IDS_SETTINGS_PASSWORD_MOVE_MULTIPLE_PASSWORDS_TO_ACCOUNT_DIALOG_CANCEL_BUTTON_TEXT},
- {"passwordMoveToAccountDialogMoveButtonText",
- IDS_SETTINGS_PASSWORD_MOVE_TO_ACCOUNT_DIALOG_MOVE_BUTTON_TEXT},
- {"passwordMoveToAccountDialogCancelButtonText",
- IDS_SETTINGS_PASSWORD_MOVE_TO_ACCOUNT_DIALOG_CANCEL_BUTTON_TEXT},
{"passwordOpenMoveMultiplePasswordsToAccountDialogButtonText",
IDS_SETTINGS_PASSWORD_OPEN_MOVE_MULTIPLE_PASSWORDS_TO_ACCOUNT_DIALOG_BUTTON_TEXT},
{"passwordRemoveDialogTitle", IDS_SETTINGS_PASSWORD_REMOVE_DIALOG_TITLE},
@@ -1209,7 +1203,6 @@ void AddAutofillStrings(content::WebUIDataSource* html_source,
IDS_SETTINGS_PASSWORDS_IMPORT_MISSING_PASSWORD},
{"importPasswordsMissingURL", IDS_SETTINGS_PASSWORDS_IMPORT_MISSING_URL},
{"importPasswordsInvalidURL", IDS_SETTINGS_PASSWORDS_IMPORT_INVALID_URL},
- {"importPasswordsNonASCIIURL", IDS_SETTINGS_PASSWORDS_IMPORT_NON_ASCII_URL},
{"importPasswordsLongURL", IDS_SETTINGS_PASSWORDS_IMPORT_LONG_URL},
{"importPasswordsLongPassword",
IDS_SETTINGS_PASSWORDS_IMPORT_LONG_PASSWORD},
@@ -1503,20 +1496,32 @@ void AddSignOutDialogStrings(content::WebUIDataSource* html_source,
void AddSyncAccountControlStrings(content::WebUIDataSource* html_source) {
static constexpr webui::LocalizedString kLocalizedStrings[] = {
- {"syncingTo", IDS_SETTINGS_PEOPLE_SYNCING_TO_ACCOUNT},
- {"peopleSignIn", IDS_PROFILES_DICE_SIGNIN_BUTTON},
- {"syncPaused", IDS_SETTINGS_PEOPLE_SYNC_PAUSED},
- {"turnOffSync", IDS_SETTINGS_PEOPLE_SYNC_TURN_OFF},
- {"settingsCheckboxLabel", IDS_SETTINGS_SETTINGS_CHECKBOX_LABEL},
- {"syncNotWorking", IDS_SETTINGS_PEOPLE_SYNC_NOT_WORKING},
- {"syncDisabled", IDS_PROFILES_DICE_SYNC_DISABLED_TITLE},
- {"syncPasswordsNotWorking",
- IDS_SETTINGS_PEOPLE_SYNC_PASSWORDS_NOT_WORKING},
- {"peopleSignOut", IDS_SETTINGS_PEOPLE_SIGN_OUT},
- {"useAnotherAccount", IDS_SETTINGS_PEOPLE_SYNC_ANOTHER_ACCOUNT},
- {"syncAdvancedPageTitle", IDS_SETTINGS_NEW_SYNC_ADVANCED_PAGE_TITLE},
+ {"syncingTo", IDS_SETTINGS_PEOPLE_SYNCING_TO_ACCOUNT},
+ {"peopleSignIn", IDS_PROFILES_DICE_SIGNIN_BUTTON},
+ {"syncPaused", IDS_SETTINGS_PEOPLE_SYNC_PAUSED},
+ {"turnOffSync", IDS_SETTINGS_PEOPLE_SYNC_TURN_OFF},
+ {"settingsCheckboxLabel", IDS_SETTINGS_SETTINGS_CHECKBOX_LABEL},
+ {"syncNotWorking", IDS_SETTINGS_PEOPLE_SYNC_NOT_WORKING},
+ {"syncDisabled", IDS_PROFILES_DICE_SYNC_DISABLED_TITLE},
+ {"syncPasswordsNotWorking", IDS_SETTINGS_PEOPLE_SYNC_PASSWORDS_NOT_WORKING},
+ {"peopleSignOut", IDS_SETTINGS_PEOPLE_SIGN_OUT},
+ {"useAnotherAccount", IDS_SETTINGS_PEOPLE_SYNC_ANOTHER_ACCOUNT},
+
+#if !BUILDFLAG(IS_CHROMEOS_LACROS)
+ {"syncAdvancedPageTitle", IDS_SETTINGS_NEW_SYNC_ADVANCED_PAGE_TITLE},
+#endif
+
};
+
html_source->AddLocalizedStrings(kLocalizedStrings);
+
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+ html_source->AddLocalizedString(
+ "syncAdvancedPageTitle",
+ base::FeatureList::IsEnabled(syncer::kSyncChromeOSAppsToggleSharing)
+ ? IDS_SETTINGS_NEW_SYNC_ADVANCED_BROWSER_PAGE_TITLE
+ : IDS_SETTINGS_NEW_SYNC_ADVANCED_PAGE_TITLE);
+#endif
}
void AddPersonalizationOptionsStrings(content::WebUIDataSource* html_source) {
@@ -1587,6 +1592,17 @@ void AddBrowserSyncPageStrings(content::WebUIDataSource* html_source) {
BuildOSSettingsUrl(chromeos::settings::mojom::kSyncSetupSubpagePath));
#endif
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+ html_source->AddString(
+ "osPrivacySettingsUrl",
+ BuildOSSettingsUrl(
+ chromeos::settings::mojom::kPrivacyAndSecuritySectionPath));
+
+ html_source->AddBoolean(
+ "osDeprecateSyncMetricsToggle",
+ ash::features::IsOsSettingsDeprecateSyncMetricsToggleEnabled());
+#endif
+
#if BUILDFLAG(IS_CHROMEOS)
html_source->AddString(
"osSyncSettingsUrl",
@@ -1596,21 +1612,24 @@ void AddBrowserSyncPageStrings(content::WebUIDataSource* html_source) {
void AddSyncControlsStrings(content::WebUIDataSource* html_source) {
static constexpr webui::LocalizedString kLocalizedStrings[] = {
- {"autofillCheckboxLabel", IDS_SETTINGS_AUTOFILL_CHECKBOX_LABEL},
- {"historyCheckboxLabel", IDS_SETTINGS_HISTORY_CHECKBOX_LABEL},
- {"extensionsCheckboxLabel", IDS_SETTINGS_EXTENSIONS_CHECKBOX_LABEL},
- {"openTabsCheckboxLabel", IDS_SETTINGS_OPEN_TABS_CHECKBOX_LABEL},
- {"wifiConfigurationsCheckboxLabel",
- IDS_SETTINGS_WIFI_CONFIGURATIONS_CHECKBOX_LABEL},
- {"syncEverythingCheckboxLabel",
- IDS_SETTINGS_SYNC_EVERYTHING_CHECKBOX_LABEL},
- {"appCheckboxLabel", IDS_SETTINGS_APPS_CHECKBOX_LABEL},
- {"enablePaymentsIntegrationCheckboxLabel",
- IDS_AUTOFILL_ENABLE_PAYMENTS_INTEGRATION_CHECKBOX_LABEL},
- {"nonPersonalizedServicesSectionLabel",
- IDS_SETTINGS_NON_PERSONALIZED_SERVICES_SECTION_LABEL},
- {"customizeSyncLabel", IDS_SETTINGS_CUSTOMIZE_SYNC},
- {"syncData", IDS_SETTINGS_SYNC_DATA},
+ {"autofillCheckboxLabel", IDS_SETTINGS_AUTOFILL_CHECKBOX_LABEL},
+ {"historyCheckboxLabel", IDS_SETTINGS_HISTORY_CHECKBOX_LABEL},
+ {"extensionsCheckboxLabel", IDS_SETTINGS_EXTENSIONS_CHECKBOX_LABEL},
+ {"openTabsCheckboxLabel", IDS_SETTINGS_OPEN_TABS_CHECKBOX_LABEL},
+ {"wifiConfigurationsCheckboxLabel",
+ IDS_SETTINGS_WIFI_CONFIGURATIONS_CHECKBOX_LABEL},
+ {"syncEverythingCheckboxLabel",
+ IDS_SETTINGS_SYNC_EVERYTHING_CHECKBOX_LABEL},
+ {"appCheckboxLabel", IDS_SETTINGS_APPS_CHECKBOX_LABEL},
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+ {"appCheckboxSublabel", IDS_SETTINGS_APPS_CHECKBOX_SUBLABEL},
+#endif
+ {"enablePaymentsIntegrationCheckboxLabel",
+ IDS_AUTOFILL_ENABLE_PAYMENTS_INTEGRATION_CHECKBOX_LABEL},
+ {"nonPersonalizedServicesSectionLabel",
+ IDS_SETTINGS_NON_PERSONALIZED_SERVICES_SECTION_LABEL},
+ {"customizeSyncLabel", IDS_SETTINGS_CUSTOMIZE_SYNC},
+ {"syncData", IDS_SETTINGS_SYNC_DATA},
};
html_source->AddLocalizedStrings(kLocalizedStrings);
}
@@ -2054,6 +2073,8 @@ void AddPrivacySandboxStrings(content::WebUIDataSource* html_source,
IDS_SETTINGS_PRIVACY_SANDBOX_SPAM_AND_FRAUD_DIALOG_DESCRIPTION_3},
{"adPrivacyLinkRowLabel", IDS_SETTINGS_AD_PRIVACY_LINK_ROW_LABEL},
{"adPrivacyLinkRowSubLabel", IDS_SETTINGS_AD_PRIVACY_LINK_ROW_SUB_LABEL},
+ {"adPrivacyRestrictedLinkRowSubLabel",
+ IDS_SETTINGS_AD_PRIVACY_RESTRICTED_LINK_ROW_SUB_LABEL},
{"adPrivacyPageTitle", IDS_SETTINGS_AD_PRIVACY_PAGE_TITLE},
{"adPrivacyPageTopicsLinkRowLabel",
IDS_SETTINGS_AD_PRIVACY_PAGE_TOPICS_LINK_ROW_LABEL},
@@ -2090,8 +2111,6 @@ void AddPrivacySandboxStrings(content::WebUIDataSource* html_source,
IDS_SETTINGS_TOPICS_PAGE_LEARN_MORE_BULLET_1},
{"topicsPageLearnMoreBullet2",
IDS_SETTINGS_TOPICS_PAGE_LEARN_MORE_BULLET_2},
- {"topicsPageLearnMoreBullet3",
- IDS_SETTINGS_TOPICS_PAGE_LEARN_MORE_BULLET_3},
{"topicsPageCurrentTopicsDescriptionDisabled",
IDS_SETTINGS_TOPICS_PAGE_CURRENT_TOPICS_DESCRIPTION_DISABLED},
{"topicsPageCurrentTopicsDescriptionEmpty",
@@ -2149,8 +2168,6 @@ void AddPrivacySandboxStrings(content::WebUIDataSource* html_source,
IDS_SETTINGS_FLEDGE_PAGE_LEARN_MORE_BULLET_1},
{"fledgePageLearnMoreBullet2",
IDS_SETTINGS_FLEDGE_PAGE_LEARN_MORE_BULLET_2},
- {"fledgePageLearnMoreBullet3",
- IDS_SETTINGS_FLEDGE_PAGE_LEARN_MORE_BULLET_3},
{"fledgePageCurrentSitesDescriptionLearnMoreA11yLabel",
IDS_SETTINGS_FLEDGE_PAGE_CURRENT_SITES_DESCRIPTION_LEARN_MORE_A11Y_LABEL},
{"adMeasurementPageTitle", IDS_SETTINGS_AD_MEASUREMENT_PAGE_TITLE},
@@ -2188,6 +2205,25 @@ void AddPrivacySandboxStrings(content::WebUIDataSource* html_source,
l10n_util::GetStringFUTF16(
IDS_SETTINGS_PRIVACY_SANDBOX_AD_MEASUREMENT_DIALOG_CONTROL_MEASUREMENT,
base::ASCIIToUTF16(chrome::kChromeUIHistoryURL)));
+
+ // Topics and fledge link to help center articles in their learn more dialog.
+ html_source->AddString(
+ "topicsPageLearnMoreBullet3",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_TOPICS_PAGE_LEARN_MORE_BULLET_3,
+ base::ASCIIToUTF16(google_util::AppendGoogleLocaleParam(
+ GURL(chrome::kAdPrivacyLearnMoreURL),
+ g_browser_process->GetApplicationLocale())
+ .spec())));
+ html_source->AddString(
+ "fledgePageLearnMoreBullet3",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_FLEDGE_PAGE_LEARN_MORE_BULLET_3,
+ base::ASCIIToUTF16(google_util::AppendGoogleLocaleParam(
+ GURL(chrome::kAdPrivacyLearnMoreURL),
+ g_browser_process->GetApplicationLocale())
+ .spec())));
+
// Topics and fledge both link to the cookies setting page and cross-link
// each other in the footers.
html_source->AddString(
@@ -2454,7 +2490,6 @@ void AddSearchStrings(content::WebUIDataSource* html_source) {
void AddSearchEnginesStrings(content::WebUIDataSource* html_source) {
static constexpr webui::LocalizedString kLocalizedStrings[] = {
- {"searchEnginesPageTitle", IDS_SETTINGS_SEARCH_ENGINES},
{"searchEnginesPageExplanation",
IDS_SETTINGS_SEARCH_ENGINES_PAGE_EXPLANATION},
{"searchEnginesAddSearchEngine",
@@ -2466,7 +2501,6 @@ void AddSearchEnginesStrings(content::WebUIDataSource* html_source) {
{"searchEnginesDeleteConfirmationDescription",
IDS_SETTINGS_SEARCH_ENGINES_DELETE_CONFIRMATION_DESCRIPTION},
{"searchEngines", IDS_SETTINGS_SEARCH_ENGINES},
- {"searchEnginesDefault", IDS_SETTINGS_SEARCH_ENGINES_DEFAULT_ENGINES},
{"searchEnginesSearchEngines",
IDS_SETTINGS_SEARCH_ENGINES_SEARCH_ENGINES},
{"searchEnginesSearchEnginesExplanation",
@@ -2477,8 +2511,6 @@ void AddSearchEnginesStrings(content::WebUIDataSource* html_source) {
{"searchEnginesNoSitesAdded", IDS_SETTINGS_SEARCH_ENGINES_NO_SITES_ADDED},
{"searchEnginesInactiveShortcuts",
IDS_SETTINGS_SEARCH_ENGINES_INACTIVE_SHORTCUTS},
- {"searchEnginesNoInactiveShortcuts",
- IDS_SETTINGS_SEARCH_ENGINES_NO_INACTIVE_SHORTCUTS},
{"searchEnginesNoOtherEngines",
IDS_SETTINGS_SEARCH_ENGINES_NO_OTHER_ENGINES},
{"searchEnginesExtension", IDS_SETTINGS_SEARCH_ENGINES_EXTENSION_ENGINES},
@@ -2487,7 +2519,6 @@ void AddSearchEnginesStrings(content::WebUIDataSource* html_source) {
{"searchEnginesSearch", IDS_SETTINGS_SEARCH_ENGINES_SEARCH},
{"searchEnginesSearchEngine", IDS_SETTINGS_SEARCH_ENGINES_SEARCH_ENGINE},
{"searchEnginesSiteOrPage", IDS_SETTINGS_SEARCH_ENGINES_SITE_OR_PAGE},
- {"searchEnginesInactiveSite", IDS_SETTINGS_SEARCH_ENGINES_INACTIVE_SITE},
{"searchEnginesShortcut", IDS_SETTINGS_SEARCH_ENGINES_SHORTCUT},
{"searchEnginesQueryURL", IDS_SETTINGS_SEARCH_ENGINES_QUERY_URL},
{"searchEnginesQueryURLExplanation",
@@ -2495,8 +2526,6 @@ void AddSearchEnginesStrings(content::WebUIDataSource* html_source) {
{"searchEnginesMakeDefault", IDS_SETTINGS_SEARCH_ENGINES_MAKE_DEFAULT},
{"searchEnginesActivate", IDS_SETTINGS_SEARCH_ENGINES_ACTIVATE},
{"searchEnginesDeactivate", IDS_SETTINGS_SEARCH_ENGINES_DEACTIVATE},
- {"searchEnginesRemoveFromList",
- IDS_SETTINGS_SEARCH_ENGINES_REMOVE_FROM_LIST},
{"searchEnginesManageExtension",
IDS_SETTINGS_SEARCH_ENGINES_MANAGE_EXTENSION},
{"searchEnginesKeyboardShortcutsTitle",
@@ -2511,8 +2540,6 @@ void AddSearchEnginesStrings(content::WebUIDataSource* html_source) {
IDS_SETTINGS_SEARCH_ENGINES_ADDITIONAL_SITES},
{"searchEnginesAdditionalInactiveSites",
IDS_SETTINGS_SEARCH_ENGINES_ADDITIONAL_INACTIVE_SITES},
- {"searchEnginesAdditionalExtensions",
- IDS_SETTINGS_SEARCH_ENGINES_ADDITIONAL_EXTENSIONS},
};
html_source->AddLocalizedStrings(kLocalizedStrings);
}
@@ -2522,49 +2549,13 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
static constexpr webui::LocalizedString kLocalizedStrings[] = {
{"addSite", IDS_SETTINGS_ADD_SITE},
{"addSiteTitle", IDS_SETTINGS_ADD_SITE_TITLE},
+ {"addSitesTitle", IDS_SETTINGS_ADD_SITES_TITLE},
#if BUILDFLAG(IS_CHROMEOS_ASH)
{"androidSmsNote", IDS_SETTINGS_ANDROID_SMS_NOTE},
#endif
- {"cookieCacheStorage", IDS_SETTINGS_COOKIES_CACHE_STORAGE},
- {"cookieDatabaseStorage", IDS_SETTINGS_COOKIES_DATABASE_STORAGE},
- {"cookieFileSystem", IDS_SETTINGS_COOKIES_FILE_SYSTEM},
- {"cookieFlashLso", IDS_SETTINGS_COOKIES_FLASH_LSO},
- {"cookieLocalStorage", IDS_SETTINGS_COOKIES_LOCAL_STORAGE},
- {"cookieServiceWorker", IDS_SETTINGS_COOKIES_SERVICE_WORKER},
- {"cookieSharedWorker", IDS_SETTINGS_COOKIES_SHARED_WORKER},
- {"cookieQuotaStorage", IDS_SETTINGS_COOKIES_QUOTA_STORAGE},
{"embeddedOnAnyHost", IDS_SETTINGS_EXCEPTIONS_EMBEDDED_ON_ANY_HOST},
{"embeddedOnHost", IDS_SETTINGS_EXCEPTIONS_EMBEDDED_ON_HOST},
{"editSiteTitle", IDS_SETTINGS_EDIT_SITE_TITLE},
- {"cacheStorageLastModified",
- IDS_SETTINGS_COOKIES_LOCAL_STORAGE_LAST_MODIFIED_LABEL},
- {"cacheStorageOrigin", IDS_SETTINGS_COOKIES_LOCAL_STORAGE_ORIGIN_LABEL},
- {"cacheStorageSize", IDS_SETTINGS_COOKIES_LOCAL_STORAGE_SIZE_ON_DISK_LABEL},
- {"cookieAccessibleToScript",
- IDS_SETTINGS_COOKIES_COOKIE_ACCESSIBLE_TO_SCRIPT_LABEL},
- {"cookieContent", IDS_SETTINGS_COOKIES_COOKIE_CONTENT_LABEL},
- {"cookieCreated", IDS_SETTINGS_COOKIES_COOKIE_CREATED_LABEL},
- {"cookieDomain", IDS_SETTINGS_COOKIES_COOKIE_DOMAIN_LABEL},
- {"cookieExpires", IDS_SETTINGS_COOKIES_COOKIE_EXPIRES_LABEL},
- {"cookieName", IDS_SETTINGS_COOKIES_COOKIE_NAME_LABEL},
- {"cookiePath", IDS_SETTINGS_COOKIES_COOKIE_PATH_LABEL},
- {"cookieSendFor", IDS_SETTINGS_COOKIES_COOKIE_SENDFOR_LABEL},
- {"databaseOrigin", IDS_SETTINGS_COOKIES_LOCAL_STORAGE_ORIGIN_LABEL},
- {"fileSystemOrigin", IDS_SETTINGS_COOKIES_LOCAL_STORAGE_ORIGIN_LABEL},
- {"fileSystemPersistentUsage",
- IDS_SETTINGS_COOKIES_FILE_SYSTEM_PERSISTENT_USAGE_LABEL},
- {"fileSystemTemporaryUsage",
- IDS_SETTINGS_COOKIES_FILE_SYSTEM_TEMPORARY_USAGE_LABEL},
- {"indexedDbSize", IDS_SETTINGS_COOKIES_LOCAL_STORAGE_SIZE_ON_DISK_LABEL},
- {"indexedDbLastModified",
- IDS_SETTINGS_COOKIES_LOCAL_STORAGE_LAST_MODIFIED_LABEL},
- {"indexedDbOrigin", IDS_SETTINGS_COOKIES_LOCAL_STORAGE_ORIGIN_LABEL},
- {"localStorageLastModified",
- IDS_SETTINGS_COOKIES_LOCAL_STORAGE_LAST_MODIFIED_LABEL},
- {"localStorageOrigin", IDS_SETTINGS_COOKIES_LOCAL_STORAGE_ORIGIN_LABEL},
- {"localStorageSize", IDS_SETTINGS_COOKIES_LOCAL_STORAGE_SIZE_ON_DISK_LABEL},
- {"quotaOrigin", IDS_SETTINGS_COOKIES_LOCAL_STORAGE_ORIGIN_LABEL},
- {"quotaSize", IDS_SETTINGS_COOKIES_LOCAL_STORAGE_SIZE_ON_DISK_LABEL},
{"noBluetoothDevicesFound", IDS_SETTINGS_NO_BLUETOOTH_DEVICES_FOUND},
{"noHidDevicesFound", IDS_SETTINGS_NO_HID_DEVICES_FOUND},
{"noSerialPortsFound", IDS_SETTINGS_NO_SERIAL_PORTS_FOUND},
@@ -2574,12 +2565,6 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
{"resetSerialPortsConfirmation",
IDS_SETTINGS_RESET_SERIAL_PORTS_CONFIRMATION},
{"resetUsbConfirmation", IDS_SETTINGS_RESET_USB_CONFIRMATION},
- {"serviceWorkerOrigin", IDS_SETTINGS_COOKIES_LOCAL_STORAGE_ORIGIN_LABEL},
- {"serviceWorkerSize",
- IDS_SETTINGS_COOKIES_LOCAL_STORAGE_SIZE_ON_DISK_LABEL},
- {"sharedWorkerWorker", IDS_SETTINGS_COOKIES_SHARED_WORKER_WORKER_LABEL},
- {"sharedWorkerName", IDS_SETTINGS_COOKIES_COOKIE_NAME_LABEL},
- {"siteSettingsCategoryPageTitle", IDS_SETTINGS_SITE_SETTINGS_CATEGORY},
{"siteSettingsRecentPermissionsSectionLabel",
IDS_SETTINGS_SITE_SETTINGS_RECENT_ACTIVITY},
{"siteSettingsCategoryCamera", IDS_SITE_SETTINGS_TYPE_CAMERA},
@@ -2672,9 +2657,6 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
{"cookiePageBlockExceptions", IDS_SETTINGS_COOKIES_BLOCK_EXCEPTIONS},
{"cookiePageSessionOnlyExceptions",
IDS_SETTINGS_COOKIES_SESSION_ONLY_EXCEPTIONS},
- {"cookiesManageSiteSpecificExceptions",
- IDS_SETTINGS_COOKIES_SITE_SPECIFIC_EXCEPTIONS},
- {"siteSettingsCategoryCookies", IDS_SITE_SETTINGS_TYPE_COOKIES},
{"siteSettingsCategoryFederatedIdentityApi",
IDS_SITE_SETTINGS_TYPE_FEDERATED_IDENTITY_API},
{"siteSettingsCategoryHandlers", IDS_SITE_SETTINGS_TYPE_HANDLERS},
@@ -2686,12 +2668,6 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
{"siteSettingsCategoryMicrophone", IDS_SITE_SETTINGS_TYPE_MIC},
{"siteSettingsMicrophoneLabel", IDS_SITE_SETTINGS_TYPE_MIC},
{"siteSettingsCategoryNotifications", IDS_SITE_SETTINGS_TYPE_NOTIFICATIONS},
- {"siteSettingsNotificationsAsk",
- IDS_SETTINGS_SITE_SETTINGS_NOTIFICATIONS_ASK},
- {"siteSettingsNotificationsBlock",
- IDS_SETTINGS_SITE_SETTINGS_NOTIFICATIONS_BLOCK},
- {"siteSettingsEnableQuietNotificationPrompts",
- IDS_SETTINGS_SITE_SETTINGS_ENABLE_QUIET_NOTIFICATION_PROMPTS},
{"siteSettingsCategoryPopups", IDS_SITE_SETTINGS_TYPE_POPUPS_REDIRECTS},
{"siteSettingsCategoryZoomLevels", IDS_SITE_SETTINGS_TYPE_ZOOM_LEVELS},
{"siteSettingsAllSites", IDS_SETTINGS_SITE_SETTINGS_ALL_SITES},
@@ -2709,8 +2685,12 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
IDS_SETTINGS_SITE_SETTINGS_FILE_SYSTEM_SITE_LIST_EDIT_HEADER},
{"siteSettingsFileSystemSiteListRemoveGrantLabel",
IDS_SETTINGS_SITE_SETTINGS_FILE_SYSTEM_SITE_LIST_REMOVE_GRANT_LABEL},
+ {"siteSettingsFileSystemSiteListRemoveGrants",
+ IDS_SETTINGS_SITE_SETTINGS_FILE_SYSTEM_SITE_LIST_REMOVE_GRANTS},
{"siteSettingsFileSystemSiteListViewHeader",
IDS_SETTINGS_SITE_SETTINGS_FILE_SYSTEM_SITE_LIST_VIEW_HEADER},
+ {"siteSettingsFileSystemSiteListViewSiteDetails",
+ IDS_SETTINGS_SITE_SETTINGS_FILE_SYSTEM_SITE_LIST_VIEW_SITE_DETAILS},
{"siteSettingsSiteEntryPartitionedLabel",
IDS_SETTINGS_SITE_SETTINGS_SITE_ENTRY_PARTITIONED_LABEL},
{"siteSettingsSiteRepresentationSeparator",
@@ -2734,10 +2714,6 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
{"siteSettingsClipboard", IDS_SITE_SETTINGS_TYPE_CLIPBOARD},
{"siteSettingsClipboardMidSentence",
IDS_SITE_SETTINGS_TYPE_CLIPBOARD_MID_SENTENCE},
- {"siteSettingsClipboardAsk", IDS_SETTINGS_SITE_SETTINGS_CLIPBOARD_ASK},
- {"siteSettingsClipboardAskRecommended",
- IDS_SETTINGS_SITE_SETTINGS_CLIPBOARD_ASK_RECOMMENDED},
- {"siteSettingsClipboardBlock", IDS_SETTINGS_SITE_SETTINGS_CLIPBOARD_BLOCK},
{"siteSettingsCookies", IDS_SITE_SETTINGS_TYPE_COOKIES},
{"siteSettingsCookiesMidSentence",
IDS_SITE_SETTINGS_TYPE_COOKIES_MID_SENTENCE},
@@ -2765,8 +2741,6 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
IDS_SITE_SETTINGS_TYPE_JAVASCRIPT_MID_SENTENCE},
{"siteSettingsSound", IDS_SITE_SETTINGS_TYPE_SOUND},
{"siteSettingsSoundMidSentence", IDS_SITE_SETTINGS_TYPE_SOUND_MID_SENTENCE},
- {"siteSettingsSoundAllowRecommended",
- IDS_SETTINGS_SITE_SETTINGS_SOUND_ALLOW_RECOMMENDED},
{"siteSettingsPdfDocuments", IDS_SITE_SETTINGS_TYPE_PDF_DOCUMENTS},
{"siteSettingsPdfDownloadPdfs",
IDS_SETTINGS_SITE_SETTINGS_PDF_DOWNLOAD_PDFS},
@@ -2775,8 +2749,6 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
IDS_SITE_SETTINGS_TYPE_PROTECTED_MEDIA_ID_MID_SENTENCE},
{"siteSettingsProtectedContentIdentifiers",
IDS_SITE_SETTINGS_TYPE_PROTECTED_MEDIA_ID},
- {"siteSettingsProtectedContentEnable",
- IDS_SETTINGS_SITE_SETTINGS_PROTECTED_CONTENT_ENABLE},
{"siteSettingsProtectedContentDescription",
IDS_SETTINGS_SITE_SETTINGS_PROTECTED_CONTENT_DESCRIPTION},
{"siteSettingsProtectedContentAllowed",
@@ -2788,8 +2760,6 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN)
{"siteSettingsProtectedContentIdentifiersExplanation",
IDS_SETTINGS_SITE_SETTINGS_PROTECTED_CONTENT_IDENTIFIERS_EXPLANATION},
- {"siteSettingsProtectedContentEnableIdentifiers",
- IDS_SETTINGS_SITE_SETTINGS_PROTECTED_CONTENT_ENABLE_IDENTIFIERS},
{"siteSettingsProtectedContentIdentifiersAllowed",
IDS_SETTINGS_SITE_SETTINGS_PROTECTED_CONTENT_IDENTIFIERS_ALLOWED},
{"siteSettingsProtectedContentIdentifiersBlocked",
@@ -2812,76 +2782,42 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
{"siteSettingsHidDevicesMidSentence",
IDS_SITE_SETTINGS_TYPE_HID_DEVICES_MID_SENTENCE},
{"siteSettingsHidDevicesAsk", IDS_SETTINGS_SITE_SETTINGS_HID_DEVICES_ASK},
- {"siteSettingsHidDevicesAskRecommended",
- IDS_SETTINGS_SITE_SETTINGS_HID_DEVICES_ASK_RECOMMENDED},
{"siteSettingsHidDevicesBlock",
IDS_SETTINGS_SITE_SETTINGS_HID_DEVICES_BLOCK},
{"siteSettingsMidiDevices", IDS_SITE_SETTINGS_TYPE_MIDI_SYSEX},
{"siteSettingsMidiDevicesMidSentence",
IDS_SITE_SETTINGS_TYPE_MIDI_SYSEX_MID_SENTENCE},
- {"siteSettingsMidiDevicesAskRecommended",
- IDS_SETTINGS_SITE_SETTINGS_MIDI_DEVICES_ASK_RECOMMENDED},
{"siteSettingsSerialPorts", IDS_SITE_SETTINGS_TYPE_SERIAL_PORTS},
{"siteSettingsSerialPortsMidSentence",
IDS_SITE_SETTINGS_TYPE_SERIAL_PORTS_MID_SENTENCE},
{"siteSettingsUsbDevices", IDS_SITE_SETTINGS_TYPE_USB_DEVICES},
{"siteSettingsUsbDevicesMidSentence",
IDS_SITE_SETTINGS_TYPE_USB_DEVICES_MID_SENTENCE},
- {"siteSettingsUsbDevicesAskRecommended",
- IDS_SETTINGS_SITE_SETTINGS_USB_DEVICES_ASK_RECOMMENDED},
{"siteSettingsBluetoothDevices", IDS_SITE_SETTINGS_TYPE_BLUETOOTH_DEVICES},
{"siteSettingsBluetoothDevicesMidSentence",
IDS_SITE_SETTINGS_TYPE_BLUETOOTH_DEVICES_MID_SENTENCE},
- {"siteSettingsBluetoothDevicesAskRecommended",
- IDS_SETTINGS_SITE_SETTINGS_BLUETOOTH_DEVICES_ASK_RECOMMENDED},
{"siteSettingsFileSystemWrite",
IDS_SITE_SETTINGS_TYPE_FILE_SYSTEM_ACCESS_WRITE},
{"siteSettingsFileSystemWriteMidSentence",
IDS_SITE_SETTINGS_TYPE_FILE_SYSTEM_ACCESS_WRITE_MID_SENTENCE},
- {"siteSettingsFileSystemWriteAskRecommended",
- IDS_SETTINGS_SITE_SETTINGS_FILE_SYSTEM_ACCESS_WRITE_ASK_RECOMMENDED},
{"siteSettingsRemoveZoomLevel",
IDS_SETTINGS_SITE_SETTINGS_REMOVE_ZOOM_LEVEL},
{"siteSettingsZoomLevels", IDS_SITE_SETTINGS_TYPE_ZOOM_LEVELS},
{"siteSettingsZoomLevelsMidSentence",
IDS_SITE_SETTINGS_TYPE_ZOOM_LEVELS_MID_SENTENCE},
{"siteSettingsNoZoomedSites", IDS_SETTINGS_SITE_SETTINGS_NO_ZOOMED_SITES},
- {"siteSettingsMaySaveCookies", IDS_SETTINGS_SITE_SETTINGS_MAY_SAVE_COOKIES},
- {"siteSettingsAskFirst", IDS_SETTINGS_SITE_SETTINGS_ASK_FIRST},
- {"siteSettingsAskFirstRecommended",
- IDS_SETTINGS_SITE_SETTINGS_ASK_FIRST_RECOMMENDED},
- {"siteSettingsAskBeforeAccessingRecommended",
- IDS_SETTINGS_SITE_SETTINGS_ASK_BEFORE_ACCESSING_RECOMMENDED},
{"siteSettingsAskBeforeSending",
IDS_SETTINGS_SITE_SETTINGS_ASK_BEFORE_SENDING},
- {"siteSettingsAskBeforeSendingRecommended",
- IDS_SETTINGS_SITE_SETTINGS_ASK_BEFORE_SENDING_RECOMMENDED},
- {"siteSettingsAllowRecentlyClosedSitesRecommended",
- IDS_SETTINGS_SITE_SETTINGS_ALLOW_RECENTLY_CLOSED_SITES_RECOMMENDED},
- {"siteSettingsBackgroundSyncBlock",
- IDS_SETTINGS_SITE_SETTINGS_BACKGROUND_SYNC_BLOCK},
{"siteSettingsHandlersAskRecommended",
IDS_SETTINGS_SITE_SETTINGS_HANDLERS_ASK_RECOMMENDED},
{"siteSettingsHandlersBlocked",
IDS_SETTINGS_SITE_SETTINGS_HANDLERS_BLOCKED},
- {"siteSettingsAutoDownloadAskRecommended",
- IDS_SETTINGS_SITE_SETTINGS_AUTOMATIC_DOWNLOAD_ASK_RECOMMENDED},
- {"siteSettingsShowAllRecommended",
- IDS_SETTINGS_SITE_SETTINGS_SHOW_ALL_RECOMMENDED},
{"siteSettingsCookiesAllowed",
IDS_SETTINGS_SITE_SETTINGS_COOKIES_ALLOW_SITES},
- {"siteSettingsCookiesAllowedRecommended",
- IDS_SETTINGS_SITE_SETTINGS_COOKIES_ALLOW_SITES_RECOMMENDED},
{"siteSettingsAllow", IDS_SETTINGS_SITE_SETTINGS_ALLOW},
{"siteSettingsBlock", IDS_SETTINGS_SITE_SETTINGS_BLOCK},
- {"siteSettingsBlockSound", IDS_SETTINGS_SITE_SETTINGS_BLOCK_SOUND},
{"siteSettingsSessionOnly", IDS_SETTINGS_SITE_SETTINGS_SESSION_ONLY},
- {"siteSettingsAllowedRecommended",
- IDS_SETTINGS_SITE_SETTINGS_ALLOWED_RECOMMENDED},
{"siteSettingsBlocked", IDS_SETTINGS_SITE_SETTINGS_BLOCKED},
- {"siteSettingsBlockedRecommended",
- IDS_SETTINGS_SITE_SETTINGS_BLOCKED_RECOMMENDED},
- {"siteSettingsSiteUrl", IDS_SETTINGS_SITE_SETTINGS_SITE_URL},
{"siteSettingsActionAskDefault",
IDS_SETTINGS_SITE_SETTINGS_ASK_DEFAULT_MENU},
{"siteSettingsActionAllowDefault",
@@ -2964,16 +2900,12 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
IDS_SETTINGS_SITE_SETTINGS_CLEAR_DISPLAYED_STORAGE_SIGN_OUT},
{"siteSettingsSiteDetailsSubpageAccessibilityLabel",
IDS_SETTINGS_SITE_SETTINGS_SITE_DETAILS_SUBPAGE_ACCESSIBILITY_LABEL},
- {"firstPartySetsMembershipLabel",
- IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_MEMBERSHIP_LABEL},
{"firstPartySetsMoreActionsTitle",
IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_MORE_ACTIONS_TITLE},
{"firstPartySetsShowRelatedSitesButton",
IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_SHOW_RELATED_SITES_BUTTON},
{"firstPartySetsSiteClearStorageButton",
IDS_SETTINGS_SITE_SETTINGS_FIRST_PARTY_SETS_SITE_CLEAR_STORAGE_BUTTON},
- {"siteSettingsSiteGroupDeleteConfirmationInstalledPlural",
- IDS_SETTINGS_SITE_SETTINGS_SITE_GROUP_DELETE_CONFIRMATION_INSTALLED_PLURAL},
{"siteSettingsSiteClearStorage",
IDS_SETTINGS_SITE_SETTINGS_SITE_CLEAR_STORAGE},
{"siteSettingsSiteClearStorageConfirmation",
@@ -2988,28 +2920,9 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
IDS_SETTINGS_SITE_SETTINGS_SITE_CLEAR_STORAGE_OFFLINE_DATA},
{"siteSettingsRemoveSiteAdPersonalization",
IDS_SETTINGS_SITE_SETTINGS_REMOVE_SITE_AD_PERSONALIZATION},
- {"siteSettingsSiteClearStorageApps",
- IDS_SETTINGS_SITE_SETTINGS_SITE_CLEAR_STORAGE_APPS},
{"siteSettingsSiteGroupDelete", IDS_SETTINGS_SITE_SETTINGS_GROUP_DELETE},
- {"siteSettingsSiteGroupDeleteDialogTitle",
- IDS_SETTINGS_SITE_SETTINGS_SITE_GROUP_DELETE_DIALOG_TITLE},
- {"siteSettingsSiteGroupDeleteConfirmation",
- IDS_SETTINGS_SITE_SETTINGS_SITE_GROUP_DELETE_CONFIRMATION},
- {"siteSettingsSiteGroupDeleteConfirmationNew",
- IDS_SETTINGS_SITE_SETTINGS_SITE_GROUP_DELETE_CONFIRMATION_NEW},
- {"siteSettingsSiteGroupDeleteConfirmationInstalled",
- IDS_SETTINGS_SITE_SETTINGS_SITE_GROUP_DELETE_CONFIRMATION_INSTALLED},
- {"siteSettingsSiteGroupDeleteSignOut",
- IDS_SETTINGS_SITE_SETTINGS_SITE_GROUP_DELETE_SIGN_OUT},
{"siteSettingsSiteGroupDeleteOfflineData",
IDS_SETTINGS_SITE_SETTINGS_SITE_GROUP_DELETE_OFFLINE_DATA},
- {"siteSettingsSiteGroupDeleteApps",
- IDS_SETTINGS_SITE_SETTINGS_SITE_GROUP_DELETE_APPS},
- {"siteSettingsSiteGroupReset", IDS_SETTINGS_SITE_SETTINGS_GROUP_RESET},
- {"siteSettingsSiteGroupResetDialogTitle",
- IDS_SETTINGS_SITE_SETTINGS_SITE_GROUP_RESET_DIALOG_TITLE},
- {"siteSettingsSiteGroupResetConfirmation",
- IDS_SETTINGS_SITE_SETTINGS_SITE_GROUP_RESET_CONFIRMATION},
{"siteSettingsSiteResetAll", IDS_SETTINGS_SITE_SETTINGS_SITE_RESET_ALL},
{"siteSettingsSiteResetConfirmation",
IDS_SETTINGS_SITE_SETTINGS_SITE_RESET_CONFIRMATION},
@@ -3308,13 +3221,9 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
IDS_SETTINGS_SITE_SETTINGS_ZOOM_LEVELS_DESCRIPTION},
{"siteSettingsAds", IDS_SITE_SETTINGS_TYPE_ADS},
{"siteSettingsAdsMidSentence", IDS_SITE_SETTINGS_TYPE_ADS_MID_SENTENCE},
- {"siteSettingsAdsBlockRecommended",
- IDS_SETTINGS_SITE_SETTINGS_ADS_BLOCK_RECOMMENDED},
{"siteSettingsPaymentHandler", IDS_SITE_SETTINGS_TYPE_PAYMENT_HANDLER},
{"siteSettingsPaymentHandlerMidSentence",
IDS_SITE_SETTINGS_TYPE_PAYMENT_HANDLER_MID_SENTENCE},
- {"siteSettingsPaymentHandlerAllowRecommended",
- IDS_SETTINGS_SITE_SETTINGS_PAYMENT_HANDLER_ALLOW_RECOMMENDED},
{"siteSettingsBlockAutoplaySetting",
IDS_SETTINGS_SITE_SETTINGS_BLOCK_AUTOPLAY},
{"emptyAllSitesPage", IDS_SETTINGS_SITE_SETTINGS_EMPTY_ALL_SITES_PAGE},
@@ -3336,13 +3245,9 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
{"siteSettingsAr", IDS_SITE_SETTINGS_TYPE_AR},
{"siteSettingsArMidSentence", IDS_SITE_SETTINGS_TYPE_AR_MID_SENTENCE},
{"siteSettingsArAsk", IDS_SETTINGS_SITE_SETTINGS_AR_ASK},
- {"siteSettingsArAskRecommended",
- IDS_SETTINGS_SITE_SETTINGS_AR_ASK_RECOMMENDED},
{"siteSettingsArBlock", IDS_SETTINGS_SITE_SETTINGS_AR_BLOCK},
{"siteSettingsVr", IDS_SITE_SETTINGS_TYPE_VR},
{"siteSettingsVrMidSentence", IDS_SITE_SETTINGS_TYPE_VR_MID_SENTENCE},
- {"siteSettingsVrAskRecommended",
- IDS_SETTINGS_SITE_SETTINGS_VR_ASK_RECOMMENDED},
{"siteSettingsWindowManagement", IDS_SITE_SETTINGS_TYPE_WINDOW_MANAGEMENT},
{"siteSettingsWindowManagementMidSentence",
IDS_SITE_SETTINGS_TYPE_WINDOW_MANAGEMENT_MID_SENTENCE},
@@ -3361,8 +3266,6 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
{"siteSettingsIdleDetection", IDS_SITE_SETTINGS_TYPE_IDLE_DETECTION},
{"siteSettingsIdleDetectionMidSentence",
IDS_SITE_SETTINGS_TYPE_IDLE_DETECTION_MID_SENTENCE},
- {"siteSettingsIdleDetectionBlock",
- IDS_SETTINGS_SITE_SETTINGS_IDLE_DETECTION_BLOCK},
{"siteSettingsExtensionIdDescription",
IDS_SETTINGS_SITE_SETTINGS_EXTENSION_ID_DESCRIPTION},
{"siteSettingsSiteDataAllowedSubLabel",
@@ -3444,6 +3347,22 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source,
html_source->AddString("addSiteExceptionPlaceholder", "[*.]example.com");
}
+void AddStorageAccessStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"siteSettingsStorageAccess", IDS_SITE_SETTINGS_TYPE_STORAGE_ACCESS},
+ {"siteSettingsStorageAccessMidSentence",
+ IDS_SITE_SETTINGS_TYPE_STORAGE_ACCESS_MID_SENTENCE},
+ {"storageAccessDescription", IDS_SETTINGS_STORAGE_ACCESS_DESCRIPTION},
+ {"storageAccessAllowed", IDS_SETTINGS_STORAGE_ACCESS_ALLOWED},
+ {"storageAccessBlocked", IDS_SETTINGS_STORAGE_ACCESS_BLOCKED},
+ {"storageAccessAllowedExceptions",
+ IDS_SETTINGS_STORAGE_ACCESS_ALLOWED_EXCEPTIONS},
+ {"storageAccessBlockedExceptions",
+ IDS_SETTINGS_STORAGE_ACCESS_BLOCKED_EXCEPTIONS},
+ };
+ html_source->AddLocalizedStrings(kLocalizedStrings);
+}
+
void AddSiteDataPageStrings(content::WebUIDataSource* html_source,
Profile* profile) {
static constexpr webui::LocalizedString kLocalizedStrings[] = {
@@ -3563,10 +3482,6 @@ void AddSecurityKeysStrings(content::WebUIDataSource* html_source) {
{"securityKeysBioEnrollmentNameLabelTooLong",
IDS_SETTINGS_SECURITY_KEYS_BIO_NAME_LABEL_TOO_LONG},
{"securityKeysConfirmPIN", IDS_SETTINGS_SECURITY_KEYS_CONFIRM_PIN},
- {"securityKeysNoCredentialManagement",
- IDS_SETTINGS_SECURITY_KEYS_NO_CREDENTIAL_MANAGEMENT},
- {"securityKeysCredentialManagementRemoved",
- IDS_SETTINGS_SECURITY_KEYS_CREDENTIAL_MANAGEMENT_REMOVED},
{"securityKeysCredentialManagementDesc",
IDS_SETTINGS_SECURITY_KEYS_CREDENTIAL_MANAGEMENT_DESC},
{"securityKeysCredentialManagementConfirmDeleteTitle",
@@ -3583,20 +3498,10 @@ void AddSecurityKeysStrings(content::WebUIDataSource* html_source) {
IDS_SETTINGS_SECURITY_KEYS_CREDENTIAL_DISPLAYNAME_LABEL},
{"securityKeysCredentialManagementLabel",
IDS_SETTINGS_SECURITY_KEYS_CREDENTIAL_MANAGEMENT_LABEL},
- {"securityKeysCredentialManagementDeleteSuccess",
- IDS_SETTINGS_SECURITY_KEYS_CREDENTIAL_MANAGEMENT_DELETE_SUCCESS},
- {"securityKeysCredentialManagementDeleteFailed",
- IDS_SETTINGS_SECURITY_KEYS_CREDENTIAL_MANAGEMENT_DELETE_FAILED},
- {"securityKeysCredentialManagementUpdateSuccess",
- IDS_SETTINGS_SECURITY_KEYS_CREDENTIAL_MANAGEMENT_UPDATE_SUCCESS},
- {"securityKeysCredentialManagementUpdateFailed",
- IDS_SETTINGS_SECURITY_KEYS_CREDENTIAL_MANAGEMENT_UPDATE_FAILED},
{"securityKeysCredentialManagementConfirmDeleteCredential",
IDS_SETTINGS_SECURITY_KEYS_CREDENTIAL_MANAGEMENT_CONFIRM_DELETE_CREDENTIAL},
{"securityKeysInputTooLong",
IDS_SETTINGS_SECURITY_KEYS_INPUT_ERROR_TOO_LONG},
- {"securityKeysCredentialManagementNoCredentials",
- IDS_SETTINGS_SECURITY_KEYS_CREDENTIAL_MANAGEMENT_NO_CREDENTIALS},
{"securityKeysCurrentPIN", IDS_SETTINGS_SECURITY_KEYS_CURRENT_PIN},
{"securityKeysCurrentPINIntro",
IDS_SETTINGS_SECURITY_KEYS_CURRENT_PIN_INTRO},
@@ -3690,7 +3595,6 @@ void AddLocalizedStrings(content::WebUIDataSource* html_source,
#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
- AddChromeCleanupStrings(html_source);
AddIncompatibleApplicationsStrings(html_source);
#endif // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
@@ -3712,6 +3616,7 @@ void AddLocalizedStrings(content::WebUIDataSource* html_source,
AddSearchStrings(html_source);
AddSiteSettingsStrings(html_source, profile);
AddSiteDataPageStrings(html_source, profile);
+ AddStorageAccessStrings(html_source);
#if !BUILDFLAG(IS_CHROMEOS)
AddDefaultBrowserStrings(html_source);
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 6340c1e4ff1..f9f09c625df 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
@@ -4,6 +4,7 @@
#include "chrome/browser/ui/webui/settings/settings_manage_profile_handler.h"
+#include <cstdint>
#include <utility>
#include "base/functional/bind.h"
@@ -153,7 +154,7 @@ void ManageProfileHandler::HandleSetProfileIconToGaiaAvatar(
// Only log if they changed to the GAIA photo.
// Selection of GAIA photo as avatar is logged as part of the function
// below.
- ProfileMetrics::LogProfileSwitchGaia(ProfileMetrics::GAIA_OPT_IN);
+ ProfileMetrics::LogProfileAvatarSelection(SIZE_MAX);
}
ProfileMetrics::LogProfileUpdate(profile_->GetPath());
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 25a9aa31406..a4b7db93f2a 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
@@ -431,9 +431,8 @@ IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, SecureDnsTemplates) {
}
#if BUILDFLAG(IS_CHROMEOS_ASH)
-// TODO(crbug.com/1415758): Flaky.
IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest,
- DISABLED_SecureDnsTemplatesWithIdentifiers) {
+ SecureDnsTemplatesWithIdentifiers) {
std::string templatesWithIdentifier =
"https://foo.test-${USER_EMAIL}/dns-query{?dns}";
std::string templatesWithIdentifierDisplay =
diff --git a/chromium/chrome/browser/ui/webui/settings/settings_security_key_handler.cc b/chromium/chrome/browser/ui/webui/settings/settings_security_key_handler.cc
index 6e3d1c08f40..c205a2310e3 100644
--- a/chromium/chrome/browser/ui/webui/settings/settings_security_key_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/settings_security_key_handler.cc
@@ -12,7 +12,6 @@
#include "base/containers/contains.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
-#include "base/metrics/histogram_functions.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_number_conversions.h"
#include "build/build_config.h"
@@ -1119,7 +1118,9 @@ PasskeysHandler::PasskeysHandler(
PasskeysHandler::~PasskeysHandler() = default;
void PasskeysHandler::OnJavascriptAllowed() {}
-void PasskeysHandler::OnJavascriptDisallowed() {}
+void PasskeysHandler::OnJavascriptDisallowed() {
+ weak_factory_.InvalidateWeakPtrs();
+}
void PasskeysHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(
@@ -1207,6 +1208,7 @@ void PasskeysHandler::HandleDelete(const base::Value::List& args) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK_EQ(2u, args.size());
+ AllowJavascript();
std::vector<uint8_t> credential_id;
const bool ok = base::HexStringToBytes(args[1].GetString(), &credential_id);
DCHECK(ok);
@@ -1218,7 +1220,6 @@ void PasskeysHandler::HandleDelete(const base::Value::List& args) {
}
void PasskeysHandler::OnDeleteComplete(std::string callback_id, bool ok) {
- base::UmaHistogramBoolean("WebAuthentication.PasskeyManagement.Delete", ok);
// The ok parameter is ignored. If it were false, it would mean
// Windows/Mac failed to delete the passkey. This can happen if API support
// is missing but no passkeys will be shown at all in that case so that
@@ -1232,6 +1233,7 @@ void PasskeysHandler::HandleEdit(const base::Value::List& args) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK_EQ(3u, args.size());
+ AllowJavascript();
std::vector<uint8_t> credential_id;
const bool ok = base::HexStringToBytes(args[1].GetString(), &credential_id);
DCHECK(ok);
@@ -1244,7 +1246,6 @@ void PasskeysHandler::HandleEdit(const base::Value::List& args) {
}
void PasskeysHandler::OnEditComplete(std::string callback_id, bool ok) {
- base::UmaHistogramBoolean("WebAuthentication.PasskeyManagement.Edit", ok);
// The ok parameter is ignored. If it were false, it would mean
// Windows/Mac failed to edit the passkey.
DoEnumerate(std::move(callback_id));
diff --git a/chromium/chrome/browser/ui/webui/settings/settings_security_key_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/settings_security_key_handler_unittest.cc
index bd8ee36d20b..9bd166c708e 100644
--- a/chromium/chrome/browser/ui/webui/settings/settings_security_key_handler_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/settings_security_key_handler_unittest.cc
@@ -7,7 +7,6 @@
#include <memory>
#include "base/test/gmock_callback_support.h"
-#include "base/test/metrics/histogram_tester.h"
#include "base/values.h"
#include "chrome/browser/webauthn/local_credential_management.h"
#include "chrome/grit/generated_resources.h"
@@ -409,7 +408,6 @@ class PasskeysHandlerTest : public ChromeRenderViewHostTestHarness {
TEST_F(PasskeysHandlerTest, TestHandleEdit) {
device::test::TestCallbackReceiver<bool> callback;
- base::HistogramTester histogram_tester;
std::vector<uint8_t> credential_id =
device::fido_parsing_utils::Materialize(kCredentialID);
std::string credential_id_hex = base::HexEncode(credential_id);
@@ -446,12 +444,9 @@ TEST_F(PasskeysHandlerTest, TestHandleEdit) {
EXPECT_EQ(*web_ui_->call_data()[0]->arg3()->GetList()[0].GetDict().FindString(
"userName"),
"new-username");
- histogram_tester.ExpectUniqueSample(
- "WebAuthentication.PasskeyManagement.Edit", true, 1);
}
TEST_F(PasskeysHandlerTest, TestRecordPasskeyDelete) {
- base::HistogramTester histogram_tester;
device::test::TestCallbackReceiver<bool> callback;
std::vector<uint8_t> credential_id =
device::fido_parsing_utils::Materialize(kCredentialID);
@@ -475,8 +470,6 @@ TEST_F(PasskeysHandlerTest, TestRecordPasskeyDelete) {
handler_->SimulateDelete(credential_id_hex);
EXPECT_EQ(web_ui_->call_data()[0]->arg1()->GetString(), "passkeysDelete");
EXPECT_EQ(web_ui_->call_data()[0]->arg2()->GetBool(), true);
- histogram_tester.ExpectUniqueSample(
- "WebAuthentication.PasskeyManagement.Delete", true, 1);
}
#endif
diff --git a/chromium/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc b/chromium/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc
index 4a49f279937..66d3c8f1c8b 100644
--- a/chromium/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc
@@ -82,7 +82,11 @@ void StartupPagesHandler::OnModelChanged() {
for (size_t i = 0; i < page_count; ++i) {
base::Value::Dict entry;
entry.Set("title", startup_custom_pages_table_model_.GetText(i, 0));
- entry.Set("url", urls[i].spec());
+ std::string spec;
+ if (urls[i].is_valid()) {
+ spec = urls[i].spec();
+ }
+ entry.Set("url", std::move(spec));
entry.Set("tooltip", startup_custom_pages_table_model_.GetTooltip(i));
entry.Set("modelIndex", base::checked_cast<int>(i));
startup_pages.Append(std::move(entry));
diff --git a/chromium/chrome/browser/ui/webui/settings/settings_ui.cc b/chromium/chrome/browser/ui/webui/settings/settings_ui.cc
index 771d2e5bfe4..6003e415372 100644
--- a/chromium/chrome/browser/ui/webui/settings/settings_ui.cc
+++ b/chromium/chrome/browser/ui/webui/settings/settings_ui.cc
@@ -52,7 +52,9 @@
#include "chrome/browser/ui/webui/settings/profile_info_handler.h"
#include "chrome/browser/ui/webui/settings/protocol_handlers_handler.h"
#include "chrome/browser/ui/webui/settings/reset_settings_handler.h"
+#include "chrome/browser/ui/webui/settings/safety_check_extensions_handler.h"
#include "chrome/browser/ui/webui/settings/safety_check_handler.h"
+#include "chrome/browser/ui/webui/settings/safety_hub_handler.h"
#include "chrome/browser/ui/webui/settings/search_engines_handler.h"
#include "chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h"
#include "chrome/browser/ui/webui/settings/settings_localized_strings_provider.h"
@@ -63,7 +65,6 @@
#include "chrome/browser/ui/webui/settings/settings_startup_pages_handler.h"
#include "chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.h"
#include "chrome/browser/ui/webui/settings/site_settings_handler.h"
-#include "chrome/browser/ui/webui/settings/site_settings_permissions_handler.h"
#include "chrome/browser/ui/webui/webui_util.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/pref_names.h"
@@ -79,6 +80,7 @@
#include "components/favicon_base/favicon_url_parser.h"
#include "components/password_manager/core/common/password_manager_features.h"
#include "components/performance_manager/public/features.h"
+#include "components/permissions/features.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_service.h"
#include "components/privacy_sandbox/privacy_sandbox_features.h"
@@ -99,16 +101,11 @@
#include "chrome/grit/settings_shared_resources_map.h"
#endif
-#if BUILDFLAG(IS_WIN)
-#include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h"
-#include "chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h"
-#include "chrome/browser/ui/webui/settings/chrome_cleanup_handler_win.h"
-#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
#include "chrome/browser/ui/webui/settings/incompatible_applications_handler_win.h"
#include "chrome/browser/win/conflicts/incompatible_applications_updater.h"
#include "chrome/browser/win/conflicts/token_util.h"
-#endif
-#endif // BUILDFLAG(IS_WIN)
+#endif // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS_ASH)
#include "chrome/browser/ui/webui/settings/languages_handler.h"
@@ -213,8 +210,9 @@ SettingsUI::SettingsUI(content::WebUI* web_ui)
AddSettingsPageUIHandler(
std::make_unique<ClearBrowsingDataHandler>(web_ui, profile));
AddSettingsPageUIHandler(std::make_unique<SafetyCheckHandler>());
+ AddSettingsPageUIHandler(std::make_unique<SafetyHubHandler>(profile));
AddSettingsPageUIHandler(
- std::make_unique<SiteSettingsPermissionsHandler>(profile));
+ std::make_unique<SafetyCheckExtensionsHandler>(profile));
AddSettingsPageUIHandler(std::make_unique<DownloadsHandler>(profile));
AddSettingsPageUIHandler(std::make_unique<ExtensionControlHandler>());
AddSettingsPageUIHandler(std::make_unique<FontHandler>(profile));
@@ -271,10 +269,6 @@ SettingsUI::SettingsUI(content::WebUI* web_ui)
#endif
-#if BUILDFLAG(IS_WIN)
- AddSettingsPageUIHandler(std::make_unique<ChromeCleanupHandler>(profile));
-#endif // BUILDFLAG(IS_WIN)
-
#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
bool has_incompatible_applications =
IncompatibleApplicationsUpdater::HasCachedApplications();
@@ -309,13 +303,6 @@ SettingsUI::SettingsUI(content::WebUI* web_ui)
html_source->AddBoolean(
"enablePasswordViewPage",
!enable_new_password_manager_page &&
- (base::FeatureList::IsEnabled(
- password_manager::features::kPasswordViewPageInSettings) ||
- base::FeatureList::IsEnabled(syncer::kPasswordNotesWithBackup)));
-
- html_source->AddBoolean(
- "enablePasswordNotes",
- !enable_new_password_manager_page &&
base::FeatureList::IsEnabled(syncer::kPasswordNotesWithBackup));
html_source->AddBoolean("enableSendPasswords",
@@ -361,16 +348,14 @@ SettingsUI::SettingsUI(content::WebUI* web_ui)
html_source->AddBoolean("userCannotManuallyEnterPassword", false);
#endif // !BUILDFLAG(IS_CHROMEOS_LACROS)
-#if BUILDFLAG(IS_CHROMEOS)
- html_source->AddBoolean(
- "useSystemAuthenticationForPasswordManager",
- chromeos::features::IsPasswordManagerSystemAuthenticationEnabled());
-#endif
-
bool show_privacy_guide =
!chrome::ShouldDisplayManagedUi(profile) && !profile->IsChild();
html_source->AddBoolean("showPrivacyGuide", show_privacy_guide);
+ html_source->AddBoolean(
+ "enableExtendedSettingsDescriptions",
+ base::FeatureList::IsEnabled(features::kExtendedSettingsDescriptions));
+
html_source->AddBoolean("esbSettingsImprovementsEnabled",
base::FeatureList::IsEnabled(
safe_browsing::kEsbIphBubbleAndCollapseSettings));
@@ -433,6 +418,9 @@ SettingsUI::SettingsUI(content::WebUI* web_ui)
"importPasswordsFailuresSummary",
IDS_SETTINGS_PASSWORDS_IMPORT_FAILURES_SUMMARY);
plural_string_handler->AddLocalizedString(
+ "safetyCheckExtensionsReviewLabel",
+ IDS_SETTINGS_SAFETY_CHECK_REVIEW_EXTENSIONS);
+ plural_string_handler->AddLocalizedString(
"safetyCheckNotificationPermissionReviewHeaderLabel",
IDS_SETTINGS_SAFETY_CHECK_REVIEW_NOTIFICATION_PERMISSIONS_HEADER_LABEL);
plural_string_handler->AddLocalizedString(
@@ -470,6 +458,7 @@ SettingsUI::SettingsUI(content::WebUI* web_ui)
base::make_span(kSettingsSharedResources, kSettingsSharedResourcesSize));
#endif
+ webui::SetupChromeRefresh2023(html_source);
AddLocalizedStrings(html_source, profile, web_ui->GetWebContents());
ManagedUIHandler::Initialize(web_ui, html_source);
@@ -511,8 +500,28 @@ SettingsUI::SettingsUI(content::WebUI* web_ui)
base::FeatureList::IsEnabled(
content_settings::features::kSafetyCheckUnusedSitePermissions));
+ html_source->AddBoolean(
+ "safetyCheckExtensionsReviewEnabled",
+ base::FeatureList::IsEnabled(features::kSafetyCheckExtensions));
+
+ html_source->AddBoolean("enableSafetyHub",
+ base::FeatureList::IsEnabled(features::kSafetyHub));
+
// Performance
AddSettingsPageUIHandler(std::make_unique<PerformanceHandler>());
+ html_source->AddBoolean(
+ "isHighEfficiencyMultistateModeEnabled",
+ base::FeatureList::IsEnabled(
+ performance_manager::features::kHighEfficiencyMultistateMode));
+ html_source->AddBoolean(
+ "isDiscardExceptionsImprovementsEnabled",
+ base::FeatureList::IsEnabled(
+ performance_manager::features::kDiscardExceptionsImprovements));
+
+ html_source->AddBoolean(
+ "enablePermissionStorageAccessApi",
+ base::FeatureList::IsEnabled(
+ permissions::features::kPermissionStorageAccessAPI));
TryShowHatsSurveyWithTimeout();
}
diff --git a/chromium/chrome/browser/ui/webui/settings/settings_utils_mac.mm b/chromium/chrome/browser/ui/webui/settings/settings_utils_mac.mm
index 816f9de96e9..68c89f0688d 100644
--- a/chromium/chrome/browser/ui/webui/settings/settings_utils_mac.mm
+++ b/chromium/chrome/browser/ui/webui/settings/settings_utils_mac.mm
@@ -16,6 +16,10 @@
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
namespace {
void ValidateFontFamily(PrefService* prefs, const char* family_pref_name) {
// The native font settings dialog saved fonts by the font name, rather
@@ -25,10 +29,10 @@ void ValidateFontFamily(PrefService* prefs, const char* family_pref_name) {
// the webui settings window, we will fix the saved preference if necessary.
NSString* family_name =
base::SysUTF8ToNSString(prefs->GetString(family_pref_name));
- NSFont* font = [NSFont fontWithName:family_name size:[NSFont systemFontSize]];
+ NSFont* font = [NSFont fontWithName:family_name size:NSFont.systemFontSize];
if (font &&
- [[font familyName] caseInsensitiveCompare:family_name] != NSOrderedSame) {
- std::string new_family_name = base::SysNSStringToUTF8([font familyName]);
+ [font.familyName caseInsensitiveCompare:family_name] != NSOrderedSame) {
+ std::string new_family_name = base::SysNSStringToUTF8(font.familyName);
prefs->SetString(family_pref_name, new_family_name);
}
}
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 17b38fe2de7..b1429fa4f30 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
@@ -118,6 +118,8 @@ void AddCaptionSubpageStrings(content::WebUIDataSource* html_source) {
{"captionsLanguage", IDS_SETTINGS_CAPTIONS_LANGUAGE},
{"captionsManageLanguagesTitle",
IDS_SETTINGS_CAPTIONS_MANAGE_LANGUAGES_TITLE},
+ {"captionsManageLanguagesSubtitle",
+ IDS_SETTINGS_CAPTIONS_MANAGE_LANGUAGES_SUBTITLE},
{"captionsLiveTranslateTargetLanguage",
IDS_SETTINGS_CAPTIONS_LIVE_TRANSLATE_TARGET_LANGUAGE},
{"removeLanguageAriaLabel",
@@ -192,8 +194,10 @@ void AddSharedSyncPageStrings(content::WebUIDataSource* html_source) {
{"sync", IDS_SETTINGS_SYNC},
{"manageSyncedDataTitle",
IDS_SETTINGS_NEW_MANAGE_SYNCED_DATA_TITLE_UNIFIED_CONSENT},
+#if BUILDFLAG(IS_CHROMEOS_ASH)
{"manageSyncedDataSubtitle",
IDS_SETTINGS_NEW_MANAGE_SYNCED_DATA_SUBTITLE_UNIFIED_CONSENT},
+#endif
{"manageBrowserSyncedDataTitle",
IDS_SETTINGS_NEW_MANAGE_BROWSER_SYNCED_DATA_TITLE},
{"syncAdvancedDevicePageTitle",
@@ -216,6 +220,14 @@ void AddSharedSyncPageStrings(content::WebUIDataSource* html_source) {
};
html_source->AddLocalizedStrings(kLocalizedStrings);
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+ if (base::FeatureList::IsEnabled(syncer::kSyncChromeOSAppsToggleSharing)) {
+ html_source->AddLocalizedString(
+ "manageSyncedDataSubtitle",
+ IDS_SETTINGS_NEW_MANAGE_SYNCED_DATA_SUBTITLE_UNIFIED_CONSENT);
+ }
+#endif
+
std::string sync_dashboard_url =
google_util::AppendGoogleLocaleParam(
GURL(chrome::kSyncGoogleDashboardURL),
@@ -256,6 +268,9 @@ void AddSharedSyncPageStrings(content::WebUIDataSource* html_source) {
#elif BUILDFLAG(IS_CHROMEOS_LACROS)
html_source->AddBoolean("shouldShowLacrosSideBySideWarning",
ShouldShowLacrosSideBySideWarningInLacros());
+ html_source->AddBoolean(
+ "showSyncSettingsRevamp",
+ base::FeatureList::IsEnabled(syncer::kSyncChromeOSAppsToggleSharing));
#endif
html_source->AddString("syncErrorsHelpUrl", chrome::kSyncErrorsHelpURL);
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 b6da61c9f64..18e8059ce26 100644
--- a/chromium/chrome/browser/ui/webui/settings/site_settings_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/site_settings_handler.cc
@@ -23,13 +23,13 @@
#include "base/metrics/user_metrics.h"
#include "base/no_destructor.h"
#include "base/ranges/algorithm.h"
+#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/apps/app_service/app_service_proxy.h"
#include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
#include "chrome/browser/bluetooth/bluetooth_chooser_context_factory.h"
-#include "chrome/browser/browsing_data/access_context_audit_service_factory.h"
#include "chrome/browser/browsing_data/chrome_browsing_data_model_delegate.h"
#include "chrome/browser/browsing_data/cookies_tree_model.h"
#include "chrome/browser/browsing_topics/browsing_topics_service_factory.h"
@@ -40,7 +40,6 @@
#include "chrome/browser/hid/hid_chooser_context.h"
#include "chrome/browser/hid/hid_chooser_context_factory.h"
#include "chrome/browser/media/unified_autoplay_config.h"
-#include "chrome/browser/permissions/notification_permission_review_service_factory.h"
#include "chrome/browser/permissions/permission_decision_auto_blocker_factory.h"
#include "chrome/browser/privacy_sandbox/privacy_sandbox_service.h"
#include "chrome/browser/privacy_sandbox/privacy_sandbox_service_factory.h"
@@ -50,13 +49,18 @@
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/page_info/page_info_infobar_delegate.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/browser/ui/url_identity.h"
#include "chrome/browser/ui/webui/settings/recent_site_settings_helper.h"
#include "chrome/browser/ui/webui/settings/site_settings_helper.h"
#include "chrome/browser/usb/usb_chooser_context.h"
#include "chrome/browser/usb/usb_chooser_context_factory.h"
+#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chrome/common/pref_names.h"
+#include "chrome/common/url_constants.h"
#include "chrome/grit/generated_resources.h"
#include "components/browsing_data/content/browsing_data_model.h"
#include "components/browsing_topics/browsing_topics_service.h"
@@ -125,6 +129,9 @@ constexpr char kIsValidKey[] = "isValid";
constexpr char kReasonKey[] = "reason";
constexpr char kEffectiveTopLevelDomainPlus1Name[] = "etldPlus1";
+constexpr char kGroupingKey[] = "groupingKey";
+constexpr char kGroupingKeyEtldPrefix[] = "etld:";
+constexpr char kGroupingKeyOriginPrefix[] = "origin:";
constexpr char kOriginList[] = "origins";
constexpr char kNumCookies[] = "numCookies";
constexpr char kHasPermissionSettings[] = "hasPermissionSettings";
@@ -423,25 +430,26 @@ std::string GetCookieSettingDescription(Profile* profile) {
NOTREACHED();
}
-// Removes all nodes from |model| which match |origin| and |etld_plus1|. At
-// least one of |origin| or |etld_plus1| must be set. If only |origin| is set,
-// then unpartitioned storage for that origin is removed. If only |etld_plus1|
-// is set, then any unpartitioned storage which matches that etld + 1, or
-// partitioned storage where it is the partitioning site, is removed. If both
-// |origin| and |etld_plus1| is set, then only storage for |origin| partitioned
-// by |etld_plus1| is removed.
+// Removes all nodes from |model| which match |origin| and/or belong to
+// |grouping_key|. At least one of |origin| or |grouping_key| must be set. If
+// only |origin| is set, then unpartitioned storage for that origin is removed.
+// If only |grouping_key| is set, then any unpartitioned storage belonging to
+// that group, or partitioned storage where it is the partitioning site, is
+// removed. If both |origin| and |grouping_key| are set, then only storage for
+// |origin| partitioned by |grouping_key| is removed.
void RemoveMatchingNodes(CookiesTreeModel* model,
- absl::optional<std::string> origin,
- absl::optional<std::string> etld_plus1) {
- DCHECK(origin || etld_plus1);
+ absl::optional<url::Origin> origin,
+ absl::optional<GroupingKey> grouping_key) {
+ DCHECK(origin || grouping_key);
+ absl::optional<std::string> group_etld_plus1 =
+ grouping_key.has_value() ? grouping_key->GetEtldPlusOne() : absl::nullopt;
std::vector<CookieTreeNode*> nodes_to_delete;
for (const auto& host_node : model->GetRoot()->children()) {
bool origin_matches =
- origin &&
- *origin == host_node->GetDetailedInfo().origin.GetURL().spec();
+ origin.has_value() && *origin == host_node->GetDetailedInfo().origin;
- if (origin && !origin_matches) {
+ if (origin.has_value() && !origin_matches) {
// If the origin is set, host nodes which do not match that origin cannot
// contain storage targeted for removal.
continue;
@@ -452,17 +460,18 @@ void RemoveMatchingNodes(CookiesTreeModel* model,
base::UTF16ToUTF8(host_node->GetTitle()),
net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
- bool etld_plus1_matches = etld_plus1 && *etld_plus1 == host_node_etld_plus1;
+ bool group_etld_plus1_matches = group_etld_plus1.has_value() &&
+ *group_etld_plus1 == host_node_etld_plus1;
for (const auto& storage_type_node : host_node->children()) {
if (storage_type_node->GetDetailedInfo().node_type !=
CookieTreeNode::DetailedInfo::TYPE_COOKIES) {
- // Non cookie storage cannot (currently) be partitioned.
- if (origin && etld_plus1) {
+ // Non-cookie storage cannot (currently) be partitioned.
+ if (origin.has_value() && group_etld_plus1.has_value()) {
continue;
}
- if (origin_matches || etld_plus1_matches) {
+ if (origin_matches || group_etld_plus1_matches) {
nodes_to_delete.push_back(storage_type_node.get());
continue;
}
@@ -473,8 +482,8 @@ void RemoveMatchingNodes(CookiesTreeModel* model,
for (const auto& cookie_node : storage_type_node->children()) {
const auto& cookie = cookie_node->GetDetailedInfo().cookie;
if (!cookie->IsPartitioned() &&
- (origin_matches || etld_plus1_matches) &&
- (!origin || !etld_plus1)) {
+ (origin_matches || group_etld_plus1_matches) &&
+ (!origin.has_value() || !group_etld_plus1.has_value())) {
nodes_to_delete.push_back(cookie_node.get());
continue;
}
@@ -484,9 +493,10 @@ void RemoveMatchingNodes(CookiesTreeModel* model,
// If an origin has been set, it must match the origin of the
// current node, which means it can be ignored.
- DCHECK(!origin || origin_matches);
+ DCHECK(!origin.has_value() || origin_matches);
- if (etld_plus1 && partition_site == *etld_plus1) {
+ if (group_etld_plus1.has_value() &&
+ partition_site == *group_etld_plus1) {
nodes_to_delete.push_back(cookie_node.get());
}
}
@@ -580,7 +590,7 @@ void ConvertSiteGroupMapToList(
for (const auto& entry : site_group_map) {
base::Value::Dict site_group;
const GroupingKey& grouping_key = entry.first;
- site_group.Set(kEffectiveTopLevelDomainPlus1Name, grouping_key.Serialize());
+ site_group.Set(kGroupingKey, grouping_key.Serialize());
// eTLD+1 is the effective top level domain + 1.
absl::optional<std::string> etld_plus1 = grouping_key.GetEtldPlusOne();
@@ -592,6 +602,9 @@ void ConvertSiteGroupMapToList(
: site_settings::GetDisplayNameForGURL(
profile, group_origin->GetURL(),
/*hostname_only=*/false));
+ if (etld_plus1.has_value()) {
+ site_group.Set(kEffectiveTopLevelDomainPlus1Name, *etld_plus1);
+ }
bool has_installed_pwa = false;
base::Value::List origin_list;
@@ -606,7 +619,7 @@ void ConvertSiteGroupMapToList(
origin_object.Set("isPartitioned", is_partitioned);
origin_object.Set("engagement",
engagement_service->GetScore(origin.GetURL()));
- origin_object.Set("usage", 0);
+ origin_object.Set("usage", 0.0);
origin_object.Set(kNumCookies, 0);
bool is_installed = installed_origins.contains(origin);
@@ -633,32 +646,22 @@ void ConvertSiteGroupMapToList(
}
}
-bool ShouldAddToNotificationPermissionReviewList(
- site_engagement::SiteEngagementService* service,
- GURL url,
- int notification_count) {
- // The notification permission should be added to the list if one of the
- // criteria below holds:
- // - Site engagement level is NONE OR MINIMAL and average daily notification
- // count is more than 0.
- // - Site engamment level is LOW and average daily notification count is
- // more than 3. Otherwise, the notification permission should not be added
- // to review list.
- double score = service->GetScore(url);
- int low_engagement_notification_limit =
- features::kSafetyCheckNotificationPermissionsLowEnagementLimit.Get();
- bool is_low_engagement =
- !site_engagement::SiteEngagementService::IsEngagementAtLeast(
- score, blink::mojom::EngagementLevel::MEDIUM) &&
- notification_count > low_engagement_notification_limit;
- int min_engagement_notification_limit =
- features::kSafetyCheckNotificationPermissionsMinEnagementLimit.Get();
- bool is_minimal_engagement =
- !site_engagement::SiteEngagementService::IsEngagementAtLeast(
- score, blink::mojom::EngagementLevel::LOW) &&
- notification_count > min_engagement_notification_limit;
-
- return is_minimal_engagement || is_low_engagement;
+base::Value::Dict CreateZoomLevelException(
+ const std::string& host_or_spec,
+ const std::string& origin_for_favicon,
+ const std::string& display_name,
+ double zoom) {
+ base::Value::Dict exception;
+ exception.Set(site_settings::kHostOrSpec, host_or_spec);
+ exception.Set(site_settings::kOriginForFavicon, origin_for_favicon);
+ exception.Set(site_settings::kDisplayName, display_name);
+
+ // Calculate the zoom percent from the factor. Round up to the nearest
+ // whole number.
+ int zoom_percent =
+ static_cast<int>(blink::PageZoomLevelToZoomFactor(zoom) * 100 + 0.5);
+ exception.Set(kZoom, base::FormatPercent(zoom_percent));
+ return exception;
}
} // namespace
@@ -676,6 +679,17 @@ GroupingKey GroupingKey::CreateFromEtldPlus1(const std::string& etld_plus1) {
return GroupingKey(etld_plus1);
}
+// static
+GroupingKey GroupingKey::Deserialize(const std::string& serialized) {
+ if (base::StartsWith(serialized, kGroupingKeyEtldPrefix)) {
+ return GroupingKey::CreateFromEtldPlus1(
+ serialized.substr(sizeof(kGroupingKeyEtldPrefix) - 1));
+ }
+ CHECK(base::StartsWith(serialized, kGroupingKeyOriginPrefix));
+ GURL url(serialized.substr(sizeof(kGroupingKeyOriginPrefix) - 1));
+ return GroupingKey::Create(url::Origin::Create(url));
+}
+
GroupingKey::GroupingKey(const absl::variant<std::string, url::Origin>& value)
: value_(value) {}
@@ -684,11 +698,15 @@ GroupingKey& GroupingKey::operator=(const GroupingKey& other) = default;
GroupingKey::~GroupingKey() = default;
std::string GroupingKey::Serialize() const {
- return absl::visit(
- base::Overloaded{
- [](const std::string& etld_plus1) { return etld_plus1; },
- [](const url::Origin& origin) { return origin.GetURL().spec(); }},
- value_);
+ return absl::visit(base::Overloaded{[](const std::string& etld_plus1) {
+ return kGroupingKeyEtldPrefix +
+ etld_plus1;
+ },
+ [](const url::Origin& origin) {
+ return kGroupingKeyOriginPrefix +
+ origin.GetURL().spec();
+ }},
+ value_);
}
absl::optional<std::string> GroupingKey::GetEtldPlusOne() const {
@@ -709,7 +727,7 @@ url::Origin GroupingKey::ToOrigin() const {
return absl::visit(
base::Overloaded{[](const std::string& etld_plus1) {
return ConvertEtldToOrigin(etld_plus1,
- /*secure=*/true);
+ /*secure=*/false);
},
[](const url::Origin& origin) { return origin; }},
value_);
@@ -799,11 +817,6 @@ void SiteSettingsHandler::RegisterMessages() {
base::BindRepeating(&SiteSettingsHandler::HandleGetChooserExceptionList,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
- "getNotificationPermissionReview",
- base::BindRepeating(
- &SiteSettingsHandler::HandleGetNotificationPermissionReviewList,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback(
"getOriginPermissions",
base::BindRepeating(&SiteSettingsHandler::HandleGetOriginPermissions,
base::Unretained(this)));
@@ -827,33 +840,6 @@ void SiteSettingsHandler::RegisterMessages() {
&SiteSettingsHandler::HandleResetChooserExceptionForSite,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
- "ignoreNotificationPermissionReviewForOrigins",
- base::BindRepeating(
- &SiteSettingsHandler::
- HandleIgnoreOriginsForNotificationPermissionReview,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback(
- "resetNotificationPermissionForOrigins",
- base::BindRepeating(
- &SiteSettingsHandler::HandleResetNotificationPermissionForOrigins,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback(
- "blockNotificationPermissionForOrigins",
- base::BindRepeating(
- &SiteSettingsHandler::HandleBlockNotificationPermissionForOrigins,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback(
- "allowNotificationPermissionForOrigins",
- base::BindRepeating(
- &SiteSettingsHandler::HandleAllowNotificationPermissionForOrigins,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback(
- "undoIgnoreNotificationPermissionReviewForOrigins",
- base::BindRepeating(
- &SiteSettingsHandler::
- HandleUndoIgnoreOriginsForNotificationPermissionReview,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback(
"isOriginValid",
base::BindRepeating(&SiteSettingsHandler::HandleIsOriginValid,
base::Unretained(this)));
@@ -882,9 +868,9 @@ void SiteSettingsHandler::RegisterMessages() {
base::BindRepeating(&SiteSettingsHandler::HandleFetchBlockAutoplayStatus,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
- "clearEtldPlus1DataAndCookies",
+ "clearSiteGroupDataAndCookies",
base::BindRepeating(
- &SiteSettingsHandler::HandleClearEtldPlus1DataAndCookies,
+ &SiteSettingsHandler::HandleClearSiteGroupDataAndCookies,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"recordAction",
@@ -906,15 +892,22 @@ void SiteSettingsHandler::OnJavascriptAllowed() {
ObserveSourcesForProfile(primary_otr_profile);
}
- // Here we only subscribe to the HostZoomMap for the default storage partition
- // since we don't allow the user to manage the zoom levels for apps.
- // We're only interested in zoom-levels that are persisted, since the user
- // is given the opportunity to view/delete these in the content-settings page.
- host_zoom_map_subscription_ =
+ // Listen for zoom changes in the default StoragePartition and the primary
+ // StoragePartition of all installed Isolated Web Apps.
+ auto zoom_changed_callback = base::BindRepeating(
+ &SiteSettingsHandler::OnZoomLevelChanged, base::Unretained(this));
+ host_zoom_map_subscriptions_.push_back(
content::HostZoomMap::GetDefaultForBrowserContext(profile_)
- ->AddZoomLevelChangedCallback(
- base::BindRepeating(&SiteSettingsHandler::OnZoomLevelChanged,
- base::Unretained(this)));
+ ->AddZoomLevelChangedCallback(zoom_changed_callback));
+ for (const web_app::IsolatedWebAppUrlInfo& iwa_url_info :
+ site_settings::GetInstalledIsolatedWebApps(profile_)) {
+ content::StoragePartition* iwa_storage_partition =
+ profile_->GetStoragePartition(
+ iwa_url_info.storage_partition_config(profile_));
+ host_zoom_map_subscriptions_.push_back(
+ content::HostZoomMap::GetForStoragePartition(iwa_storage_partition)
+ ->AddZoomLevelChangedCallback(zoom_changed_callback));
+ }
pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>();
pref_change_registrar_->Init(profile_->GetPrefs());
@@ -935,7 +928,7 @@ void SiteSettingsHandler::OnJavascriptAllowed() {
void SiteSettingsHandler::OnJavascriptDisallowed() {
observations_.RemoveAllObservations();
chooser_observations_.RemoveAllObservations();
- host_zoom_map_subscription_ = {};
+ host_zoom_map_subscriptions_.clear();
pref_change_registrar_->Remove(prefs::kBlockAutoplayEnabled);
pref_change_registrar_->Remove(prefs::kCookieControlsMode);
observed_profiles_.RemoveAllObservations();
@@ -1009,7 +1002,8 @@ void SiteSettingsHandler::OnGetUsageInfo() {
for (const BrowsingDataModel::BrowsingDataEntryView& entry :
*browsing_data_model_) {
- if (*entry.primary_host != usage_hostname) {
+ auto usage_origin = url::Origin::Create(GURL(usage_origin_));
+ if (!entry.Matches(usage_origin)) {
continue;
}
size += entry.data_details->storage_size;
@@ -1131,8 +1125,7 @@ void SiteSettingsHandler::HandleGetFpsMembershipLabel(
void SiteSettingsHandler::HandleClearUnpartitionedUsage(
const base::Value::List& args) {
CHECK_EQ(1U, args.size());
- const std::string& origin_string = args[0].GetString();
- auto origin = url::Origin::Create(GURL(origin_string));
+ auto origin = url::Origin::Create(GURL(args[0].GetString()));
if (origin.opaque())
return;
AllowJavascript();
@@ -1143,7 +1136,7 @@ void SiteSettingsHandler::HandleClearUnpartitionedUsage(
DCHECK(browsing_data_model_);
DCHECK(cookies_tree_model_);
- RemoveMatchingNodes(cookies_tree_model_.get(), origin_string, absl::nullopt);
+ RemoveMatchingNodes(cookies_tree_model_.get(), origin, absl::nullopt);
// The scheme for some sites detail page is http on
// chrome://settings/content/all. Cookies or site data might not cleared if
@@ -1162,8 +1155,7 @@ void SiteSettingsHandler::HandleClearUnpartitionedUsage(
// avoid confusion when cookies already exist when refreshing clear site
// data page. Notes: this also means HTTPS sites cookie will be cleared when
// user clear HTTP scheme Cookie.
- RemoveMatchingNodes(cookies_tree_model_.get(), https_origin.GetURL().spec(),
- absl::nullopt);
+ RemoveMatchingNodes(cookies_tree_model_.get(), https_origin, absl::nullopt);
affected_origins.emplace_back(https_origin);
}
@@ -1173,10 +1165,10 @@ void SiteSettingsHandler::HandleClearUnpartitionedUsage(
void SiteSettingsHandler::HandleClearPartitionedUsage(
const base::Value::List& args) {
CHECK_EQ(2U, args.size());
- const std::string& origin = args[0].GetString();
- const std::string& etld_plus1 = args[1].GetString();
+ auto origin = url::Origin::Create(GURL(args[0].GetString()));
+ auto grouping_key = GroupingKey::Deserialize(args[1].GetString());
- RemoveMatchingNodes(cookies_tree_model_.get(), origin, etld_plus1);
+ RemoveMatchingNodes(cookies_tree_model_.get(), origin, grouping_key);
}
void SiteSettingsHandler::HandleSetDefaultValueForContentType(
@@ -1330,7 +1322,6 @@ void SiteSettingsHandler::HandleGetCategoryList(const base::Value::List& args) {
CHECK_EQ(2U, args.size());
std::string callback_id = args[0].GetString();
- GURL origin(args[1].GetString());
base::Value::List result;
for (ContentSettingsType content_type :
@@ -1413,15 +1404,18 @@ base::Value::List SiteSettingsHandler::PopulateCookiesAndUsageData(
base::Value::Dict& site_group = item.GetDict();
base::Value::List& origin_list = *site_group.FindList(kOriginList);
int cookie_num = 0;
- const std::string& etld_plus1 =
- *site_group.FindString(kEffectiveTopLevelDomainPlus1Name);
- const auto& etld_plus1_cookie_num_it =
- host_cookie_map.find({etld_plus1, absl::nullopt});
+ auto grouping_key =
+ GroupingKey::Deserialize(*site_group.FindString(kGroupingKey));
// Add the number of eTLD+1 scoped cookies.
- if (etld_plus1_cookie_num_it != host_cookie_map.end()) {
- cookie_num = etld_plus1_cookie_num_it->second;
+ absl::optional<std::string> etld_plus1 = grouping_key.GetEtldPlusOne();
+ if (etld_plus1.has_value()) {
+ const auto& etld_plus1_cookie_num_it =
+ std::as_const(host_cookie_map).find({*etld_plus1, absl::nullopt});
+ if (etld_plus1_cookie_num_it != host_cookie_map.end()) {
+ cookie_num += etld_plus1_cookie_num_it->second;
+ }
}
- // Iterate over the origins for the ETLD+1, and set their usage and cookie
+ // Iterate over the origins for the group, and set their usage and cookie
// numbers.
for (base::Value& value : origin_list) {
base::Value::Dict& origin_info = value.GetDict();
@@ -1436,12 +1430,10 @@ base::Value::List SiteSettingsHandler::PopulateCookiesAndUsageData(
origin_info.Set("usage", static_cast<double>(size_info_it->second));
}
const auto& host_cookie_num_it = host_cookie_map.find(
- {origin.host(),
- (is_partitioned ? absl::optional<std::string>(etld_plus1)
- : absl::nullopt)});
+ {origin.host(), (is_partitioned ? etld_plus1 : absl::nullopt)});
if (host_cookie_num_it != host_cookie_map.end()) {
origin_info.Set(kNumCookies, host_cookie_num_it->second);
- // Add cookies numbers for origins that isn't an eTLD+1.
+ // Add cookies numbers for origins that aren't an eTLD+1.
if (origin.host() != etld_plus1 || is_partitioned) {
cookie_num += host_cookie_num_it->second;
}
@@ -1547,9 +1539,9 @@ void SiteSettingsHandler::HandleGetOriginPermissions(
HostContentSettingsMap* map =
HostContentSettingsMapFactory::GetForProfile(profile_);
- std::string source_string, display_name;
+ std::string source_string;
ContentSetting content_setting = site_settings::GetContentSettingForOrigin(
- profile_, map, origin_url, content_type, &source_string, &display_name);
+ profile_, map, origin_url, content_type, &source_string);
std::string content_setting_string =
content_settings::ContentSettingToString(content_setting);
@@ -1558,36 +1550,30 @@ void SiteSettingsHandler::HandleGetOriginPermissions(
raw_site_exception.Set(site_settings::kIncognito,
profile_->IsOffTheRecord());
raw_site_exception.Set(site_settings::kOrigin, origin);
- absl::optional<std::string> extension_name =
- site_settings::GetExtensionDisplayName(profile_, origin_url);
- if (extension_name.has_value()) {
- raw_site_exception.Set(site_settings::kExtensionNameWithId,
- l10n_util::GetStringFUTF8(
- IDS_SETTINGS_EXTENSION_DISPLAY_NAME,
- base::UTF8ToUTF16(extension_name.value()),
- base::UTF8ToUTF16(origin_url.host_piece())));
- }
- raw_site_exception.Set(site_settings::kDisplayName, display_name);
raw_site_exception.Set(site_settings::kSetting, content_setting_string);
raw_site_exception.Set(site_settings::kSource, source_string);
+ UrlIdentity identity = site_settings::GetUrlIdentityForGURL(
+ profile_, origin_url, /*hostname_only=*/false);
+ std::string display_name;
+ if (identity.type == UrlIdentity::Type::kChromeExtension ||
+ identity.type == UrlIdentity::Type::kIsolatedWebApp) {
+ // Append " (ID: <id>)" to extensions and IWA names as the user could have
+ // multiple extensions/IWAs installed with the same name.
+ display_name = l10n_util::GetStringFUTF8(
+ IDS_SETTINGS_EXTENSION_OR_APP_DISPLAY_NAME, identity.name,
+ base::UTF8ToUTF16(origin_url.host_piece()));
+ } else {
+ display_name = base::UTF16ToUTF8(identity.name);
+ }
+ raw_site_exception.Set(site_settings::kDisplayName, display_name);
+
exceptions.Append(std::move(raw_site_exception));
}
ResolveJavascriptCallback(callback_id, exceptions);
}
-void SiteSettingsHandler::HandleGetNotificationPermissionReviewList(
- const base::Value::List& args) {
- AllowJavascript();
-
- const base::Value& callback_id = args[0];
-
- base::Value::List result = PopulateNotificationPermissionReviewData();
-
- ResolveJavascriptCallback(callback_id, base::Value(std::move(result)));
-}
-
void SiteSettingsHandler::HandleGetFileSystemGrants(
const base::Value::List& args) {
CHECK_EQ(1U, args.size());
@@ -1728,6 +1714,10 @@ void SiteSettingsHandler::HandleSetOriginPermissions(
"SoundContentSetting.UnmuteBy.SiteSettings"));
}
}
+
+ permissions::PermissionUmaUtil::RecordPermissionRegrantForUnusedSites(
+ origin, content_type, permissions::PermissionSourceUI::SITE_SETTINGS,
+ profile_, base::Time::Now());
}
// Show an infobar reminding the user to reload tabs where their site
@@ -1894,104 +1884,13 @@ void SiteSettingsHandler::HandleResetChooserExceptionForSite(
site_settings::ChooserTypeFromGroupName(chooser_type_str);
CHECK(chooser_type);
- const std::string& origin_str = args[1].GetString();
- GURL origin(origin_str);
- CHECK(origin.is_valid());
+ auto origin_url = GURL(args[1].GetString());
+ CHECK(origin_url.is_valid());
+ auto origin = url::Origin::Create(origin_url);
permissions::ObjectPermissionContextBase* chooser_context =
chooser_type->get_context(profile_);
- chooser_context->RevokeObjectPermission(url::Origin::Create(origin), args[2]);
-}
-
-void SiteSettingsHandler::HandleIgnoreOriginsForNotificationPermissionReview(
- const base::Value::List& args) {
- CHECK_EQ(1U, args.size());
- const base::Value::List& origins = args[0].GetList();
-
- auto* service =
- NotificationPermissionsReviewServiceFactory::GetForProfile(profile_);
- DCHECK(service);
-
- for (const auto& origin : origins) {
- const ContentSettingsPattern primary_pattern =
- ContentSettingsPattern::FromString(origin.GetString());
- service->AddPatternToNotificationPermissionReviewBlocklist(
- primary_pattern, ContentSettingsPattern::Wildcard());
- }
-
- SendNotificationPermissionReviewList();
-}
-
-void SiteSettingsHandler::HandleResetNotificationPermissionForOrigins(
- const base::Value::List& args) {
- CHECK_EQ(1U, args.size());
-
- const base::Value::List& origins = args[0].GetList();
-
- HostContentSettingsMap* map =
- HostContentSettingsMapFactory::GetForProfile(profile_);
-
- for (const auto& origin : origins) {
- map->SetContentSettingCustomScope(
- ContentSettingsPattern::FromString(origin.GetString()),
- ContentSettingsPattern::Wildcard(), ContentSettingsType::NOTIFICATIONS,
- CONTENT_SETTING_DEFAULT);
- }
-
- SendNotificationPermissionReviewList();
-}
-
-void SiteSettingsHandler::HandleBlockNotificationPermissionForOrigins(
- const base::Value::List& args) {
- CHECK_EQ(1U, args.size());
- const base::Value::List& origins = args[0].GetList();
-
- HostContentSettingsMap* map =
- HostContentSettingsMapFactory::GetForProfile(profile_);
- for (const auto& origin : origins) {
- map->SetContentSettingCustomScope(
- ContentSettingsPattern::FromString(origin.GetString()),
- ContentSettingsPattern::Wildcard(), ContentSettingsType::NOTIFICATIONS,
- CONTENT_SETTING_BLOCK);
- }
-
- SendNotificationPermissionReviewList();
-}
-
-void SiteSettingsHandler::HandleAllowNotificationPermissionForOrigins(
- const base::Value::List& args) {
- CHECK_EQ(1U, args.size());
- const base::Value::List& origins = args[0].GetList();
-
- HostContentSettingsMap* map =
- HostContentSettingsMapFactory::GetForProfile(profile_);
-
- for (const auto& origin : origins) {
- map->SetContentSettingCustomScope(
- ContentSettingsPattern::FromString(origin.GetString()),
- ContentSettingsPattern::Wildcard(), ContentSettingsType::NOTIFICATIONS,
- CONTENT_SETTING_ALLOW);
- }
-
- SendNotificationPermissionReviewList();
-}
-
-void SiteSettingsHandler::
- HandleUndoIgnoreOriginsForNotificationPermissionReview(
- const base::Value::List& args) {
- CHECK_EQ(1U, args.size());
- const base::Value::List& origins = args[0].GetList();
- auto* service =
- NotificationPermissionsReviewServiceFactory::GetForProfile(profile_);
- DCHECK(service);
-
- for (const auto& origin : origins) {
- const ContentSettingsPattern& primary_pattern =
- ContentSettingsPattern::FromString(origin.GetString());
- service->RemovePatternFromNotificationPermissionReviewBlocklist(
- primary_pattern, ContentSettingsPattern::Wildcard());
- }
- SendNotificationPermissionReviewList();
+ chooser_context->RevokeObjectPermission(origin, args[2].GetDict());
}
void SiteSettingsHandler::HandleIsOriginValid(const base::Value::List& args) {
@@ -2045,6 +1944,40 @@ void SiteSettingsHandler::SendZoomLevels() {
base::Value::List zoom_levels_exceptions;
+ // Show any non-default Isolated Web App zoom levels at the top of the page.
+ auto* web_app_provider = web_app::WebAppProvider::GetForWebApps(profile_);
+ if (web_app_provider) {
+ const web_app::WebAppRegistrar& registrar =
+ web_app_provider->registrar_unsafe();
+ for (const web_app::IsolatedWebAppUrlInfo& iwa_url_info :
+ site_settings::GetInstalledIsolatedWebApps(profile_)) {
+ content::StoragePartition* iwa_storage_partition =
+ profile_->GetStoragePartition(
+ iwa_url_info.storage_partition_config(profile_));
+ auto* host_zoom_map =
+ content::HostZoomMap::GetForStoragePartition(iwa_storage_partition);
+ double iwa_zoom = host_zoom_map->GetZoomLevelForHostAndScheme(
+ chrome::kIsolatedAppScheme, iwa_url_info.origin().host());
+ if (iwa_zoom == host_zoom_map->GetDefaultZoomLevel()) {
+ continue;
+ }
+
+ zoom_levels_exceptions.Append(CreateZoomLevelException(
+ iwa_url_info.origin().Serialize(), iwa_url_info.origin().Serialize(),
+ registrar.GetAppShortName(iwa_url_info.app_id()), iwa_zoom));
+ }
+
+ // Sort by app name.
+ std::sort(zoom_levels_exceptions.begin(), zoom_levels_exceptions.end(),
+ [](const base::Value& a, const base::Value& b) {
+ const std::string& name_a =
+ *a.GetDict().FindString(site_settings::kDisplayName);
+ const std::string& name_b =
+ *b.GetDict().FindString(site_settings::kDisplayName);
+ return name_a < name_b;
+ });
+ }
+
content::HostZoomMap* host_zoom_map =
content::HostZoomMap::GetDefaultForBrowserContext(profile_);
content::HostZoomMap::ZoomLevelVector zoom_levels(
@@ -2059,32 +1992,35 @@ void SiteSettingsHandler::SendZoomLevels() {
const content::HostZoomMap::ZoomLevelChange& b) {
return a.host == b.host ? a.scheme < b.scheme : a.host < b.host;
});
+ GURL unreachable_web_data_url(content::kUnreachableWebDataURL);
for (const auto& zoom_level : zoom_levels) {
base::Value::Dict exception;
switch (zoom_level.mode) {
case content::HostZoomMap::ZOOM_CHANGED_FOR_HOST: {
- std::string host = zoom_level.host;
- if (host == content::kUnreachableWebDataURL) {
- host =
+ std::string host_or_spec = zoom_level.host;
+ std::string origin_for_favicon = host_or_spec;
+ std::string display_name = host_or_spec;
+
+ if (host_or_spec == unreachable_web_data_url.host()) {
+ display_name =
l10n_util::GetStringUTF8(IDS_ZOOMLEVELS_CHROME_ERROR_PAGES_LABEL);
}
- exception.Set(site_settings::kOrigin, host);
- std::string display_name = host;
- std::string origin_for_favicon = host;
// As an optimization, only check hosts that could be an extension.
- if (crx_file::id_util::IdIsValid(host)) {
+ if (crx_file::id_util::IdIsValid(host_or_spec)) {
// Look up the host as an extension, if found then it is an extension.
const extensions::Extension* extension =
extension_registry->GetExtensionById(
- host, extensions::ExtensionRegistry::EVERYTHING);
+ host_or_spec, extensions::ExtensionRegistry::EVERYTHING);
if (extension) {
origin_for_favicon = extension->url().spec();
display_name = extension->name();
}
}
- exception.Set(site_settings::kDisplayName, display_name);
- exception.Set(site_settings::kOriginForFavicon, origin_for_favicon);
+
+ zoom_levels_exceptions.Append(
+ CreateZoomLevelException(host_or_spec, origin_for_favicon,
+ display_name, zoom_level.zoom_level));
break;
}
case content::HostZoomMap::ZOOM_CHANGED_FOR_SCHEME_AND_HOST:
@@ -2094,23 +2030,6 @@ void SiteSettingsHandler::SendZoomLevels() {
case content::HostZoomMap::ZOOM_CHANGED_TEMPORARY_ZOOM:
NOTREACHED();
}
-
- std::string setting_string =
- content_settings::ContentSettingToString(CONTENT_SETTING_DEFAULT);
- DCHECK(!setting_string.empty());
-
- exception.Set(site_settings::kSetting, setting_string);
-
- // Calculate the zoom percent from the factor. Round up to the nearest whole
- // number.
- int zoom_percent = static_cast<int>(
- blink::PageZoomLevelToZoomFactor(zoom_level.zoom_level) * 100 + 0.5);
- exception.Set(kZoom, base::FormatPercent(zoom_percent));
- exception.Set(site_settings::kSource,
- site_settings::SiteSettingSourceToString(
- site_settings::SiteSettingSource::kPreference));
- // Append the new entry to the list and map.
- zoom_levels_exceptions.Append(std::move(exception));
}
FireWebUIListener("onZoomLevelsChanged", zoom_levels_exceptions);
@@ -2119,17 +2038,29 @@ void SiteSettingsHandler::SendZoomLevels() {
void SiteSettingsHandler::HandleRemoveZoomLevel(const base::Value::List& args) {
CHECK_EQ(1U, args.size());
- std::string origin = args[0].GetString();
+ std::string host_or_spec = args[0].GetString();
- if (origin ==
- l10n_util::GetStringUTF8(IDS_ZOOMLEVELS_CHROME_ERROR_PAGES_LABEL)) {
- origin = content::kUnreachableWebDataURL;
+ GURL url(host_or_spec);
+ if (url.is_valid() && url.scheme() == chrome::kIsolatedAppScheme) {
+ base::expected<web_app::IsolatedWebAppUrlInfo, std::string> iwa_url_info =
+ web_app::IsolatedWebAppUrlInfo::Create(url);
+ if (!iwa_url_info.has_value()) {
+ return;
+ }
+ content::StoragePartition* iwa_storage_partition =
+ profile_->GetStoragePartition(
+ iwa_url_info->storage_partition_config(profile_));
+ auto* host_zoom_map =
+ content::HostZoomMap::GetForStoragePartition(iwa_storage_partition);
+ double default_level = host_zoom_map->GetDefaultZoomLevel();
+ host_zoom_map->SetZoomLevelForHost(url.host(), default_level);
+ return;
}
- content::HostZoomMap* host_zoom_map;
- host_zoom_map = content::HostZoomMap::GetDefaultForBrowserContext(profile_);
+ content::HostZoomMap* host_zoom_map =
+ content::HostZoomMap::GetDefaultForBrowserContext(profile_);
double default_level = host_zoom_map->GetDefaultZoomLevel();
- host_zoom_map->SetZoomLevelForHost(origin, default_level);
+ host_zoom_map->SetZoomLevelForHost(host_or_spec, default_level);
}
void SiteSettingsHandler::HandleFetchBlockAutoplayStatus(
@@ -2316,10 +2247,14 @@ void SiteSettingsHandler::GetOriginStorage(
if (entry.data_details->storage_size == 0)
continue;
- // Convert the primary host to an HTTPS url to match expecations for this
- // code.
- url::Origin origin =
- ConvertEtldToOrigin(*entry.primary_host, /*secure=*/true);
+ url::Origin origin = absl::visit(
+ base::Overloaded{[](const std::string& host) {
+ // Convert the primary host to an HTTPS url to match
+ // expecations for this code.
+ return ConvertEtldToOrigin(host, /*secure=*/true);
+ },
+ [](const url::Origin& origin) { return origin; }},
+ *entry.data_owner);
UpdateDataFromModel(all_sites_map, origin_size_map, origin,
entry.data_details->storage_size);
}
@@ -2371,16 +2306,15 @@ void SiteSettingsHandler::GetHostCookies(
}
}
-void SiteSettingsHandler::HandleClearEtldPlus1DataAndCookies(
+void SiteSettingsHandler::HandleClearSiteGroupDataAndCookies(
const base::Value::List& args) {
CHECK_EQ(1U, args.size());
- const std::string& etld_plus1 = args[0].GetString();
- auto grouping_key = GroupingKey::CreateFromEtldPlus1(etld_plus1);
+ auto grouping_key = GroupingKey::Deserialize(args[0].GetString());
AllowJavascript();
- RemoveMatchingNodes(cookies_tree_model_.get(), absl::nullopt, etld_plus1);
+ RemoveMatchingNodes(cookies_tree_model_.get(), absl::nullopt, grouping_key);
- // Retrieve all of the origin entries grouped under this eTLD + 1.
+ // Retrieve all of the origin entries grouped under this group.
std::vector<url::Origin> affected_origins;
for (const auto& origin_is_partitioned : all_sites_map_[grouping_key]) {
// Ignore entries which are partitioned, as no non-cookie tree storage is
@@ -2400,8 +2334,10 @@ void SiteSettingsHandler::HandleClearEtldPlus1DataAndCookies(
// if the existing entry was https, otherwise a new http entry would be
// created for the placeholder. Hence, we need only additionally include the
// HTTPS version of the eTLD+1 as an origin.
- affected_origins.emplace_back(
- ConvertEtldToOrigin(etld_plus1, /*secure=*/true));
+ if (auto etld_plus1 = grouping_key.GetEtldPlusOne(); etld_plus1.has_value()) {
+ affected_origins.emplace_back(
+ ConvertEtldToOrigin(*etld_plus1, /*secure=*/true));
+ }
RemoveNonTreeModelData(affected_origins);
}
@@ -2532,61 +2468,6 @@ void SiteSettingsHandler::SendCookieSettingDescription() {
base::Value(GetCookieSettingDescription(profile_)));
}
-base::Value::List
-SiteSettingsHandler::PopulateNotificationPermissionReviewData() {
- base::Value::List result;
- if (!base::FeatureList::IsEnabled(
- features::kSafetyCheckNotificationPermissions))
- return result;
-
- auto* service =
- NotificationPermissionsReviewServiceFactory::GetForProfile(profile_);
- if (!service)
- return result;
-
- auto notification_permissions = service->GetNotificationSiteListForReview();
-
- site_engagement::SiteEngagementService* engagement_service =
- site_engagement::SiteEngagementService::Get(profile_);
-
- // Sort notification permissions by their priority for surfacing to the user.
- auto notification_permission_ordering =
- [](const permissions::NotificationPermissions& left,
- const permissions::NotificationPermissions& right) {
- return left.notification_count > right.notification_count;
- };
- std::sort(notification_permissions.begin(), notification_permissions.end(),
- notification_permission_ordering);
-
- for (const auto& notification_permission : notification_permissions) {
- // Converting primary pattern to GURL should always be valid, since
- // Notification Permission Review list only contains single origins. Those
- // are filtered in
- // NotificationPermissionsReviewService::GetNotificationSiteListForReview.
- GURL url = GURL(notification_permission.primary_pattern.ToString());
- DCHECK(url.is_valid());
- if (!ShouldAddToNotificationPermissionReviewList(
- engagement_service, url,
- notification_permission.notification_count)) {
- continue;
- }
-
- base::Value::Dict permission;
- permission.Set(site_settings::kOrigin,
- notification_permission.primary_pattern.ToString());
-
- std::string notification_info_string =
- base::UTF16ToUTF8(l10n_util::GetPluralStringFUTF16(
- IDS_SETTINGS_SAFETY_CHECK_REVIEW_NOTIFICATION_PERMISSIONS_COUNT_LABEL,
- notification_permission.notification_count));
- permission.Set(site_settings::kNotificationInfoString,
- notification_info_string);
- result.Append(std::move(permission));
- }
-
- return result;
-}
-
// Dictionary keys for an individual `FileSystemPermissionGrant`.
// Schema (per grant):
// {
@@ -2710,8 +2591,9 @@ void SiteSettingsHandler::SendNotificationPermissionReviewList() {
// an unchanged list may be sent. This is the case for
// HandleResetCategoryPermissionForPattern and
// HandleSetCategoryPermissionForPattern.
- FireWebUIListener("notification-permission-review-list-maybe-changed",
- PopulateNotificationPermissionReviewData());
+ FireWebUIListener(
+ site_settings::kNotificationPermissionsReviewListMaybeChangedEvent,
+ site_settings::PopulateNotificationPermissionReviewData(profile_));
}
} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/site_settings_handler.h b/chromium/chrome/browser/ui/webui/settings/site_settings_handler.h
index b4edc1b2a06..5a22fb63250 100644
--- a/chromium/chrome/browser/ui/webui/settings/site_settings_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/site_settings_handler.h
@@ -9,6 +9,7 @@
#include <memory>
#include <set>
#include <string>
+#include <vector>
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
@@ -50,6 +51,7 @@ class SiteSettingsHandler
public:
static GroupingKey Create(const url::Origin& origin);
static GroupingKey CreateFromEtldPlus1(const std::string& etld_plus1);
+ static GroupingKey Deserialize(const std::string& serialized);
GroupingKey(const GroupingKey& other);
GroupingKey& operator=(const GroupingKey& other);
@@ -171,7 +173,7 @@ class SiteSettingsHandler
FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, SessionOnlyException);
FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, ZoomLevels);
FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest,
- HandleClearEtldPlus1DataAndCookies);
+ HandleClearSiteGroupDataAndCookies);
FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest,
HandleClearUnpartitionedUsage);
FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, ClearClientHints);
@@ -190,24 +192,6 @@ class SiteSettingsHandler
HandleGetFpsMembershipLabel);
FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, NonTreeModelDeletion);
FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, FirstPartySetsMembership);
- FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest,
- HandleIgnoreOriginsForNotificationPermissionReview);
- FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest,
- HandleBlockNotificationPermissionForOrigins);
- FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest,
- HandleAllowNotificationPermissionForOrigins);
- FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest,
- HandleResetNotificationPermissionForOrigins);
- FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest,
- PopulateNotificationPermissionReviewData);
- FRIEND_TEST_ALL_PREFIXES(
- SiteSettingsHandlerTest,
- HandleUndoIgnoreOriginsForNotificationPermissionReview);
- FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest,
- SendNotificationPermissionReviewList_FeatureEnabled);
- FRIEND_TEST_ALL_PREFIXES(
- SiteSettingsHandlerTest,
- SendNotificationPermissionReviewList_FeatureDisabled);
FRIEND_TEST_ALL_PREFIXES(
SiteSettingsHandlerInfobarTest,
SettingPermissionsDoesNotTriggerInfobarOnDifferentProfile);
@@ -215,6 +199,9 @@ class SiteSettingsHandler
FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, HandleGetExtensionName);
#endif
FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerTest, IsolatedWebAppUsageInfo);
+ FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerIsolatedWebAppTest, ZoomLevel);
+ FRIEND_TEST_ALL_PREFIXES(SiteSettingsHandlerIsolatedWebAppTest,
+ ZoomLevelsSortedByAppName);
// Rebuilds the BrowsingDataModel & CookiesTreeModel. Pending requests are
// serviced when both models are built.
@@ -296,9 +283,6 @@ class SiteSettingsHandler
// Returns the list of chooser exceptions for a given chooser type.
void HandleGetChooserExceptionList(const base::Value::List& args);
- // Returns the list of notification permissions that needs to be reviewed.
- void HandleGetNotificationPermissionReviewList(const base::Value::List& args);
-
// Returns the list of the allowed permission grants as defined by the
// File System Access API.
void HandleGetFileSystemGrants(const base::Value::List& args);
@@ -326,28 +310,6 @@ class SiteSettingsHandler
// Handles resetting a chooser exception for the given site.
void HandleResetChooserExceptionForSite(const base::Value::List& args);
- // Handles ignoring origins for the review notification permissions feature.
- void HandleIgnoreOriginsForNotificationPermissionReview(
- const base::Value::List& args);
-
- // Handles resetting a notification permission for given origins.
- void HandleResetNotificationPermissionForOrigins(
- const base::Value::List& args);
-
- // Handles blocking notification permissions for multiple origins.
- void HandleBlockNotificationPermissionForOrigins(
- const base::Value::List& args);
-
- // Handles allowing notification permissions for multiple origins.
- void HandleAllowNotificationPermissionForOrigins(
- const base::Value::List& args);
-
- // Handles reverting the action of ignoring origins for review notification
- // permissions feature by removing them from the notification permission
- // verification blocklist.
- void HandleUndoIgnoreOriginsForNotificationPermissionReview(
- const base::Value::List& args);
-
// Returns whether a given string is a valid origin.
void HandleIsOriginValid(const base::Value::List& args);
@@ -378,8 +340,8 @@ class SiteSettingsHandler
// Updates the block autoplay enabled pref when the UI is toggled.
void HandleSetBlockAutoplayEnabled(const base::Value::List& args);
- // Clear web storage data and cookies from cookies tree model for an ETLD+1.
- void HandleClearEtldPlus1DataAndCookies(const base::Value::List& args);
+ // Clear web storage data and cookies from CookiesTreeModel for a site group.
+ void HandleClearSiteGroupDataAndCookies(const base::Value::List& args);
// Record metrics for actions on All Sites Page.
void HandleRecordAction(const base::Value::List& args);
@@ -403,11 +365,6 @@ class SiteSettingsHandler
// provides the updated description label for display.
void SendCookieSettingDescription();
- // Returns a list of domains to be shown on the 'Review Notification
- // Permissions' module in site settings notification page. Those domains send
- // a lot of notifications, but have low site engagement.
- base::Value::List PopulateNotificationPermissionReviewData();
-
// Returns a dictionary containing the lists of the allowed permission
// grant objects granted via the File System Access API, per origin.
base::Value::List PopulateFileSystemGrantData();
@@ -415,20 +372,17 @@ class SiteSettingsHandler
// Sends the list of notification permissions to review to the WebUI.
void SendNotificationPermissionReviewList();
- const raw_ptr<Profile> profile_;
+ const raw_ptr<Profile, DanglingUntriaged> profile_;
base::ScopedMultiSourceObservation<Profile, ProfileObserver>
observed_profiles_{this};
// Keeps track of events related to zooming.
- base::CallbackListSubscription host_zoom_map_subscription_;
+ std::vector<base::CallbackListSubscription> host_zoom_map_subscriptions_;
// The origin for which to fetch usage.
std::string usage_origin_;
- // The origin for which to clear usage.
- std::string clearing_origin_;
-
// Change observer for content settings.
base::ScopedMultiSourceObservation<HostContentSettingsMap,
content_settings::Observer>
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 ad52d5eaa6d..9fd8fd8bf8f 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
@@ -42,19 +42,25 @@
#include "chrome/browser/extensions/test_extension_system.h"
#include "chrome/browser/file_system_access/chrome_file_system_access_permission_context.h"
#include "chrome/browser/file_system_access/file_system_access_permission_context_factory.h"
+#include "chrome/browser/hid/hid_chooser_context.h"
+#include "chrome/browser/hid/hid_chooser_context_factory.h"
#include "chrome/browser/history/history_service_factory.h"
-#include "chrome/browser/permissions/notification_permission_review_service_factory.h"
-#include "chrome/browser/permissions/notifications_engagement_service_factory.h"
#include "chrome/browser/permissions/permission_decision_auto_blocker_factory.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "chrome/browser/privacy_sandbox/mock_privacy_sandbox_service.h"
#include "chrome/browser/privacy_sandbox/privacy_sandbox_service_factory.h"
+#include "chrome/browser/serial/serial_chooser_context.h"
+#include "chrome/browser/serial/serial_chooser_context_factory.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/browser/ui/web_applications/test/isolated_web_app_test_utils.h"
#include "chrome/browser/ui/webui/settings/site_settings_helper.h"
#include "chrome/browser/usb/usb_chooser_context.h"
#include "chrome/browser/usb/usb_chooser_context_factory.h"
+#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.h"
+#include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
#include "chrome/browser/web_applications/web_app_helpers.h"
+#include "chrome/browser/web_applications/web_app_id.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/pref_names.h"
#include "chrome/grit/generated_resources.h"
@@ -69,6 +75,7 @@
#include "components/browsing_topics/browsing_topics_service.h"
#include "components/browsing_topics/test_util.h"
#include "components/client_hints/common/client_hints.h"
+#include "components/content_settings/core/browser/content_settings_uma_util.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"
@@ -93,6 +100,7 @@
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/public/browser/browsing_data_remover.h"
+#include "content/public/browser/host_zoom_map.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_ui_data_source.h"
@@ -106,7 +114,11 @@
#include "extensions/common/extension_builder.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "ppapi/buildflags/buildflags.h"
+#include "services/device/public/cpp/test/fake_hid_manager.h"
+#include "services/device/public/cpp/test/fake_serial_port_manager.h"
#include "services/device/public/cpp/test/fake_usb_device_manager.h"
+#include "services/device/public/mojom/hid.mojom.h"
+#include "services/device/public/mojom/serial.mojom.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
@@ -127,20 +139,6 @@
#include "chrome/browser/plugins/chrome_plugin_service_filter.h"
#endif
-#if !BUILDFLAG(IS_ANDROID)
-#include "chrome/browser/hid/hid_chooser_context.h"
-#include "chrome/browser/hid/hid_chooser_context_factory.h"
-#include "chrome/browser/serial/serial_chooser_context.h"
-#include "chrome/browser/serial/serial_chooser_context_factory.h"
-#include "chrome/browser/ui/web_applications/test/isolated_web_app_test_utils.h"
-#include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
-#include "chrome/browser/web_applications/web_app_id.h"
-#include "services/device/public/cpp/test/fake_hid_manager.h"
-#include "services/device/public/cpp/test/fake_serial_port_manager.h"
-#include "services/device/public/mojom/hid.mojom.h"
-#include "services/device/public/mojom/serial.mojom.h"
-#endif
-
namespace {
using ::base::test::ParseJson;
@@ -151,6 +149,8 @@ using ::testing::NiceMock;
using ::testing::Return;
using ::testing::UnorderedElementsAre;
+using GroupingKey = settings::SiteSettingsHandler::GroupingKey;
+
constexpr char kCallbackId[] = "test-callback-id";
constexpr char kSetting[] = "setting";
constexpr char kSource[] = "source";
@@ -178,6 +178,15 @@ const struct PatternContentTypeTestCase {
{{"http://127.0.0.1", "location"}, {true, ""}}, // Localhost is secure.
{{"http://[::1]", "location"}, {true, ""}}};
+// Matchers to make verifying GroupingKey contents easier.
+MATCHER_P(IsEtldPlus1, etld_plus1, "") {
+ return arg == std::string("etld:") + etld_plus1;
+}
+
+MATCHER_P(IsOrigin, origin, "") {
+ return arg == std::string("origin:") + origin.spec();
+}
+
// Converts |etld_plus1| into an HTTPS SchemefulSite.
net::SchemefulSite ConvertEtldToSchemefulSite(const std::string etld_plus1) {
return net::SchemefulSite(GURL(std::string(url::kHttpsScheme) +
@@ -192,7 +201,12 @@ void ValidateSitesWithFps(
base::flat_map<net::SchemefulSite, net::SchemefulSite>& first_party_sets) {
for (const base::Value& site_group_value : storage_and_cookie_list) {
const base::Value::Dict& site_group = site_group_value.GetDict();
- std::string etld_plus1 = *site_group.FindString("etldPlus1");
+ GroupingKey grouping_key = GroupingKey::Deserialize(
+ CHECK_DEREF(site_group.FindString("groupingKey")));
+ if (!grouping_key.GetEtldPlusOne().has_value()) {
+ return;
+ }
+ std::string etld_plus1 = *grouping_key.GetEtldPlusOne();
auto schemeful_site = ConvertEtldToSchemefulSite(etld_plus1);
if (first_party_sets.count(schemeful_site)) {
@@ -361,20 +375,6 @@ class SiteSettingsHandlerBaseTest : public testing::Test {
}
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
- void RecordNotification(permissions::NotificationsEngagementService* service,
- GURL url,
- int daily_average_count) {
- // This many notifications were recorded during the past week in total.
- int total_count = daily_average_count * 7;
- service->RecordNotificationDisplayed(url, total_count);
- }
-
- base::Time GetReferenceTime() {
- base::Time time;
- EXPECT_TRUE(base::Time::FromString("Sat, 1 Sep 2018 11:00:00 GMT", &time));
- return time;
- }
-
TestingProfile* profile() { return profile_.get(); }
Profile* incognito_profile() { return incognito_profile_; }
content::TestWebUI* web_ui() { return &web_ui_; }
@@ -544,8 +544,13 @@ class SiteSettingsHandlerBaseTest : public testing::Test {
EXPECT_EQ(expected_incognito, data.arg2()->GetBool());
}
- void ValidateZoom(const std::string& expected_host,
- const std::string& expected_zoom,
+ struct ZoomLevel {
+ std::string host_or_spec;
+ std::string display_name;
+ std::string zoom;
+ };
+
+ void ValidateZoom(const std::vector<ZoomLevel>& zoom_levels,
size_t expected_total_calls) {
EXPECT_EQ(expected_total_calls, web_ui()->call_data().size());
@@ -557,20 +562,22 @@ class SiteSettingsHandlerBaseTest : public testing::Test {
ASSERT_TRUE(data.arg2()->is_list());
const base::Value::List& exceptions = data.arg2()->GetList();
- if (expected_host.empty()) {
- EXPECT_EQ(0U, exceptions.size());
- } else {
- EXPECT_EQ(1U, exceptions.size());
+ ASSERT_EQ(zoom_levels.size(), exceptions.size());
+ for (size_t i = 0; i < zoom_levels.size(); i++) {
+ const ZoomLevel& zoom_level = zoom_levels[i];
+ const base::Value::Dict& exception = exceptions[i].GetDict();
- const base::Value::Dict& exception = exceptions[0].GetDict();
+ const std::string* host_or_spec = exception.FindString("hostOrSpec");
+ ASSERT_TRUE(host_or_spec);
+ ASSERT_EQ(zoom_level.host_or_spec, *host_or_spec);
- const std::string* host = exception.FindString("origin");
- ASSERT_TRUE(host);
- ASSERT_EQ(expected_host, *host);
+ const std::string* display_name = exception.FindString("displayName");
+ ASSERT_TRUE(display_name);
+ ASSERT_EQ(zoom_level.display_name, *display_name);
const std::string* zoom = exception.FindString("zoom");
ASSERT_TRUE(zoom);
- ASSERT_EQ(expected_zoom, *zoom);
+ ASSERT_EQ(zoom_level.zoom, *zoom);
}
}
@@ -584,7 +591,7 @@ class SiteSettingsHandlerBaseTest : public testing::Test {
ASSERT_EQ(expected_string, data.arg2()->GetString());
}
- void ValidateUsageInfo(const std::string& expected_usage_host,
+ void ValidateUsageInfo(const std::string& expected_usage_origin,
const std::string& expected_usage_string,
const std::string& expected_cookie_string,
const std::string& expected_fps_member_count_string,
@@ -596,7 +603,7 @@ class SiteSettingsHandlerBaseTest : public testing::Test {
EXPECT_EQ("usage-total-changed", data.arg_nth(0)->GetString());
ASSERT_TRUE(data.arg_nth(1)->is_string());
- EXPECT_EQ(expected_usage_host, data.arg_nth(1)->GetString());
+ EXPECT_EQ(expected_usage_origin, data.arg_nth(1)->GetString());
ASSERT_TRUE(data.arg_nth(2)->is_string());
EXPECT_EQ(expected_usage_string, data.arg_nth(2)->GetString());
@@ -611,17 +618,6 @@ class SiteSettingsHandlerBaseTest : public testing::Test {
EXPECT_EQ(expected_fps_policy, data.arg_nth(5)->GetBool());
}
- void ValidateNotificationPermissionUpdate() {
- const content::TestWebUI::CallData& data = *web_ui()->call_data().back();
- EXPECT_EQ("cr.webUIListenerCallback", data.function_name());
-
- ASSERT_TRUE(data.arg1()->is_string());
- EXPECT_EQ("notification-permission-review-list-maybe-changed",
- data.arg1()->GetString());
-
- ASSERT_TRUE(data.arg2()->is_list());
- }
-
void CreateIncognitoProfile() {
incognito_profile_ = profile_->GetOffTheRecordProfile(
Profile::OTRProfileID::PrimaryID(), /*create_if_needed=*/true);
@@ -659,11 +655,13 @@ class SiteSettingsHandlerBaseTest : public testing::Test {
auto mock_cookies_tree_model = std::make_unique<CookiesTreeModel>(
std::move(container), profile()->GetExtensionSpecialStoragePolicy());
- auto fake_browsing_data_model = std::make_unique<FakeBrowsingDataModel>();
+ auto fake_browsing_data_model = std::make_unique<FakeBrowsingDataModel>(
+ ChromeBrowsingDataModelDelegate::CreateForProfile(profile()));
- std::move(setup).Run({mock_browsing_data_cookie_helper,
- mock_browsing_data_local_storage_helper,
- raw_ref(*fake_browsing_data_model)});
+ std::move(setup).Run(
+ {mock_browsing_data_cookie_helper,
+ mock_browsing_data_local_storage_helper,
+ ToRawRef<ExperimentalAsh>(*fake_browsing_data_model)});
mock_browsing_data_local_storage_helper->Notify();
mock_browsing_data_cookie_helper->Notify();
@@ -738,8 +736,7 @@ class SiteSettingsHandlerBaseTest : public testing::Test {
base::Value::List GetOnStorageFetchedSentList() {
handler()->ClearAllSitesMapForTesting();
- base::Value::List get_all_sites_args;
- get_all_sites_args.Append(kCallbackId);
+ auto get_all_sites_args = base::Value::List().Append(kCallbackId);
handler()->HandleGetAllSites(get_all_sites_args);
handler()->ServicePendingRequests();
@@ -786,22 +783,13 @@ class SiteSettingsHandlerBaseTest : public testing::Test {
return first_party_sets;
}
- base::Value::List GetOriginList(int size) {
- base::Value::List origins;
- for (int i = 0; i < size; i++) {
- origins.Append("https://example" + base::NumberToString(i) + ".org:443");
- }
- return origins;
- }
-
scoped_refptr<const extensions::Extension> LoadExtension(
const std::string& extension_name) {
auto extension = extensions::ExtensionBuilder()
- .SetManifest(extensions::DictionaryBuilder()
+ .SetManifest(base::Value::Dict()
.Set("name", kExtensionName)
.Set("version", "1.0.0")
- .Set("manifest_version", 3)
- .Build())
+ .Set("manifest_version", 3))
.Build();
extensions::TestExtensionSystem* extension_system =
@@ -848,7 +836,7 @@ class SiteSettingsHandlerBaseTest : public testing::Test {
content::BrowserTaskEnvironment task_environment_;
std::unique_ptr<TestingProfileManager> testing_profile_manager_;
raw_ptr<TestingProfile> profile_ = nullptr;
- raw_ptr<Profile> incognito_profile_ = nullptr;
+ raw_ptr<Profile, DanglingUntriaged> incognito_profile_ = nullptr;
content::TestWebUI web_ui_;
std::unique_ptr<SiteSettingsHandler> handler_;
#if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -931,11 +919,10 @@ TEST_F(SiteSettingsHandlerTest, GetAllSites) {
EXPECT_EQ(1UL, site_groups.size());
for (const base::Value& site_group_val : site_groups) {
const base::Value::Dict& site_group = site_group_val.GetDict();
- const std::string& etld_plus1_string =
- CHECK_DEREF(site_group.FindString("etldPlus1"));
const base::Value::List& origin_list =
CHECK_DEREF(site_group.FindList("origins"));
- EXPECT_EQ("example.com", etld_plus1_string);
+ EXPECT_THAT(CHECK_DEREF(site_group.FindString("groupingKey")),
+ IsEtldPlus1("example.com"));
EXPECT_EQ(2UL, origin_list.size());
const base::Value::Dict& first_origin = origin_list[0].GetDict();
const base::Value::Dict& second_origin = origin_list[1].GetDict();
@@ -963,16 +950,17 @@ TEST_F(SiteSettingsHandlerTest, GetAllSites) {
EXPECT_EQ(2UL, site_groups.size());
for (const base::Value& site_group_val : site_groups) {
const base::Value::Dict& site_group = site_group_val.GetDict();
- const std::string& etld_plus1_string =
- CHECK_DEREF(site_group.FindString("etldPlus1"));
+ const std::string& grouping_key_string =
+ CHECK_DEREF(site_group.FindString("groupingKey"));
+ auto grouping_key = GroupingKey::Deserialize(grouping_key_string);
const base::Value::List& origin_list =
CHECK_DEREF(site_group.FindList("origins"));
- if (etld_plus1_string == "example2.net") {
+ if (grouping_key.GetEtldPlusOne() == "example2.net") {
EXPECT_EQ(1UL, origin_list.size());
const base::Value::Dict& first_origin = origin_list[0].GetDict();
EXPECT_EQ(url3.spec(), CHECK_DEREF(first_origin.FindString("origin")));
} else {
- EXPECT_EQ("example.com", etld_plus1_string);
+ EXPECT_THAT(grouping_key_string, IsEtldPlus1("example.com"));
}
}
}
@@ -1015,10 +1003,10 @@ TEST_F(SiteSettingsHandlerTest, GetAllSites) {
const base::Value::List& site_groups = data.arg3()->GetList();
EXPECT_EQ(2UL, site_groups.size());
- EXPECT_EQ("example.com",
- CHECK_DEREF(site_groups[0].GetDict().FindString("etldPlus1")));
- EXPECT_EQ("example2.net",
- CHECK_DEREF(site_groups[1].GetDict().FindString("etldPlus1")));
+ EXPECT_THAT(CHECK_DEREF(site_groups[0].GetDict().FindString("groupingKey")),
+ IsEtldPlus1("example.com"));
+ EXPECT_THAT(CHECK_DEREF(site_groups[1].GetDict().FindString("groupingKey")),
+ IsEtldPlus1("example2.net"));
}
// Add an expired embargo setting to an existing eTLD+1 group and make sure it
@@ -1045,10 +1033,10 @@ TEST_F(SiteSettingsHandlerTest, GetAllSites) {
const base::Value::List& site_groups = data.arg3()->GetList();
EXPECT_EQ(2UL, site_groups.size());
- EXPECT_EQ("example.com",
- CHECK_DEREF(site_groups[0].GetDict().FindString("etldPlus1")));
- EXPECT_EQ("example2.net",
- CHECK_DEREF(site_groups[1].GetDict().FindString("etldPlus1")));
+ EXPECT_THAT(CHECK_DEREF(site_groups[0].GetDict().FindString("groupingKey")),
+ IsEtldPlus1("example.com"));
+ EXPECT_THAT(CHECK_DEREF(site_groups[1].GetDict().FindString("groupingKey")),
+ IsEtldPlus1("example2.net"));
}
// Add an expired embargo to a new eTLD+1 and make sure it doesn't appear.
@@ -1075,10 +1063,10 @@ TEST_F(SiteSettingsHandlerTest, GetAllSites) {
const base::Value::List& site_groups = data.arg3()->GetList();
EXPECT_EQ(2UL, site_groups.size());
- EXPECT_EQ("example.com",
- CHECK_DEREF(site_groups[0].GetDict().FindString("etldPlus1")));
- EXPECT_EQ("example2.net",
- CHECK_DEREF(site_groups[1].GetDict().FindString("etldPlus1")));
+ EXPECT_THAT(CHECK_DEREF(site_groups[0].GetDict().FindString("groupingKey")),
+ IsEtldPlus1("example.com"));
+ EXPECT_THAT(CHECK_DEREF(site_groups[1].GetDict().FindString("groupingKey")),
+ IsEtldPlus1("example2.net"));
}
// Same extension url from different content setting types shows only one
@@ -1099,13 +1087,18 @@ TEST_F(SiteSettingsHandlerTest, GetAllSites) {
const base::Value::List& site_groups = data.arg3()->GetList();
EXPECT_EQ(3UL, site_groups.size());
- // Extension etldPlus1 string will be in the pattern of
+ // Extension groupingKey will be its origin with the pattern
// "chrome-extension://<extension_id>" so it is before other site groups in
// the list.
- EXPECT_EQ(extension->url().spec(),
- CHECK_DEREF(site_groups[0].GetDict().FindString("etldPlus1")));
+ EXPECT_THAT(CHECK_DEREF(site_groups[0].GetDict().FindString("groupingKey")),
+ IsOrigin(extension->url()));
+ EXPECT_EQ(nullptr, site_groups[0].GetDict().FindString("etldPlus1"));
+ EXPECT_THAT(CHECK_DEREF(site_groups[1].GetDict().FindString("groupingKey")),
+ IsEtldPlus1("example.com"));
EXPECT_EQ("example.com",
CHECK_DEREF(site_groups[1].GetDict().FindString("etldPlus1")));
+ EXPECT_THAT(CHECK_DEREF(site_groups[2].GetDict().FindString("groupingKey")),
+ IsEtldPlus1("example2.net"));
EXPECT_EQ("example2.net",
CHECK_DEREF(site_groups[2].GetDict().FindString("etldPlus1")));
}
@@ -1133,7 +1126,8 @@ TEST_F(SiteSettingsHandlerTest, Cookies) {
ASSERT_EQ(1UL, site_groups.size());
const base::Value::Dict& first_group = site_groups[0].GetDict();
- EXPECT_EQ("c1.com", CHECK_DEREF(first_group.FindString("etldPlus1")));
+ EXPECT_THAT(CHECK_DEREF(first_group.FindString("groupingKey")),
+ IsEtldPlus1("c1.com"));
EXPECT_EQ(1, *first_group.FindInt("numCookies"));
const base::Value::List& first_group_origins =
CHECK_DEREF(first_group.FindList("origins"));
@@ -1157,7 +1151,8 @@ TEST_F(SiteSettingsHandlerTest, Cookies) {
ASSERT_EQ(1UL, site_groups.size());
const base::Value::Dict& first_group = site_groups[0].GetDict();
- EXPECT_EQ("c2.com", CHECK_DEREF(first_group.FindString("etldPlus1")));
+ EXPECT_THAT(CHECK_DEREF(first_group.FindString("groupingKey")),
+ IsEtldPlus1("c2.com"));
EXPECT_EQ(2, *first_group.FindInt("numCookies"));
const base::Value::List& first_group_origins =
CHECK_DEREF(first_group.FindList("origins"));
@@ -1183,7 +1178,8 @@ TEST_F(SiteSettingsHandlerTest, Cookies) {
ASSERT_EQ(1UL, site_groups.size());
const base::Value::Dict& first_group = site_groups[0].GetDict();
- EXPECT_EQ("c3.com", CHECK_DEREF(first_group.FindString("etldPlus1")));
+ EXPECT_THAT(CHECK_DEREF(first_group.FindString("groupingKey")),
+ IsEtldPlus1("c3.com"));
EXPECT_EQ(1, *first_group.FindInt("numCookies"));
const base::Value::List& first_group_origins =
CHECK_DEREF(first_group.FindList("origins"));
@@ -1206,7 +1202,8 @@ TEST_F(SiteSettingsHandlerTest, Cookies) {
ASSERT_EQ(1UL, site_groups.size());
const base::Value::Dict& first_group = site_groups[0].GetDict();
- EXPECT_EQ("c4.com", CHECK_DEREF(first_group.FindString("etldPlus1")));
+ EXPECT_THAT(CHECK_DEREF(first_group.FindString("groupingKey")),
+ IsEtldPlus1("c4.com"));
EXPECT_EQ(2, *first_group.FindInt("numCookies"));
const base::Value::List& first_group_origins =
CHECK_DEREF(first_group.FindList("origins"));
@@ -1347,8 +1344,8 @@ TEST_F(SiteSettingsHandlerTest, OnStorageFetched) {
ASSERT_TRUE(site_group_val.is_dict());
const base::Value::Dict& site_group = site_group_val.GetDict();
- ASSERT_TRUE(site_group.FindString("etldPlus1"));
- ASSERT_EQ("example.com", *site_group.FindString("etldPlus1"));
+ ASSERT_THAT(CHECK_DEREF(site_group.FindString("groupingKey")),
+ IsEtldPlus1("example.com"));
EXPECT_EQ(3, site_group.FindDouble("numCookies"));
@@ -1381,8 +1378,8 @@ TEST_F(SiteSettingsHandlerTest, OnStorageFetched) {
{
const base::Value::Dict& site_group = storage_and_cookie_list[1].GetDict();
- ASSERT_TRUE(site_group.FindString("etldPlus1"));
- ASSERT_EQ("google.com", *site_group.FindString("etldPlus1"));
+ ASSERT_THAT(CHECK_DEREF(site_group.FindString("groupingKey")),
+ IsEtldPlus1("google.com"));
EXPECT_EQ(3, site_group.FindDouble("numCookies"));
@@ -1419,8 +1416,8 @@ TEST_F(SiteSettingsHandlerTest, OnStorageFetched) {
ASSERT_TRUE(site_group_val.is_dict());
const base::Value::Dict& site_group = site_group_val.GetDict();
- ASSERT_TRUE(site_group.FindString("etldPlus1"));
- ASSERT_EQ("google.com.au", *site_group.FindString("etldPlus1"));
+ ASSERT_THAT(CHECK_DEREF(site_group.FindString("groupingKey")),
+ IsEtldPlus1("google.com.au"));
EXPECT_EQ(4, site_group.FindDouble("numCookies"));
@@ -1472,8 +1469,8 @@ TEST_F(SiteSettingsHandlerTest, OnStorageFetched) {
ASSERT_TRUE(site_group_val.is_dict());
const base::Value::Dict& site_group = site_group_val.GetDict();
- ASSERT_TRUE(site_group.FindString("etldPlus1"));
- ASSERT_EQ("ungrouped.com", *site_group.FindString("etldPlus1"));
+ ASSERT_THAT(CHECK_DEREF(site_group.FindString("groupingKey")),
+ IsEtldPlus1("ungrouped.com"));
EXPECT_EQ(1, site_group.FindDouble("numCookies"));
@@ -1509,8 +1506,8 @@ TEST_F(SiteSettingsHandlerTest, InstalledApps) {
ASSERT_TRUE(site_group_val.is_dict());
const base::Value::Dict& site_group = site_group_val.GetDict();
- ASSERT_TRUE(site_group.FindString("etldPlus1"));
- ASSERT_EQ("example.com", *site_group.FindString("etldPlus1"));
+ ASSERT_THAT(CHECK_DEREF(site_group.FindString("groupingKey")),
+ IsEtldPlus1("example.com"));
ASSERT_TRUE(site_group.FindBool("hasInstalledPWA").value_or(false));
@@ -1530,8 +1527,8 @@ TEST_F(SiteSettingsHandlerTest, InstalledApps) {
ASSERT_TRUE(site_group_val.is_dict());
const base::Value::Dict& site_group = site_group_val.GetDict();
- ASSERT_TRUE(site_group.FindString("etldPlus1"));
- ASSERT_EQ("google.com", *site_group.FindString("etldPlus1"));
+ ASSERT_THAT(CHECK_DEREF(site_group.FindString("groupingKey")),
+ IsEtldPlus1("google.com"));
EXPECT_FALSE(site_group.FindBool("hasInstalledPWA").value_or(true));
const base::Value::List* origin_list = site_group.FindList("origins");
@@ -1545,50 +1542,6 @@ TEST_F(SiteSettingsHandlerTest, InstalledApps) {
}
}
-#if !BUILDFLAG(IS_ANDROID)
-TEST_F(SiteSettingsHandlerTest, AllSitesDisplaysIsolatedWebAppName) {
- std::string iwa_hostname =
- "aerugqztij5biqquuk3mfwpsaibuegaqcitgfchwuosuofdjabzqaaic";
- GURL iwa_url("isolated-app://" + iwa_hostname);
- GURL https_url("https://" + iwa_hostname);
-
- // Install an IWA at |iwa_url|.
- web_app::test::AwaitStartWebAppProviderAndSubsystems(profile());
- web_app::AppId app_id =
- web_app::AddDummyIsolatedAppToRegistry(profile(), iwa_url, "IWA Name");
- RegisterWebApp(profile(),
- MakeApp(app_id, apps::AppType::kWeb, iwa_url.spec(),
- apps::Readiness::kReady, apps::InstallReason::kUser));
-
- SetupModels(base::DoNothing());
- HostContentSettingsMap* map =
- HostContentSettingsMapFactory::GetForProfile(profile());
- map->SetContentSettingDefaultScope(iwa_url, iwa_url,
- ContentSettingsType::NOTIFICATIONS,
- CONTENT_SETTING_BLOCK);
- map->SetContentSettingDefaultScope(https_url, https_url,
- ContentSettingsType::NOTIFICATIONS,
- CONTENT_SETTING_BLOCK);
-
- base::Value::List site_groups = GetOnStorageFetchedSentList();
-
- ASSERT_EQ(site_groups.size(), 2u);
- const base::Value::Dict& group1 = site_groups[0].GetDict();
- const base::Value::Dict& origin1 =
- CHECK_DEREF(group1.FindList("origins"))[0].GetDict();
- EXPECT_EQ(CHECK_DEREF(group1.FindString("etldPlus1")), iwa_url);
- EXPECT_EQ(CHECK_DEREF(group1.FindString("displayName")), "IWA Name");
- EXPECT_EQ(CHECK_DEREF(origin1.FindString("origin")), iwa_url);
-
- const base::Value::Dict& group2 = site_groups[1].GetDict();
- const base::Value::Dict& origin2 =
- CHECK_DEREF(group2.FindList("origins"))[0].GetDict();
- EXPECT_EQ(CHECK_DEREF(group2.FindString("etldPlus1")), iwa_hostname);
- EXPECT_EQ(CHECK_DEREF(group2.FindString("displayName")), iwa_hostname);
- EXPECT_EQ(CHECK_DEREF(origin2.FindString("origin")), https_url);
-}
-#endif // !BUILDFLAG(IS_ANDROID)
-
TEST_F(SiteSettingsHandlerTest, IncognitoExceptions) {
constexpr char kOriginToBlock[] = "https://www.blocked.com:443";
@@ -1863,10 +1816,10 @@ TEST_F(SiteSettingsHandlerTest, NotificationPermissionRevokeUkm) {
EXPECT_EQ(
*ukm_recorder.GetEntryMetric(entry, "Source"),
static_cast<int64_t>(permissions::PermissionSourceUI::SITE_SETTINGS));
- size_t num_values = 0;
+
EXPECT_EQ(*ukm_recorder.GetEntryMetric(entry, "PermissionType"),
- ContentSettingTypeToHistogramValue(
- ContentSettingsType::NOTIFICATIONS, &num_values));
+ content_settings_uma_util::ContentSettingTypeToHistogramValue(
+ ContentSettingsType::NOTIFICATIONS));
EXPECT_EQ(*ukm_recorder.GetEntryMetric(entry, "Action"),
static_cast<int64_t>(permissions::PermissionAction::REVOKED));
}
@@ -2062,11 +2015,10 @@ TEST_F(SiteSettingsHandlerTest, ExceptionHelpers) {
scoped_refptr<const extensions::Extension> extension;
extension = extensions::ExtensionBuilder()
- .SetManifest(extensions::DictionaryBuilder()
+ .SetManifest(base::Value::Dict()
.Set("name", kExtensionName)
.Set("version", "1.0.0")
- .Set("manifest_version", 2)
- .Build())
+ .Set("manifest_version", 2))
.SetID("ahfgeienlihckogmohjhadlkjgocpleb")
.Build();
@@ -2088,8 +2040,7 @@ TEST_F(SiteSettingsHandlerTest, ExceptionHelpers) {
}
TEST_F(SiteSettingsHandlerTest, ExtensionDisplayName) {
- // When the extension is loaded, the displayName is the extension's name, and
- // there is extensionNameWithId field.
+ // When the extension is loaded, displayName is the extension's name and id.
auto extension = LoadExtension(kExtensionName);
auto extension_url = extension->url().spec();
{
@@ -2102,28 +2053,14 @@ TEST_F(SiteSettingsHandlerTest, ExtensionDisplayName) {
get_origin_permissions_args.Append(std::move(category_list));
}
handler()->HandleGetOriginPermissions(get_origin_permissions_args);
- ValidateOrigin(extension_url, extension_url, kExtensionName,
+ std::string expected_display_name =
+ base::StringPrintf("Test Extension (ID: %s)", extension->id().c_str());
+ ValidateOrigin(extension_url, extension_url, expected_display_name,
CONTENT_SETTING_ASK,
site_settings::SiteSettingSource::kDefault, 1U);
- // Validates the extensionNameWithId field.
- {
- const content::TestWebUI::CallData& data = *web_ui()->call_data().back();
- EXPECT_EQ("cr.webUIResponse", data.function_name());
- ASSERT_TRUE(data.arg3()->is_list());
- EXPECT_EQ(1U, data.arg3()->GetList().size());
- const base::Value& exception = data.arg3()->GetList()[0];
- ASSERT_TRUE(exception.is_dict());
- const std::string* extension_name_with_id =
- exception.GetDict().FindString(site_settings::kExtensionNameWithId);
- ASSERT_TRUE(extension_name_with_id);
- ASSERT_EQ(base::StringPrintf("Test Extension (ID: %s)",
- extension->id().c_str()),
- *extension_name_with_id);
- }
}
- // When the extension is unloaded, the displayName is the extension's origin,
- // and there is no extensionNameWithId field.
+ // When the extension is unloaded, the displayName is the extension's origin.
UnloadExtension(extension->id());
{
base::Value::List get_origin_permissions_args;
@@ -2139,17 +2076,6 @@ TEST_F(SiteSettingsHandlerTest, ExtensionDisplayName) {
extension_url, extension_url,
base::StringPrintf("chrome-extension://%s", extension->id().c_str()),
CONTENT_SETTING_ASK, site_settings::SiteSettingSource::kDefault, 2U);
- // Validates there is no extensionNameWithId field.
- {
- const content::TestWebUI::CallData& data = *web_ui()->call_data().back();
- EXPECT_EQ("cr.webUIResponse", data.function_name());
- ASSERT_TRUE(data.arg3()->is_list());
- EXPECT_EQ(1U, data.arg3()->GetList().size());
- const base::Value::Dict& exception = data.arg3()->GetList()[0].GetDict();
- const std::string* extension_name_with_id =
- exception.FindString(site_settings::kExtensionNameWithId);
- ASSERT_FALSE(extension_name_with_id);
- }
}
}
@@ -2180,27 +2106,165 @@ TEST_F(SiteSettingsHandlerTest, Incognito) {
}
TEST_F(SiteSettingsHandlerTest, ZoomLevels) {
- std::string host("http://www.google.com");
+ std::string http_host("www.google.com");
+ std::string error_host("chromewebdata");
+ std::string data_url("data:text/plain;base64,SGVsbG8sIFdvcmxkIQ==");
double zoom_level = 1.1;
content::HostZoomMap* host_zoom_map =
content::HostZoomMap::GetDefaultForBrowserContext(profile());
- host_zoom_map->SetZoomLevelForHost(host, zoom_level);
- ValidateZoom(host, "122%", 1U);
+ host_zoom_map->SetZoomLevelForHost(http_host, zoom_level);
+ host_zoom_map->SetZoomLevelForHost(error_host, zoom_level);
+ host_zoom_map->SetZoomLevelForHost(data_url, zoom_level);
+ ValidateZoom({{error_host, "(Chrome error pages)", "122%"},
+ {data_url, data_url, "122%"},
+ {http_host, http_host, "122%"}},
+ 3U);
base::Value::List args;
handler()->HandleFetchZoomLevels(args);
- ValidateZoom(host, "122%", 2U);
+ ValidateZoom({{error_host, "(Chrome error pages)", "122%"},
+ {data_url, data_url, "122%"},
+ {http_host, http_host, "122%"}},
+ 4U);
- args.Append("http://www.google.com");
+ args.Append(http_host);
+ handler()->HandleRemoveZoomLevel(args);
+ args.front() = base::Value(error_host);
+ handler()->HandleRemoveZoomLevel(args);
+ args.front() = base::Value(data_url);
handler()->HandleRemoveZoomLevel(args);
- ValidateZoom("", "", 3U);
+ ValidateZoom({}, 7U);
double default_level = host_zoom_map->GetDefaultZoomLevel();
- double level = host_zoom_map->GetZoomLevelForHostAndScheme("http", host);
+ double level = host_zoom_map->GetZoomLevelForHostAndScheme("http", http_host);
+ EXPECT_EQ(default_level, level);
+}
+
+class SiteSettingsHandlerIsolatedWebAppTest : public SiteSettingsHandlerTest {
+ public:
+ void SetUp() override {
+ web_app::test::AwaitStartWebAppProviderAndSubsystems(profile());
+ InstallIsolatedWebApp(iwa_url(), "IWA Name");
+
+ SiteSettingsHandlerTest::SetUp();
+ }
+
+ protected:
+ GURL iwa_url() {
+ return GURL(
+ "isolated-app://"
+ "aerugqztij5biqquuk3mfwpsaibuegaqcitgfchwuosuofdjabzqaaic");
+ }
+
+ web_app::AppId InstallIsolatedWebApp(const GURL& iwa_url,
+ const std::string& name) {
+ web_app::AppId app_id =
+ web_app::AddDummyIsolatedAppToRegistry(profile(), iwa_url, name);
+ RegisterWebApp(profile(), MakeApp(app_id, apps::AppType::kWeb,
+ iwa_url.spec(), apps::Readiness::kReady,
+ apps::InstallReason::kUser));
+ return app_id;
+ }
+
+ content::HostZoomMap* GetIwaHostZoomMap(const GURL& url) {
+ auto url_info = *web_app::IsolatedWebAppUrlInfo::Create(url);
+ content::StoragePartition* iwa_partition = profile()->GetStoragePartition(
+ url_info.storage_partition_config(profile()));
+ return content::HostZoomMap::GetForStoragePartition(iwa_partition);
+ }
+};
+
+TEST_F(SiteSettingsHandlerIsolatedWebAppTest, AllSitesDisplaysAppName) {
+ GURL https_url("https://" + iwa_url().host());
+
+ SetupModelsWithIsolatedWebAppData(iwa_url().spec(), 50);
+ HostContentSettingsMap* map =
+ HostContentSettingsMapFactory::GetForProfile(profile());
+ map->SetContentSettingDefaultScope(iwa_url(), iwa_url(),
+ ContentSettingsType::NOTIFICATIONS,
+ CONTENT_SETTING_BLOCK);
+ map->SetContentSettingDefaultScope(https_url, https_url,
+ ContentSettingsType::NOTIFICATIONS,
+ CONTENT_SETTING_BLOCK);
+
+ base::Value::List site_groups = GetOnStorageFetchedSentList();
+
+ ASSERT_EQ(site_groups.size(), 2u);
+ const base::Value::Dict& group1 = site_groups[0].GetDict();
+ const base::Value::Dict& origin1 =
+ CHECK_DEREF(group1.FindList("origins"))[0].GetDict();
+ EXPECT_THAT(CHECK_DEREF(group1.FindString("groupingKey")),
+ IsOrigin(iwa_url()));
+ EXPECT_EQ(group1.FindString("etldPlus1"), nullptr);
+ EXPECT_EQ(CHECK_DEREF(group1.FindString("displayName")), "IWA Name");
+ EXPECT_EQ(CHECK_DEREF(origin1.FindString("origin")), iwa_url());
+ EXPECT_EQ(origin1.FindDouble("usage").value(), 50.0);
+
+ const base::Value::Dict& group2 = site_groups[1].GetDict();
+ const base::Value::Dict& origin2 =
+ CHECK_DEREF(group2.FindList("origins"))[0].GetDict();
+ EXPECT_THAT(CHECK_DEREF(group2.FindString("groupingKey")),
+ IsEtldPlus1(iwa_url().host()));
+ EXPECT_EQ(CHECK_DEREF(group2.FindString("etldPlus1")), iwa_url().host());
+ EXPECT_EQ(CHECK_DEREF(group2.FindString("displayName")), iwa_url().host());
+ EXPECT_EQ(CHECK_DEREF(origin2.FindString("origin")), https_url);
+ EXPECT_EQ(origin2.FindDouble("usage").value(), 0.0);
+}
+
+TEST_F(SiteSettingsHandlerIsolatedWebAppTest, ZoomLevel) {
+ content::HostZoomMap* iwa_host_zoom_map = GetIwaHostZoomMap(iwa_url());
+
+ std::string host_or_spec = url::Origin::Create(iwa_url()).Serialize();
+ iwa_host_zoom_map->SetZoomLevelForHost(iwa_url().host(), 1.1);
+ ValidateZoom({{host_or_spec, "IWA Name", "122%"}}, 1U);
+
+ base::Value::List args;
+ handler()->HandleFetchZoomLevels(args);
+ ValidateZoom({{host_or_spec, "IWA Name", "122%"}}, 2U);
+
+ args.Append(host_or_spec);
+ handler()->HandleRemoveZoomLevel(args);
+ ValidateZoom({}, 3U);
+
+ double default_level = iwa_host_zoom_map->GetDefaultZoomLevel();
+ double level = iwa_host_zoom_map->GetZoomLevelForHostAndScheme(
+ "isolated-app", iwa_url().host());
EXPECT_EQ(default_level, level);
}
+TEST_F(SiteSettingsHandlerIsolatedWebAppTest, ZoomLevelsSortedByAppName) {
+ GetIwaHostZoomMap(iwa_url())->SetZoomLevelForHost(iwa_url().host(), 1.1);
+
+ // Install 3 more IWAs.
+ GURL iwa3_url(
+ "isolated-app://"
+ "cerugqztij5biqquuk3mfwpsaibuegaqcitgfchwuosuofdjabzqaaic");
+ InstallIsolatedWebApp(iwa3_url, "IWA Name 3");
+ GetIwaHostZoomMap(iwa3_url)->SetZoomLevelForHost(iwa3_url.host(), 1.1);
+
+ GURL iwa2_url(
+ "isolated-app://"
+ "berugqztij5biqquuk3mfwpsaibuegaqcitgfchwuosuofdjabzqaaic");
+ InstallIsolatedWebApp(iwa2_url, "IWA Name 2");
+ GetIwaHostZoomMap(iwa2_url)->SetZoomLevelForHost(iwa2_url.host(), 1.1);
+
+ // Don't set a zoom for this app to make sure it's not in the list.
+ GURL iwa4_url(
+ "isolated-app://"
+ "derugqztij5biqquuk3mfwpsaibuegaqcitgfchwuosuofdjabzqaaic");
+ InstallIsolatedWebApp(iwa4_url, "IWA Name 4");
+
+ base::Value::List args;
+ handler()->HandleFetchZoomLevels(args);
+
+ ValidateZoom(
+ {{url::Origin::Create(iwa_url()).Serialize(), "IWA Name", "122%"},
+ {url::Origin::Create(iwa2_url).Serialize(), "IWA Name 2", "122%"},
+ {url::Origin::Create(iwa3_url).Serialize(), "IWA Name 3", "122%"}},
+ 2U);
+}
+
class SiteSettingsHandlerInfobarTest : public BrowserWithTestWindowTest {
public:
SiteSettingsHandlerInfobarTest()
@@ -2610,9 +2674,8 @@ TEST_F(SiteSettingsHandlerTest, ExcludeWebUISchemesInLists) {
EXPECT_EQ(1UL, site_groups.size());
const base::Value::Dict& first_site_group = site_groups[0].GetDict();
- const std::string etld_plus1_string =
- CHECK_DEREF(first_site_group.FindString("etldPlus1"));
- EXPECT_EQ("example.com", etld_plus1_string);
+ EXPECT_THAT(CHECK_DEREF(first_site_group.FindString("groupingKey")),
+ IsEtldPlus1("example.com"));
const base::Value::List& origin_list =
CHECK_DEREF(first_site_group.FindList("origins"));
EXPECT_EQ(1UL, origin_list.size());
@@ -3964,7 +4027,6 @@ TEST_F(SiteSettingsHandlerBluetoothTest, HandleSetOriginPermissionsPolicyOnly) {
TestHandleSetOriginPermissionsPolicyOnly();
}
-#if !BUILDFLAG(IS_ANDROID)
class SiteSettingsHandlerHidTest
: public SiteSettingsHandlerChooserExceptionTest {
protected:
@@ -4099,12 +4161,14 @@ class SiteSettingsHandlerHidTest
base::Value GetPersistentDeviceValueForOrigin(
const url::Origin& origin) override {
- return HidChooserContext::DeviceInfoToValue(*persistent_device_);
+ return base::Value(
+ HidChooserContext::DeviceInfoToValue(*persistent_device_));
}
base::Value GetUserGrantedDeviceValueForOrigin(
const url::Origin& origin) override {
- return HidChooserContext::DeviceInfoToValue(*user_granted_device_);
+ return base::Value(
+ HidChooserContext::DeviceInfoToValue(*user_granted_device_));
}
std::string GetAllDevicesDisplayName() override { return "Any HID device"; }
@@ -4343,12 +4407,14 @@ class SiteSettingsHandlerSerialTest
base::Value GetPersistentDeviceValueForOrigin(
const url::Origin& origin) override {
- return SerialChooserContext::PortInfoToValue(*persistent_port_);
+ return base::Value(
+ SerialChooserContext::PortInfoToValue(*persistent_port_));
}
base::Value GetUserGrantedDeviceValueForOrigin(
const url::Origin& origin) override {
- return SerialChooserContext::PortInfoToValue(*user_granted_port_);
+ return base::Value(
+ SerialChooserContext::PortInfoToValue(*user_granted_port_));
}
std::string GetAllDevicesDisplayName() override { return "Any serial port"; }
@@ -4405,7 +4471,6 @@ TEST_F(SiteSettingsHandlerSerialTest, HandleSetOriginPermissions) {
TEST_F(SiteSettingsHandlerSerialTest, HandleSetOriginPermissionsPolicyOnly) {
TestHandleSetOriginPermissionsPolicyOnly();
}
-#endif // !BUILDFLAG(IS_ANDROID)
class SiteSettingsHandlerUsbTest
: public SiteSettingsHandlerChooserExceptionTest {
@@ -4545,12 +4610,14 @@ class SiteSettingsHandlerUsbTest
base::Value GetPersistentDeviceValueForOrigin(
const url::Origin& origin) override {
- return UsbChooserContext::DeviceInfoToValue(*persistent_device_);
+ return base::Value(
+ UsbChooserContext::DeviceInfoToValue(*persistent_device_));
}
base::Value GetUserGrantedDeviceValueForOrigin(
const url::Origin& origin) override {
- return UsbChooserContext::DeviceInfoToValue(*user_granted_device_);
+ return base::Value(
+ UsbChooserContext::DeviceInfoToValue(*user_granted_device_));
}
std::string GetAllDevicesDisplayName() override {
@@ -4610,7 +4677,7 @@ TEST_F(SiteSettingsHandlerUsbTest, HandleSetOriginPermissionsPolicyOnly) {
TestHandleSetOriginPermissionsPolicyOnly();
}
-TEST_F(SiteSettingsHandlerTest, HandleClearEtldPlus1DataAndCookies) {
+TEST_F(SiteSettingsHandlerTest, HandleClearSiteGroupDataAndCookies) {
SetupModels();
EXPECT_EQ(28u,
@@ -4619,10 +4686,8 @@ TEST_F(SiteSettingsHandlerTest, HandleClearEtldPlus1DataAndCookies) {
auto verify_site_group = [](const base::Value& site_group,
std::string expected_etld_plus1) {
ASSERT_TRUE(site_group.is_dict());
- const std::string* etld_plus1 =
- site_group.GetDict().FindString("etldPlus1");
- ASSERT_TRUE(etld_plus1);
- ASSERT_EQ(expected_etld_plus1, *etld_plus1);
+ ASSERT_THAT(CHECK_DEREF(site_group.GetDict().FindString("groupingKey")),
+ IsEtldPlus1(expected_etld_plus1));
};
base::Value::List storage_and_cookie_list = GetOnStorageFetchedSentList();
@@ -4630,8 +4695,8 @@ TEST_F(SiteSettingsHandlerTest, HandleClearEtldPlus1DataAndCookies) {
verify_site_group(storage_and_cookie_list[0], "example.com");
base::Value::List args;
- args.Append("example.com");
- handler()->HandleClearEtldPlus1DataAndCookies(args);
+ args.Append(GroupingKey::CreateFromEtldPlus1("example.com").Serialize());
+ handler()->HandleClearSiteGroupDataAndCookies(args);
// All host nodes for non-secure example.com, and abc.example.com, which do
// not have any unpartitioned storage, should have been removed.
@@ -4664,9 +4729,9 @@ TEST_F(SiteSettingsHandlerTest, HandleClearEtldPlus1DataAndCookies) {
verify_site_group(storage_and_cookie_list[0], "google.com");
args.clear();
- args.Append("google.com");
+ args.Append(GroupingKey::CreateFromEtldPlus1("google.com").Serialize());
- handler()->HandleClearEtldPlus1DataAndCookies(args);
+ handler()->HandleClearSiteGroupDataAndCookies(args);
EXPECT_EQ(14u,
handler()->cookies_tree_model_->GetRoot()->GetTotalNodeCount());
@@ -4676,9 +4741,9 @@ TEST_F(SiteSettingsHandlerTest, HandleClearEtldPlus1DataAndCookies) {
verify_site_group(storage_and_cookie_list[0], "google.com.au");
args.clear();
- args.Append("google.com.au");
+ args.Append(GroupingKey::CreateFromEtldPlus1("google.com.au").Serialize());
- handler()->HandleClearEtldPlus1DataAndCookies(args);
+ handler()->HandleClearSiteGroupDataAndCookies(args);
// No nodes representing storage partitioned on google.com.au should be
// present.
for (const auto& host_node :
@@ -4703,9 +4768,9 @@ TEST_F(SiteSettingsHandlerTest, HandleClearEtldPlus1DataAndCookies) {
verify_site_group(storage_and_cookie_list[0], "ungrouped.com");
args.clear();
- args.Append("ungrouped.com");
+ args.Append(GroupingKey::CreateFromEtldPlus1("ungrouped.com").Serialize());
- handler()->HandleClearEtldPlus1DataAndCookies(args);
+ handler()->HandleClearSiteGroupDataAndCookies(args);
storage_and_cookie_list = GetOnStorageFetchedSentList();
EXPECT_EQ(0U, storage_and_cookie_list.size());
@@ -4775,8 +4840,7 @@ TEST_P(SiteSettingsHandlerTest, HandleClearUnpartitionedUsage) {
// In the beginning, there should be nothing stored in the origin data.
ASSERT_EQ(0u, user_prefs->GetDict(prefs::kMediaCdmOriginData).size());
- base::Value::Dict entry_google;
- entry_google.Set(
+ auto entry_google = base::Value::Dict().Set(
"https://www.google.com/",
base::UnguessableTokenToValue(base::UnguessableToken::Create()));
@@ -4842,8 +4906,8 @@ TEST_F(SiteSettingsHandlerTest, ClearClientHints) {
// Clear at the eTLD+1 level and ensure affected origins are cleared.
base::Value::List args;
- args.Append("example.com");
- handler()->HandleClearEtldPlus1DataAndCookies(args);
+ args.Append(GroupingKey::CreateFromEtldPlus1("example.com").Serialize());
+ handler()->HandleClearSiteGroupDataAndCookies(args);
host_content_settings_map->GetSettingsForOneType(
ContentSettingsType::CLIENT_HINTS, &client_hints_settings);
EXPECT_EQ(2U, client_hints_settings.size());
@@ -4917,8 +4981,8 @@ TEST_F(SiteSettingsHandlerTest, ClearReducedAcceptLanguage) {
// Clear at the eTLD+1 level and ensure affected origins are cleared.
base::Value::List args;
- args.Append("example.com");
- handler()->HandleClearEtldPlus1DataAndCookies(args);
+ args.Append(GroupingKey::CreateFromEtldPlus1("example.com").Serialize());
+ handler()->HandleClearSiteGroupDataAndCookies(args);
host_content_settings_map->GetSettingsForOneType(
ContentSettingsType::REDUCED_ACCEPT_LANGUAGE, &accept_language_settings);
EXPECT_EQ(2U, accept_language_settings.size());
@@ -4980,7 +5044,7 @@ TEST_F(SiteSettingsHandlerTest, HandleClearPartitionedUsage) {
base::Value::List args;
args.Append("https://www.example.com/");
- args.Append("google.com");
+ args.Append(GroupingKey::CreateFromEtldPlus1("google.com").Serialize());
handler()->HandleClearPartitionedUsage(args);
// This should have only removed cookies for embedded.com partitioned on
@@ -5180,11 +5244,20 @@ TEST_F(SiteSettingsHandlerTest, HandleGetUsageInfo) {
handler()->ServicePendingRequests();
ValidateUsageInfo("http://google.com", "", "2 cookies",
"2 sites in google.com's group", false);
+
args.clear();
args.Append("http://ungrouped.com");
handler()->HandleFetchUsageTotal(args);
handler()->ServicePendingRequests();
ValidateUsageInfo("http://ungrouped.com", "", "1 cookie", "", false);
+
+ // Test that the argument URL formatting is preserved in the response because
+ // the UI ignores responses with different URL strings.
+ args.clear();
+ args.Append("http://ungrouped.com//");
+ handler()->HandleFetchUsageTotal(args);
+ handler()->ServicePendingRequests();
+ ValidateUsageInfo("http://ungrouped.com//", "", "1 cookie", "", false);
}
TEST_F(SiteSettingsHandlerTest, NonTreeModelDeletion) {
@@ -5202,8 +5275,8 @@ TEST_F(SiteSettingsHandlerTest, NonTreeModelDeletion) {
url::Origin::Create(GURL("https://google.com"))));
base::Value::List args;
- args.Append("google.com");
- handler()->HandleClearEtldPlus1DataAndCookies(args);
+ args.Append(GroupingKey::CreateFromEtldPlus1("google.com").Serialize());
+ handler()->HandleClearSiteGroupDataAndCookies(args);
auto* browsing_data_remover = profile()->GetBrowsingDataRemover();
EXPECT_EQ(content::BrowsingDataRemover::DATA_TYPE_PRIVACY_SANDBOX &
@@ -5247,241 +5320,10 @@ TEST_F(SiteSettingsHandlerTest, FirstPartySetsMembership) {
ValidateSitesWithFps(storage_and_cookie_list, first_party_sets);
}
-TEST_F(SiteSettingsHandlerTest,
- HandleIgnoreOriginsForNotificationPermissionReview) {
- base::test::ScopedFeatureList scoped_feature;
- scoped_feature.InitAndEnableFeature(
- ::features::kSafetyCheckNotificationPermissions);
-
- HostContentSettingsMap* content_settings =
- HostContentSettingsMapFactory::GetForProfile(profile());
- ContentSettingsForOneType ignored_patterns;
- content_settings->GetSettingsForOneType(
- ContentSettingsType::NOTIFICATION_PERMISSION_REVIEW, &ignored_patterns);
- ASSERT_EQ(0U, ignored_patterns.size());
-
- base::Value::List args;
- args.Append(GetOriginList(1));
- handler()->HandleIgnoreOriginsForNotificationPermissionReview(args);
-
- // Check there is 1 origin in ignore list.
- content_settings->GetSettingsForOneType(
- ContentSettingsType::NOTIFICATION_PERMISSION_REVIEW, &ignored_patterns);
- ASSERT_EQ(1U, ignored_patterns.size());
-
- ValidateNotificationPermissionUpdate();
-}
-
-TEST_F(SiteSettingsHandlerTest, HandleBlockNotificationPermissionForOrigins) {
- base::test::ScopedFeatureList scoped_feature;
- scoped_feature.InitAndEnableFeature(
- ::features::kSafetyCheckNotificationPermissions);
-
- base::Value::List args;
- base::Value::List origins = GetOriginList(2);
- args.Append(origins.Clone());
-
- handler()->HandleBlockNotificationPermissionForOrigins(args);
-
- // Check the permission for the two origins is block.
- HostContentSettingsMap* content_settings =
- HostContentSettingsMapFactory::GetForProfile(profile());
- ContentSettingsForOneType notification_permissions;
- content_settings->GetSettingsForOneType(ContentSettingsType::NOTIFICATIONS,
- &notification_permissions);
- auto type = content_settings->GetContentSetting(
- GURL(origins[0].GetString()), GURL(), ContentSettingsType::NOTIFICATIONS);
- ASSERT_EQ(CONTENT_SETTING_BLOCK, type);
-
- type = content_settings->GetContentSetting(
- GURL(origins[1].GetString()), GURL(), ContentSettingsType::NOTIFICATIONS);
- ASSERT_EQ(CONTENT_SETTING_BLOCK, type);
-
- ValidateNotificationPermissionUpdate();
-}
-
-TEST_F(SiteSettingsHandlerTest, HandleAllowNotificationPermissionForOrigins) {
- base::test::ScopedFeatureList scoped_feature;
- scoped_feature.InitAndEnableFeature(
- ::features::kSafetyCheckNotificationPermissions);
-
- base::Value::List args;
- base::Value::List origins = GetOriginList(2);
- args.Append(origins.Clone());
- handler()->HandleAllowNotificationPermissionForOrigins(args);
-
- // Check the permission for the two origins is allow.
- HostContentSettingsMap* content_settings =
- HostContentSettingsMapFactory::GetForProfile(profile());
- ContentSettingsForOneType notification_permissions;
- content_settings->GetSettingsForOneType(ContentSettingsType::NOTIFICATIONS,
- &notification_permissions);
- auto type = content_settings->GetContentSetting(
- GURL(origins[0].GetString()), GURL(), ContentSettingsType::NOTIFICATIONS);
- ASSERT_EQ(CONTENT_SETTING_ALLOW, type);
-
- type = content_settings->GetContentSetting(
- GURL(origins[1].GetString()), GURL(), ContentSettingsType::NOTIFICATIONS);
- ASSERT_EQ(CONTENT_SETTING_ALLOW, type);
-
- ValidateNotificationPermissionUpdate();
-}
-
-TEST_F(SiteSettingsHandlerTest, HandleResetNotificationPermissionForOrigins) {
- base::test::ScopedFeatureList scoped_feature;
- scoped_feature.InitAndEnableFeature(
- ::features::kSafetyCheckNotificationPermissions);
-
- HostContentSettingsMap* content_settings =
- HostContentSettingsMapFactory::GetForProfile(profile());
- base::Value::List args;
- base::Value::List origins = GetOriginList(1);
- args.Append(origins.Clone());
-
- content_settings->SetContentSettingCustomScope(
- ContentSettingsPattern::FromString(origins[0].GetString()),
- ContentSettingsPattern::Wildcard(), ContentSettingsType::NOTIFICATIONS,
- CONTENT_SETTING_ALLOW);
-
- handler()->HandleResetNotificationPermissionForOrigins(args);
-
- // Check the permission for the origin is reset.
- auto type = content_settings->GetContentSetting(
- GURL(origins[0].GetString()), GURL(), ContentSettingsType::NOTIFICATIONS);
- ASSERT_EQ(CONTENT_SETTING_ASK, type);
-
- ValidateNotificationPermissionUpdate();
-}
-
-TEST_F(SiteSettingsHandlerTest, PopulateNotificationPermissionReviewData) {
- base::test::ScopedFeatureList scoped_feature;
- scoped_feature.InitAndEnableFeature(
- ::features::kSafetyCheckNotificationPermissions);
-
- // Add a couple of notification permission and check they appear in review
- // list.
- HostContentSettingsMap* map =
- HostContentSettingsMapFactory::GetForProfile(profile());
- GURL urls[] = {GURL("https://google.com:443"),
- GURL("https://www.youtube.com:443"),
- GURL("https://www.example.com:443")};
-
- map->SetContentSettingDefaultScope(urls[0], GURL(),
- ContentSettingsType::NOTIFICATIONS,
- CONTENT_SETTING_ALLOW);
- map->SetContentSettingDefaultScope(urls[1], GURL(),
- ContentSettingsType::NOTIFICATIONS,
- CONTENT_SETTING_ALLOW);
- map->SetContentSettingDefaultScope(urls[2], GURL(),
- ContentSettingsType::NOTIFICATIONS,
- CONTENT_SETTING_ALLOW);
-
- // Record initial display date to enable comparing dictionaries for
- // NotificationEngagementService.
- auto* notification_engagement_service =
- NotificationsEngagementServiceFactory::GetForProfile(profile());
- std::string displayedDate =
- notification_engagement_service->GetBucketLabel(base::Time::Now());
-
- auto* site_engagement_service =
- site_engagement::SiteEngagementServiceFactory::GetForProfile(profile());
-
- // Set a host to have minimum engagement. This should be in review list.
- RecordNotification(notification_engagement_service, urls[0], 1);
- site_engagement::SiteEngagementScore score =
- site_engagement_service->CreateEngagementScore(urls[0]);
- score.Reset(0.5, GetReferenceTime());
- score.Commit();
- EXPECT_EQ(blink::mojom::EngagementLevel::MINIMAL,
- site_engagement_service->GetEngagementLevel(urls[0]));
-
- // Set a host to have large number of notifications, but low engagement. This
- // should be in review list.
- RecordNotification(notification_engagement_service, urls[1], 5);
- site_engagement_service->AddPointsForTesting(urls[1], 1.0);
- EXPECT_EQ(blink::mojom::EngagementLevel::LOW,
- site_engagement_service->GetEngagementLevel(urls[1]));
-
- // Set a host to have medium engagement and high notification count. This
- // should not be in review list.
- RecordNotification(notification_engagement_service, urls[2], 5);
- site_engagement_service->AddPointsForTesting(urls[2], 50.0);
- EXPECT_EQ(blink::mojom::EngagementLevel::MEDIUM,
- site_engagement_service->GetEngagementLevel(urls[2]));
-
- const auto& notification_permissions =
- handler()->PopulateNotificationPermissionReviewData();
- // Check if resulting list contains only the expected URLs. They should be in
- // descending order of notification count.
- EXPECT_EQ(2UL, notification_permissions.size());
- EXPECT_EQ("https://www.youtube.com:443",
- *notification_permissions[0].GetDict().FindString(
- site_settings::kOrigin));
- EXPECT_EQ("https://google.com:443",
- *notification_permissions[1].GetDict().FindString(
- site_settings::kOrigin));
-
- // Increasing notification count also promotes host in the list.
- RecordNotification(notification_engagement_service,
- GURL("https://google.com:443"), 10);
- const auto& updated_notification_permissions =
- handler()->PopulateNotificationPermissionReviewData();
- EXPECT_EQ(2UL, updated_notification_permissions.size());
- EXPECT_EQ("https://google.com:443",
- *updated_notification_permissions[0].GetDict().FindString(
- site_settings::kOrigin));
- EXPECT_EQ("https://www.youtube.com:443",
- *updated_notification_permissions[1].GetDict().FindString(
- site_settings::kOrigin));
-}
-
-TEST_F(SiteSettingsHandlerTest,
- HandleUndoIgnoreOriginsForNotificationPermissionReview) {
- base::Value::List args;
- args.Append(GetOriginList(1));
- handler()->HandleIgnoreOriginsForNotificationPermissionReview(args);
-
- // Check there is 1 origin in ignore list.
- HostContentSettingsMap* content_settings =
- HostContentSettingsMapFactory::GetForProfile(profile());
- ContentSettingsForOneType ignored_patterns;
- ASSERT_EQ(0U, ignored_patterns.size());
- content_settings->GetSettingsForOneType(
- ContentSettingsType::NOTIFICATION_PERMISSION_REVIEW, &ignored_patterns);
- ASSERT_EQ(1U, ignored_patterns.size());
-
- // Check there are no origins in ignore list.
- handler()->HandleUndoIgnoreOriginsForNotificationPermissionReview(args);
- content_settings->GetSettingsForOneType(
- ContentSettingsType::NOTIFICATION_PERMISSION_REVIEW, &ignored_patterns);
- ASSERT_EQ(0U, ignored_patterns.size());
-}
-
-TEST_F(SiteSettingsHandlerTest,
- SendNotificationPermissionReviewList_FeatureEnabled) {
- base::test::ScopedFeatureList scoped_feature;
- scoped_feature.InitAndEnableFeature(
- ::features::kSafetyCheckNotificationPermissions);
-
- handler()->SendNotificationPermissionReviewList();
-
- ValidateNotificationPermissionUpdate();
-}
-
-TEST_F(SiteSettingsHandlerTest,
- SendNotificationPermissionReviewList_FeatureDisabled) {
- base::test::ScopedFeatureList scoped_feature;
- scoped_feature.InitAndDisableFeature(
- ::features::kSafetyCheckNotificationPermissions);
-
- handler()->SendNotificationPermissionReviewList();
-
- ASSERT_EQ(0U, web_ui()->call_data().size());
-}
-
TEST_F(SiteSettingsHandlerTest, IsolatedWebAppUsageInfo) {
std::string iwa_url =
- "isolated-app://aerugqztij5biqquuk3mfwpsaibuegaqcitgfchwuosuofdjabzqaaic";
+ "isolated-app://"
+ "aerugqztij5biqquuk3mfwpsaibuegaqcitgfchwuosuofdjabzqaaic/";
SetupModelsWithIsolatedWebAppData(iwa_url, 1000);
base::Value::List args;
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 60957ef4bd5..0bc74c27f99 100644
--- a/chromium/chrome/browser/ui/webui/settings/site_settings_helper.cc
+++ b/chromium/chrome/browser/ui/webui/settings/site_settings_helper.cc
@@ -27,6 +27,7 @@
#include "chrome/browser/file_system_access/file_system_access_permission_context_factory.h"
#include "chrome/browser/hid/hid_chooser_context.h"
#include "chrome/browser/hid/hid_chooser_context_factory.h"
+#include "chrome/browser/permissions/notification_permission_review_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/serial/serial_chooser_context.h"
#include "chrome/browser/serial/serial_chooser_context_factory.h"
@@ -34,9 +35,14 @@
#include "chrome/browser/ui/url_identity.h"
#include "chrome/browser/usb/usb_chooser_context.h"
#include "chrome/browser/usb/usb_chooser_context_factory.h"
+#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.h"
+#include "chrome/browser/web_applications/web_app.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
+#include "chrome/grit/generated_resources.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"
@@ -49,6 +55,7 @@
#include "components/permissions/permissions_client.h"
#include "components/prefs/pref_service.h"
#include "components/privacy_sandbox/privacy_sandbox_features.h"
+#include "components/site_engagement/content/site_engagement_service.h"
#include "components/subresource_filter/content/browser/subresource_filter_content_settings_manager.h"
#include "components/subresource_filter/content/browser/subresource_filter_profile_context.h"
#include "components/subresource_filter/core/browser/subresource_filter_features.h"
@@ -60,8 +67,10 @@
#include "content/public/common/url_utils.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/constants.h"
+#include "services/network/public/cpp/features.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/permissions/permission_utils.h"
+#include "ui/base/l10n/l10n_util.h"
#include "url/origin.h"
namespace site_settings {
@@ -80,7 +89,7 @@ const char kBluetoothChooserDataGroupType[] = "bluetooth-devices-data";
const ContentSettingsTypeNameEntry kContentSettingsTypeGroupNames[] = {
// The following ContentSettingsTypes have UI in Content Settings
// and require a mapping from their Javascript string representation in
- // chrome/browser/resources/settings/site_settings/constants.js to their C++
+ // chrome/browser/resources/settings/site_settings/constants.ts to their C++
// ContentSettingsType provided here. These group names are only used by
// desktop webui.
{ContentSettingsType::COOKIES, "cookies"},
@@ -125,6 +134,7 @@ const ContentSettingsTypeNameEntry kContentSettingsTypeGroupNames[] = {
{ContentSettingsType::PRIVATE_NETWORK_CHOOSER_DATA,
"private-network-devices-data"},
{ContentSettingsType::ANTI_ABUSE, "anti-abuse"},
+ {ContentSettingsType::STORAGE_ACCESS, "storage-access"},
// Add new content settings here if a corresponding Javascript string
// representation for it is not required, for example if the content setting
@@ -155,7 +165,6 @@ const ContentSettingsTypeNameEntry kContentSettingsTypeGroupNames[] = {
{ContentSettingsType::NFC, nullptr},
{ContentSettingsType::SAFE_BROWSING_URL_CHECK_DATA, nullptr},
{ContentSettingsType::FILE_SYSTEM_READ_GUARD, nullptr},
- {ContentSettingsType::STORAGE_ACCESS, nullptr},
{ContentSettingsType::CAMERA_PAN_TILT_ZOOM, nullptr},
{ContentSettingsType::INSECURE_LOCAL_NETWORK, nullptr},
{ContentSettingsType::PERMISSION_AUTOREVOCATION_DATA, nullptr},
@@ -169,7 +178,6 @@ const ContentSettingsTypeNameEntry kContentSettingsTypeGroupNames[] = {
{ContentSettingsType::FEDERATED_IDENTITY_ACTIVE_SESSION, nullptr},
{ContentSettingsType::AUTO_DARK_WEB_CONTENT, nullptr},
{ContentSettingsType::REQUEST_DESKTOP_SITE, nullptr},
- {ContentSettingsType::GET_DISPLAY_MEDIA_SET_SELECT_ALL_SCREENS, nullptr},
{ContentSettingsType::NOTIFICATION_INTERACTIONS, nullptr},
{ContentSettingsType::REDUCED_ACCEPT_LANGUAGE, nullptr},
{ContentSettingsType::NOTIFICATION_PERMISSION_REVIEW, nullptr},
@@ -186,6 +194,7 @@ const ContentSettingsTypeNameEntry kContentSettingsTypeGroupNames[] = {
{ContentSettingsType::FEDERATED_IDENTITY_IDENTITY_PROVIDER_REGISTRATION,
nullptr},
{ContentSettingsType::THIRD_PARTY_STORAGE_PARTITIONING, nullptr},
+ {ContentSettingsType::ALL_SCREEN_CAPTURE, nullptr},
};
static_assert(std::size(kContentSettingsTypeGroupNames) ==
@@ -420,17 +429,49 @@ const ChooserTypeNameEntry kChooserTypeGroupNames[] = {
{&GetHidChooserContext, kHidChooserDataGroupType},
{&GetBluetoothChooserContext, kBluetoothChooserDataGroupType}};
-// There are two FormatOptions to support both hostname-only and schemeful URL
-// formatting, both of which are used in Site Settings.
-constexpr UrlIdentity::FormatOptions kUrlIdentityOptionsWithScheme = {
+// These variables represent different formatting options for default (i.e. not
+// extension or IWA) URLs as well as fallbacks for when the IWA/extension is not
+// found in the registry.
+constexpr UrlIdentity::FormatOptions kUrlIdentityOptionsOmitHttps = {
.default_options = {
UrlIdentity::DefaultFormatOptions::kOmitCryptographicScheme}};
-constexpr UrlIdentity::FormatOptions kUrlIdentityOptionsHostnameOnly = {
+constexpr UrlIdentity::FormatOptions kUrlIdentityOptionsHostOnly = {
.default_options = {UrlIdentity::DefaultFormatOptions::kHostname}};
+constexpr UrlIdentity::FormatOptions kUrlIdentityOptionsRawSpec = {
+ .default_options = {UrlIdentity::DefaultFormatOptions::kRawSpec}};
+
constexpr UrlIdentity::TypeSet kUrlIdentityAllowedTypes = {
UrlIdentity::Type::kDefault, UrlIdentity::Type::kFile,
UrlIdentity::Type::kIsolatedWebApp, UrlIdentity::Type::kChromeExtension};
+bool ShouldAddToNotificationPermissionReviewList(
+ site_engagement::SiteEngagementService* service,
+ GURL url,
+ int notification_count) {
+ // The notification permission should be added to the list if one of the
+ // criteria below holds:
+ // - Site engagement level is NONE OR MINIMAL and average daily notification
+ // count is more than 0.
+ // - Site engamment level is LOW and average daily notification count is
+ // more than 3. Otherwise, the notification permission should not be added
+ // to review list.
+ double score = service->GetScore(url);
+ int low_engagement_notification_limit =
+ features::kSafetyCheckNotificationPermissionsLowEnagementLimit.Get();
+ bool is_low_engagement =
+ !site_engagement::SiteEngagementService::IsEngagementAtLeast(
+ score, blink::mojom::EngagementLevel::MEDIUM) &&
+ notification_count > low_engagement_notification_limit;
+ int min_engagement_notification_limit =
+ features::kSafetyCheckNotificationPermissionsMinEnagementLimit.Get();
+ bool is_minimal_engagement =
+ !site_engagement::SiteEngagementService::IsEngagementAtLeast(
+ score, blink::mojom::EngagementLevel::LOW) &&
+ notification_count > min_engagement_notification_limit;
+
+ return is_minimal_engagement || is_low_engagement;
+}
+
} // namespace
bool HasRegisteredGroupName(ContentSettingsType type) {
@@ -458,12 +499,18 @@ ContentSettingsType ContentSettingsTypeFromGroupName(base::StringPiece name) {
}
base::StringPiece ContentSettingsTypeToGroupName(ContentSettingsType type) {
- for (size_t i = 0; i < std::size(kContentSettingsTypeGroupNames); ++i) {
- if (type == kContentSettingsTypeGroupNames[i].type) {
- const char* name = kContentSettingsTypeGroupNames[i].name;
- if (name)
- return name;
- break;
+ for (const auto& entry : kContentSettingsTypeGroupNames) {
+ if (type == entry.type) {
+ // Content setting types that aren't represented in the settings UI
+ // will have `nullptr` as their `name`. Although they are valid content
+ // settings types, they don't have a readable name.
+ // TODO(crbug.com/1459305): Replace LOG with CHECK.
+ if (!entry.name) {
+ LOG(ERROR) << static_cast<int32_t>(type)
+ << " does not have a readable name.";
+ }
+
+ return entry.name ? entry.name : base::StringPiece();
}
}
@@ -531,7 +578,7 @@ const std::vector<ContentSettingsType>& GetVisiblePermissionCategories() {
}
if (base::FeatureList::IsEnabled(
- blink::features::kPrivateNetworkAccessPermissionPrompt)) {
+ network::features::kPrivateNetworkAccessPermissionPrompt)) {
base_types->push_back(ContentSettingsType::PRIVATE_NETWORK_GUARD);
}
@@ -626,19 +673,26 @@ base::Value::Dict GetExceptionForPage(
return exception;
}
-std::string GetDisplayNameForGURL(Profile* profile,
+UrlIdentity GetUrlIdentityForGURL(Profile* profile,
const GURL& url,
bool hostname_only) {
auto origin = url::Origin::Create(url);
if (origin.opaque()) {
- return url.spec();
+ return {.type = UrlIdentity::Type::kDefault,
+ .name = base::UTF8ToUTF16(url.spec())};
}
- auto url_identity = UrlIdentity::CreateFromUrl(
+ return UrlIdentity::CreateFromUrl(
profile, origin.GetURL(), kUrlIdentityAllowedTypes,
- hostname_only ? kUrlIdentityOptionsHostnameOnly
- : kUrlIdentityOptionsWithScheme);
- return base::UTF16ToUTF8(url_identity.name);
+ hostname_only ? kUrlIdentityOptionsHostOnly
+ : kUrlIdentityOptionsOmitHttps);
+}
+
+std::string GetDisplayNameForGURL(Profile* profile,
+ const GURL& url,
+ bool hostname_only) {
+ return base::UTF16ToUTF8(
+ GetUrlIdentityForGURL(profile, url, hostname_only).name);
}
void GetExceptionsForContentType(ContentSettingsType type,
@@ -800,19 +854,17 @@ ContentSetting GetContentSettingForOrigin(Profile* profile,
const HostContentSettingsMap* map,
const GURL& origin,
ContentSettingsType content_type,
- std::string* source_string,
- std::string* display_name) {
+ std::string* source_string) {
// TODO(patricialor): In future, PermissionManager should know about all
// content settings, not just the permissions, plus all the possible sources,
// and the calls to HostContentSettingsMap should be removed.
content_settings::SettingInfo info;
- const base::Value value =
- map->GetWebsiteSetting(origin, origin, content_type, &info);
+ ContentSetting setting =
+ map->GetContentSetting(origin, origin, content_type, &info);
// Retrieve the content setting.
permissions::PermissionResult result(
- content_settings::ValueToContentSetting(value),
- permissions::PermissionStatusSource::UNSPECIFIED);
+ setting, permissions::PermissionStatusSource::UNSPECIFIED);
if (permissions::PermissionDecisionAutoBlocker::IsEnabledForContentSetting(
content_type)) {
if (permissions::PermissionUtil::IsPermission(content_type)) {
@@ -838,10 +890,9 @@ ContentSetting GetContentSettingForOrigin(Profile* profile,
// Retrieve the source of the content setting.
*source_string = SiteSettingSourceToString(
CalculateSiteSettingSource(profile, content_type, origin, info, result));
- *display_name =
- GetDisplayNameForGURL(profile, origin, /*hostname_only=*/false);
- if (info.metadata.session_model == content_settings::SessionModel::OneTime) {
+ if (info.metadata.session_model() ==
+ content_settings::SessionModel::OneTime) {
DCHECK(
permissions::PermissionUtil::CanPermissionBeAllowedOnce(content_type));
DCHECK_EQ(result.content_setting, CONTENT_SETTING_ALLOW);
@@ -874,7 +925,7 @@ void GetFileSystemGrantedEntries(std::vector<base::Value::Dict>* exceptions,
for (const auto& grant : grants) {
const std::string url = grant->origin.spec();
- auto* const optional_path = grant->value.GetDict().Find(
+ auto* const optional_path = grant->value.Find(
ChromeFileSystemAccessPermissionContext::kPermissionPathKey);
// Ensure that the file path is found for the given kPermissionPathKey.
@@ -929,23 +980,10 @@ base::Value::Dict CreateChooserExceptionObject(
const std::string& source = std::get<1>(details);
const bool incognito = std::get<2>(details);
- std::string site_display_name = origin.spec();
-#if BUILDFLAG(ENABLE_EXTENSIONS)
- // Set the |site_display_name| to the extension's name which is more clear
- // to the user if the |origin| is for an extension and the extension name
- // can be found in the |profile|.
- if (origin.SchemeIs(extensions::kExtensionScheme)) {
- DCHECK(profile);
- const auto* extension_registry =
- extensions::ExtensionRegistry::Get(profile);
- const extensions::Extension* extension =
- extension_registry->GetExtensionById(
- origin.host(), extensions::ExtensionRegistry::EVERYTHING);
- if (extension) {
- site_display_name = extension->name();
- }
- }
-#endif
+ std::string site_display_name = base::UTF16ToUTF8(
+ UrlIdentity::CreateFromUrl(profile, origin, kUrlIdentityAllowedTypes,
+ kUrlIdentityOptionsRawSpec)
+ .name);
auto& this_provider_sites =
all_provider_sites[HostContentSettingsMap::GetProviderTypeFromSource(
@@ -1014,8 +1052,8 @@ base::Value::List GetChooserExceptionListFromProfile(
continue;
std::u16string name = chooser_context->GetObjectDisplayName(object->value);
- auto& chooser_exception_details =
- all_chooser_objects[std::make_pair(name, object->value.Clone())];
+ auto& chooser_exception_details = all_chooser_objects[std::make_pair(
+ name, base::Value(object->value.Clone()))];
std::string source = GetSourceStringForChooserException(
profile, content_type, object->source);
@@ -1036,23 +1074,83 @@ base::Value::List GetChooserExceptionListFromProfile(
return exceptions;
}
-absl::optional<std::string> GetExtensionDisplayName(Profile* profile,
- GURL url) {
- if (!url.SchemeIs(extensions::kExtensionScheme)) {
+std::vector<web_app::IsolatedWebAppUrlInfo> GetInstalledIsolatedWebApps(
+ Profile* profile) {
+ auto* web_app_provider = web_app::WebAppProvider::GetForWebApps(profile);
+ if (!web_app_provider) {
return {};
}
- auto* extension_registry = extensions::ExtensionRegistry::Get(profile);
- if (!extension_registry) {
- return {};
+
+ std::vector<web_app::IsolatedWebAppUrlInfo> iwas;
+ web_app::WebAppRegistrar& registrar = web_app_provider->registrar_unsafe();
+ for (const web_app::WebApp& web_app : registrar.GetApps()) {
+ if (!registrar.IsIsolated(web_app.app_id())) {
+ continue;
+ }
+ base::expected<web_app::IsolatedWebAppUrlInfo, std::string> url_info =
+ web_app::IsolatedWebAppUrlInfo::Create(web_app.scope());
+ if (url_info.has_value()) {
+ iwas.push_back(*url_info);
+ }
}
- // For the extension scheme, the pattern must be a valid URL.
- DCHECK(url.is_valid());
- const extensions::Extension* extension = extension_registry->GetExtensionById(
- url.host(), extensions::ExtensionRegistry::EVERYTHING);
- if (!extension) {
- return {};
+ return iwas;
+}
+
+// TODO(crbug.com/1444024): Migrate to NotificationPermissionsReviewService.
+base::Value::List PopulateNotificationPermissionReviewData(Profile* profile) {
+ base::Value::List result;
+ if (!base::FeatureList::IsEnabled(
+ features::kSafetyCheckNotificationPermissions)) {
+ return result;
}
- return extension->name();
+
+ auto* service =
+ NotificationPermissionsReviewServiceFactory::GetForProfile(profile);
+ if (!service) {
+ return result;
+ }
+
+ auto notification_permissions = service->GetNotificationSiteListForReview();
+
+ site_engagement::SiteEngagementService* engagement_service =
+ site_engagement::SiteEngagementService::Get(profile);
+
+ // Sort notification permissions by their priority for surfacing to the user.
+ auto notification_permission_ordering =
+ [](const permissions::NotificationPermissions& left,
+ const permissions::NotificationPermissions& right) {
+ return left.notification_count > right.notification_count;
+ };
+ std::sort(notification_permissions.begin(), notification_permissions.end(),
+ notification_permission_ordering);
+
+ for (const auto& notification_permission : notification_permissions) {
+ // Converting primary pattern to GURL should always be valid, since
+ // Notification Permission Review list only contains single origins. Those
+ // are filtered in
+ // NotificationPermissionsReviewService::GetNotificationSiteListForReview.
+ GURL url = GURL(notification_permission.primary_pattern.ToString());
+ DCHECK(url.is_valid());
+ if (!ShouldAddToNotificationPermissionReviewList(
+ engagement_service, url,
+ notification_permission.notification_count)) {
+ continue;
+ }
+
+ base::Value::Dict permission;
+ permission.Set(site_settings::kOrigin,
+ notification_permission.primary_pattern.ToString());
+
+ std::string notification_info_string =
+ base::UTF16ToUTF8(l10n_util::GetPluralStringFUTF16(
+ IDS_SETTINGS_SAFETY_CHECK_REVIEW_NOTIFICATION_PERMISSIONS_COUNT_LABEL,
+ notification_permission.notification_count));
+ permission.Set(site_settings::kNotificationInfoString,
+ notification_info_string);
+ result.Append(std::move(permission));
+ }
+
+ return result;
}
} // namespace site_settings
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 303d3926b77..d05b9dde71d 100644
--- a/chromium/chrome/browser/ui/webui/settings/site_settings_helper.h
+++ b/chromium/chrome/browser/ui/webui/settings/site_settings_helper.h
@@ -22,6 +22,7 @@
class HostContentSettingsMap;
class Profile;
+struct UrlIdentity;
namespace content {
class WebUI;
@@ -31,6 +32,10 @@ namespace permissions {
class ObjectPermissionContextBase;
}
+namespace web_app {
+class IsolatedWebAppUrlInfo;
+} // namespace web_app
+
namespace site_settings {
// Maps from a secondary pattern to a setting.
@@ -46,31 +51,32 @@ typedef std::map<std::pair<ContentSettingsPattern, std::string>,
using ChooserExceptionDetails = std::set<std::tuple<GURL, std::string, bool>>;
constexpr char kChooserType[] = "chooserType";
+constexpr char kDirectoryReadGrants[] = "directoryReadGrants";
+constexpr char kDirectoryWriteGrants[] = "directoryWriteGrants";
+constexpr char kDisabled[] = "disabled";
constexpr char kDisplayName[] = "displayName";
constexpr char kEmbeddingOrigin[] = "embeddingOrigin";
+constexpr char kFilePath[] = "filePath";
+constexpr char kFileReadGrants[] = "fileReadGrants";
+constexpr char kFileWriteGrants[] = "fileWriteGrants";
+constexpr char kHostOrSpec[] = "hostOrSpec";
constexpr char kIncognito[] = "incognito";
+constexpr char kIsDirectory[] = "isDirectory";
+constexpr char kIsEmbargoed[] = "isEmbargoed";
+constexpr char kIsWritable[] = "isWritable";
+constexpr char kNotificationInfoString[] = "notificationInfoString";
constexpr char kObject[] = "object";
-constexpr char kDisabled[] = "disabled";
-constexpr char kIsolatedWebAppName[] = "isolatedWebAppName";
constexpr char kOrigin[] = "origin";
constexpr char kOriginForFavicon[] = "originForFavicon";
+constexpr char kPermissions[] = "permissions";
+constexpr char kPolicyIndicator[] = "indicator";
constexpr char kRecentPermissions[] = "recentPermissions";
constexpr char kSetting[] = "setting";
constexpr char kSites[] = "sites";
-constexpr char kPolicyIndicator[] = "indicator";
constexpr char kSource[] = "source";
constexpr char kType[] = "type";
-constexpr char kIsDirectory[] = "isDirectory";
-constexpr char kIsEmbargoed[] = "isEmbargoed";
-constexpr char kIsWritable[] = "isWritable";
-constexpr char kDirectoryReadGrants[] = "directoryReadGrants";
-constexpr char kDirectoryWriteGrants[] = "directoryWriteGrants";
-constexpr char kFilePath[] = "filePath";
-constexpr char kFileReadGrants[] = "fileReadGrants";
-constexpr char kFileWriteGrants[] = "fileWriteGrants";
-constexpr char kNotificationInfoString[] = "notificationInfoString";
-constexpr char kPermissions[] = "permissions";
-constexpr char kExtensionNameWithId[] = "extensionNameWithId";
+constexpr char kNotificationPermissionsReviewListMaybeChangedEvent[] =
+ "notification-permission-review-list-maybe-changed";
enum class SiteSettingSource {
kAllowlist,
@@ -151,8 +157,7 @@ ContentSetting GetContentSettingForOrigin(Profile* profile,
const HostContentSettingsMap* map,
const GURL& origin,
ContentSettingsType content_type,
- std::string* source_string,
- std::string* display_name);
+ std::string* source_string);
// Returns URLs with granted entries from the File System Access API.
void GetFileSystemGrantedEntries(std::vector<base::Value::Dict>* exceptions,
@@ -199,20 +204,27 @@ base::Value::List GetChooserExceptionListFromProfile(
Profile* profile,
const ChooserTypeNameEntry& chooser_type);
-// Returns the short name of a browser extension, or nullopt if `origin` is not
-// an extension URL.
-absl::optional<std::string> GetExtensionDisplayName(Profile* profile,
- GURL origin);
-
// Takes |url| and converts it into an individual origin string or retrieves
// name of the extension or Isolated Web App it belongs to. If |hostname_only|
// is true, returns |url|'s hostname for HTTP/HTTPS pages or unknown
// extension/IWA URLs, otherwise an origin string will be returned that
// includes the scheme if it's non-cryptographic.
+UrlIdentity GetUrlIdentityForGURL(Profile* profile,
+ const GURL& url,
+ bool hostname_only);
std::string GetDisplayNameForGURL(Profile* profile,
const GURL& url,
bool hostname_only);
+// Returns data about all currently installed Isolated Web Apps.
+std::vector<web_app::IsolatedWebAppUrlInfo> GetInstalledIsolatedWebApps(
+ Profile* profile);
+
+// Returns a list of domains to be shown on the 'Review Notification
+// Permissions' module in site settings notification page. Those domains send
+// a lot of notifications, but have low site engagement.
+base::Value::List PopulateNotificationPermissionReviewData(Profile* profile);
+
} // namespace site_settings
#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_SITE_SETTINGS_HELPER_H_
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 412c83f821f..1723406b7b3 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
@@ -13,11 +13,17 @@
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
+#include "chrome/browser/engagement/site_engagement_service_factory.h"
#include "chrome/browser/file_system_access/chrome_file_system_access_permission_context.h"
#include "chrome/browser/file_system_access/file_system_access_permission_context_factory.h"
+#include "chrome/browser/permissions/notifications_engagement_service_factory.h"
#include "chrome/browser/permissions/permission_decision_auto_blocker_factory.h"
+#include "chrome/browser/ui/web_applications/test/isolated_web_app_test_utils.h"
#include "chrome/browser/usb/usb_chooser_context.h"
#include "chrome/browser/usb/usb_chooser_context_factory.h"
+#include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
+#include "chrome/browser/web_applications/test/web_app_test_utils.h"
+#include "chrome/common/chrome_features.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/testing_profile.h"
#include "components/content_settings/core/browser/content_settings_utils.h"
@@ -32,6 +38,7 @@
#include "components/permissions/test/permission_test_util.h"
#include "components/prefs/pref_service.h"
#include "components/privacy_sandbox/privacy_sandbox_features.h"
+#include "components/site_engagement/content/site_engagement_score.h"
#include "content/public/test/browser_task_environment.h"
#include "extensions/browser/extension_registry.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
@@ -46,7 +53,7 @@
#include "extensions/browser/extension_system.h"
#include "extensions/browser/unloaded_extension_reason.h"
#include "extensions/test/test_extension_dir.h"
-#endif
+#endif // BUILDFLAG(ENABLE_EXTENSIONS)
namespace site_settings {
@@ -90,6 +97,20 @@ class SiteSettingsHelperTest : public testing::Test {
ContentSettingsPattern::Wildcard(), kContentType, setting);
}
+ void RecordNotification(permissions::NotificationsEngagementService* service,
+ GURL url,
+ int daily_average_count) {
+ // This many notifications were recorded during the past week in total.
+ int total_count = daily_average_count * 7;
+ service->RecordNotificationDisplayed(url, total_count);
+ }
+
+ base::Time GetReferenceTime() {
+ base::Time time;
+ EXPECT_TRUE(base::Time::FromString("Sat, 1 Sep 2018 11:00:00 GMT", &time));
+ return time;
+ }
+
private:
content::BrowserTaskEnvironment task_environment_;
};
@@ -432,34 +453,33 @@ TEST_F(SiteSettingsHelperTest, ContentSettingSource) {
GURL origin("https://www.example.com/");
std::string source;
- std::string display_name;
ContentSetting content_setting;
// Built in Chrome default.
- content_setting = GetContentSettingForOrigin(
- &profile, map, origin, kContentType, &source, &display_name);
+ content_setting =
+ GetContentSettingForOrigin(&profile, map, origin, kContentType, &source);
EXPECT_EQ(SiteSettingSourceToString(SiteSettingSource::kDefault), source);
EXPECT_EQ(CONTENT_SETTING_ASK, content_setting);
// User-set global default.
map->SetDefaultContentSetting(kContentType, CONTENT_SETTING_ALLOW);
- content_setting = GetContentSettingForOrigin(
- &profile, map, origin, kContentType, &source, &display_name);
+ content_setting =
+ GetContentSettingForOrigin(&profile, map, origin, kContentType, &source);
EXPECT_EQ(SiteSettingSourceToString(SiteSettingSource::kDefault), source);
EXPECT_EQ(CONTENT_SETTING_ALLOW, content_setting);
// User-set pattern.
AddSetting(map, "https://*", CONTENT_SETTING_BLOCK);
- content_setting = GetContentSettingForOrigin(
- &profile, map, origin, kContentType, &source, &display_name);
+ content_setting =
+ GetContentSettingForOrigin(&profile, map, origin, kContentType, &source);
EXPECT_EQ(SiteSettingSourceToString(SiteSettingSource::kPreference), source);
EXPECT_EQ(CONTENT_SETTING_BLOCK, content_setting);
// User-set origin setting.
map->SetContentSettingDefaultScope(origin, origin, kContentType,
CONTENT_SETTING_ALLOW);
- content_setting = GetContentSettingForOrigin(
- &profile, map, origin, kContentType, &source, &display_name);
+ content_setting =
+ GetContentSettingForOrigin(&profile, map, origin, kContentType, &source);
EXPECT_EQ(SiteSettingSourceToString(SiteSettingSource::kPreference), source);
EXPECT_EQ(CONTENT_SETTING_ALLOW, content_setting);
@@ -473,8 +493,8 @@ TEST_F(SiteSettingsHelperTest, ContentSettingSource) {
content_settings::TestUtils::OverrideProvider(
map, std::move(extension_provider),
HostContentSettingsMap::CUSTOM_EXTENSION_PROVIDER);
- content_setting = GetContentSettingForOrigin(
- &profile, map, origin, kContentType, &source, &display_name);
+ content_setting =
+ GetContentSettingForOrigin(&profile, map, origin, kContentType, &source);
EXPECT_EQ(SiteSettingSourceToString(SiteSettingSource::kExtension), source);
EXPECT_EQ(CONTENT_SETTING_BLOCK, content_setting);
@@ -487,15 +507,15 @@ TEST_F(SiteSettingsHelperTest, ContentSettingSource) {
policy_provider->set_read_only(true);
content_settings::TestUtils::OverrideProvider(
map, std::move(policy_provider), HostContentSettingsMap::POLICY_PROVIDER);
- content_setting = GetContentSettingForOrigin(
- &profile, map, origin, kContentType, &source, &display_name);
+ content_setting =
+ GetContentSettingForOrigin(&profile, map, origin, kContentType, &source);
EXPECT_EQ(SiteSettingSourceToString(SiteSettingSource::kPolicy), source);
EXPECT_EQ(CONTENT_SETTING_ALLOW, content_setting);
// Insecure origins.
content_setting = GetContentSettingForOrigin(
&profile, map, GURL("http://www.insecure_http_site.com/"), kContentType,
- &source, &display_name);
+ &source);
EXPECT_EQ(SiteSettingSourceToString(SiteSettingSource::kInsecureOrigin),
source);
EXPECT_EQ(CONTENT_SETTING_BLOCK, content_setting);
@@ -754,6 +774,89 @@ TEST_F(SiteSettingsHelperTest, CreateChooserExceptionObject) {
}
}
+TEST_F(SiteSettingsHelperTest, PopulateNotificationPermissionReviewData) {
+ TestingProfile profile;
+ base::test::ScopedFeatureList scoped_feature;
+ scoped_feature.InitAndEnableFeature(
+ ::features::kSafetyCheckNotificationPermissions);
+
+ // Add a couple of notification permission and check they appear in review
+ // list.
+ HostContentSettingsMap* map =
+ HostContentSettingsMapFactory::GetForProfile(&profile);
+ GURL urls[] = {GURL("https://google.com:443"),
+ GURL("https://www.youtube.com:443"),
+ GURL("https://www.example.com:443")};
+
+ map->SetContentSettingDefaultScope(urls[0], GURL(),
+ ContentSettingsType::NOTIFICATIONS,
+ CONTENT_SETTING_ALLOW);
+ map->SetContentSettingDefaultScope(urls[1], GURL(),
+ ContentSettingsType::NOTIFICATIONS,
+ CONTENT_SETTING_ALLOW);
+ map->SetContentSettingDefaultScope(urls[2], GURL(),
+ ContentSettingsType::NOTIFICATIONS,
+ CONTENT_SETTING_ALLOW);
+
+ // Record initial display date to enable comparing dictionaries for
+ // NotificationEngagementService.
+ auto* notification_engagement_service =
+ NotificationsEngagementServiceFactory::GetForProfile(&profile);
+ std::string displayedDate =
+ notification_engagement_service->GetBucketLabel(base::Time::Now());
+
+ auto* site_engagement_service =
+ site_engagement::SiteEngagementServiceFactory::GetForProfile(&profile);
+
+ // Set a host to have minimum engagement. This should be in review list.
+ RecordNotification(notification_engagement_service, urls[0], 1);
+ site_engagement::SiteEngagementScore score =
+ site_engagement_service->CreateEngagementScore(urls[0]);
+ score.Reset(0.5, GetReferenceTime());
+ score.Commit();
+ EXPECT_EQ(blink::mojom::EngagementLevel::MINIMAL,
+ site_engagement_service->GetEngagementLevel(urls[0]));
+
+ // Set a host to have large number of notifications, but low engagement. This
+ // should be in review list.
+ RecordNotification(notification_engagement_service, urls[1], 5);
+ site_engagement_service->AddPointsForTesting(urls[1], 1.0);
+ EXPECT_EQ(blink::mojom::EngagementLevel::LOW,
+ site_engagement_service->GetEngagementLevel(urls[1]));
+
+ // Set a host to have medium engagement and high notification count. This
+ // should not be in review list.
+ RecordNotification(notification_engagement_service, urls[2], 5);
+ site_engagement_service->AddPointsForTesting(urls[2], 50.0);
+ EXPECT_EQ(blink::mojom::EngagementLevel::MEDIUM,
+ site_engagement_service->GetEngagementLevel(urls[2]));
+
+ const auto& notification_permissions =
+ PopulateNotificationPermissionReviewData(&profile);
+ // Check if resulting list contains only the expected URLs. They should be in
+ // descending order of notification count.
+ EXPECT_EQ(2UL, notification_permissions.size());
+ EXPECT_EQ("https://www.youtube.com:443",
+ *notification_permissions[0].GetDict().FindString(
+ site_settings::kOrigin));
+ EXPECT_EQ("https://google.com:443",
+ *notification_permissions[1].GetDict().FindString(
+ site_settings::kOrigin));
+
+ // Increasing notification count also promotes host in the list.
+ RecordNotification(notification_engagement_service,
+ GURL("https://google.com:443"), 10);
+ const auto& updated_notification_permissions =
+ PopulateNotificationPermissionReviewData(&profile);
+ EXPECT_EQ(2UL, updated_notification_permissions.size());
+ EXPECT_EQ("https://google.com:443",
+ *updated_notification_permissions[0].GetDict().FindString(
+ site_settings::kOrigin));
+ EXPECT_EQ("https://www.youtube.com:443",
+ *updated_notification_permissions[1].GetDict().FindString(
+ site_settings::kOrigin));
+}
+
namespace {
constexpr char kUsbPolicySetting[] = R"(
@@ -1140,4 +1243,68 @@ TEST_F(SiteSettingsHelperExtensionTest,
}
#endif // #if BUILDFLAG(ENABLE_EXTENSIONS)
+class SiteSettingsHelperIsolatedWebAppTest : public testing::Test {
+ protected:
+ void InstallIsolatedWebApp(const GURL& url, const std::string& name) {
+ web_app::test::AwaitStartWebAppProviderAndSubsystems(&testing_profile_);
+ web_app::AddDummyIsolatedAppToRegistry(&testing_profile_, url, name);
+ }
+
+ Profile* profile() { return &testing_profile_; }
+
+ private:
+ content::BrowserTaskEnvironment task_environment_;
+ TestingProfile testing_profile_;
+
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+ web_app::test::ScopedSkipMainProfileCheck skip_main_profile_check_;
+#endif // BUILDFLAG(IS_CHROMEOS_LACROS)
+};
+
+TEST_F(SiteSettingsHelperIsolatedWebAppTest,
+ IsolatedWebAppsUseAppNameAsDisplayName) {
+ const GURL kAppUrl(
+ "isolated-app://"
+ "berugqztij5biqquuk3mfwpsaibuegaqcitgfchwuosuofdjabzqaaic");
+ const std::string kAppName("test IWA Name");
+
+ const std::string kUsbChooserGroupName(
+ ContentSettingsTypeToGroupName(ContentSettingsType::USB_CHOOSER_DATA));
+ const std::string& kPolicySource =
+ SiteSettingSourceToString(SiteSettingSource::kPolicy);
+ const std::string& kPreferenceSource =
+ SiteSettingSourceToString(SiteSettingSource::kPreference);
+ const std::u16string& kObjectName = u"Gadget";
+
+ InstallIsolatedWebApp(kAppUrl, kAppName);
+
+ // Create a chooser object for testing.
+ base::Value::Dict chooser_object;
+ chooser_object.Set("name", kObjectName);
+
+ // Add a user permission for an origin of |kAppUrl|.
+ ChooserExceptionDetails exception_details;
+ exception_details.insert({kAppUrl.DeprecatedGetOriginAsURL(),
+ kPreferenceSource, /*incognito=*/false});
+ {
+ auto exception = CreateChooserExceptionObject(
+ /*display_name=*/kObjectName,
+ /*object=*/base::Value(chooser_object.Clone()),
+ /*chooser_type=*/kUsbChooserGroupName,
+ /*chooser_exception_details=*/exception_details,
+ /*profile=*/profile());
+ ExpectValidChooserExceptionObject(
+ exception, /*chooser_type=*/kUsbChooserGroupName,
+ /*display_name=*/kObjectName, chooser_object);
+
+ const auto& sites_list = exception.Find(kSites)->GetList();
+ ExpectValidSiteExceptionObject(
+ /*actual_site_object=*/sites_list[0],
+ /*display_name=*/kAppName,
+ /*origin=*/kAppUrl,
+ /*source=*/kPreferenceSource,
+ /*incognito=*/false);
+ }
+}
+
} // namespace site_settings
diff --git a/chromium/chrome/browser/ui/webui/settings/site_settings_permissions_handler.cc b/chromium/chrome/browser/ui/webui/settings/site_settings_permissions_handler.cc
deleted file mode 100644
index b43272ed11b..00000000000
--- a/chromium/chrome/browser/ui/webui/settings/site_settings_permissions_handler.cc
+++ /dev/null
@@ -1,266 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// 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/site_settings_permissions_handler.h"
-
-#include "base/check.h"
-#include "base/json/values_util.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/threading/thread_checker.h"
-#include "base/time/clock.h"
-#include "base/time/default_clock.h"
-#include "base/time/time.h"
-#include "base/values.h"
-#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
-#include "chrome/browser/permissions/unused_site_permissions_service_factory.h"
-#include "chrome/browser/ui/webui/settings/site_settings_helper.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/features.h"
-#include "components/permissions/constants.h"
-#include "components/permissions/unused_site_permissions_service.h"
-#include "url/gurl.h"
-
-namespace {
-// Reflects the maximum number of days between a permissions being revoked and
-// the time when the user regrants the permission through the unused site
-// permission module of Safete Check. The maximum number of days is determined
-// by `content_settings::features::
-// kSafetyCheckUnusedSitePermissionsRevocationCleanUpThreshold`.
-size_t kAllowAgainMetricsExclusiveMaxCount = 31;
-// Using a single bucket per day, following the value of
-// |kAllowAgainMetricsExclusiveMaxCount|.
-size_t kAllowAgainMetricsBuckets = 31;
-// Key of the expiration time in the |UnusedSitePermissions| object. Indicates
-// the time after which the associated origin and permissions are no longer
-// shown in the UI.
-constexpr char kExpirationKey[] = "expiration";
-} // namespace
-
-SiteSettingsPermissionsHandler::SiteSettingsPermissionsHandler(Profile* profile)
- : profile_(profile), clock_(base::DefaultClock::GetInstance()) {}
-SiteSettingsPermissionsHandler::~SiteSettingsPermissionsHandler() = default;
-
-void SiteSettingsPermissionsHandler::HandleGetRevokedUnusedSitePermissionsList(
- const base::Value::List& args) {
- AllowJavascript();
-
- CHECK_EQ(1U, args.size());
- const base::Value& callback_id = args[0];
-
- base::Value::List result = PopulateUnusedSitePermissionsData();
-
- ResolveJavascriptCallback(callback_id, base::Value(std::move(result)));
-}
-
-void SiteSettingsPermissionsHandler::HandleAllowPermissionsAgainForUnusedSite(
- const base::Value::List& args) {
- CHECK_EQ(1U, args.size());
- CHECK(args[0].is_string());
- const std::string& origin_str = args[0].GetString();
-
- permissions::UnusedSitePermissionsService* service =
- UnusedSitePermissionsServiceFactory::GetForProfile(profile_);
-
- url::Origin origin = url::Origin::Create(GURL(origin_str));
-
- HostContentSettingsMap* hcsm =
- HostContentSettingsMapFactory::GetForProfile(profile_);
- content_settings::SettingInfo info;
- base::Value stored_value(hcsm->GetWebsiteSetting(
- origin.GetURL(), origin.GetURL(),
- ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS, &info));
- base::Time revoked_time =
- info.metadata.expiration -
- content_settings::features::
- kSafetyCheckUnusedSitePermissionsRevocationCleanUpThreshold.Get();
- base::UmaHistogramCustomCounts(
- "Settings.SafetyCheck.UnusedSitePermissionsAllowAgainDays",
- (clock_->Now() - revoked_time).InDays(), 0,
- kAllowAgainMetricsExclusiveMaxCount, kAllowAgainMetricsBuckets);
-
- service->RegrantPermissionsForOrigin(origin);
- SendUnusedSitePermissionsReviewList();
-}
-
-void SiteSettingsPermissionsHandler::
- HandleUndoAllowPermissionsAgainForUnusedSite(
- const base::Value::List& args) {
- CHECK_EQ(1U, args.size());
- CHECK(args[0].is_dict());
-
- auto [origin, permissions, constraints] =
- GetUnusedSitePermissionsFromDict(args[0].GetDict());
- permissions::UnusedSitePermissionsService* service =
- UnusedSitePermissionsServiceFactory::GetForProfile(profile_);
-
- service->UndoRegrantPermissionsForOrigin(permissions, constraints, origin);
-
- SendUnusedSitePermissionsReviewList();
-}
-
-void SiteSettingsPermissionsHandler::
- HandleAcknowledgeRevokedUnusedSitePermissionsList(
- const base::Value::List& args) {
- permissions::UnusedSitePermissionsService* service =
- UnusedSitePermissionsServiceFactory::GetForProfile(profile_);
- service->ClearRevokedPermissionsList();
-
- SendUnusedSitePermissionsReviewList();
-}
-
-void SiteSettingsPermissionsHandler::
- HandleUndoAcknowledgeRevokedUnusedSitePermissionsList(
- const base::Value::List& args) {
- CHECK_EQ(1U, args.size());
- CHECK(args[0].is_list());
-
- const base::Value::List& unused_site_permissions_list = args[0].GetList();
- permissions::UnusedSitePermissionsService* service =
- UnusedSitePermissionsServiceFactory::GetForProfile(profile_);
-
- for (const auto& unused_site_permissions_js : unused_site_permissions_list) {
- CHECK(unused_site_permissions_js.is_dict());
- auto [origin, permissions, constraints] =
- GetUnusedSitePermissionsFromDict(unused_site_permissions_js.GetDict());
-
- service->StorePermissionInRevokedPermissionSetting(permissions, constraints,
- origin);
- }
-
- SendUnusedSitePermissionsReviewList();
-}
-
-base::Value::List
-SiteSettingsPermissionsHandler::PopulateUnusedSitePermissionsData() {
- base::Value::List result;
- if (!base::FeatureList::IsEnabled(
- content_settings::features::kSafetyCheckUnusedSitePermissions)) {
- return result;
- }
-
- HostContentSettingsMap* hcsm =
- HostContentSettingsMapFactory::GetForProfile(profile_);
-
- ContentSettingsForOneType settings;
- hcsm->GetSettingsForOneType(
- ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS, &settings);
-
- for (const auto& revoked_permissions : settings) {
- base::Value::Dict revoked_permission_value;
- revoked_permission_value.Set(
- site_settings::kOrigin, revoked_permissions.primary_pattern.ToString());
- const base::Value& stored_value = revoked_permissions.setting_value;
- DCHECK(stored_value.is_dict());
-
- // The revoked permissions list should be reachable by given key.
- DCHECK(stored_value.GetDict().FindList(permissions::kRevokedKey));
-
- auto type_list =
- stored_value.GetDict().FindList(permissions::kRevokedKey)->Clone();
- base::Value::List permissions_value_list;
- for (base::Value& type : type_list) {
- permissions_value_list.Append(
- site_settings::ContentSettingsTypeToGroupName(
- static_cast<ContentSettingsType>(type.GetInt())));
- }
-
- revoked_permission_value.Set(
- site_settings::kPermissions,
- base::Value(std::move(permissions_value_list)));
-
- revoked_permission_value.Set(
- kExpirationKey,
- base::TimeToValue(revoked_permissions.metadata.expiration));
-
- result.Append(std::move(revoked_permission_value));
- }
- return result;
-}
-
-std::tuple<url::Origin,
- std::set<ContentSettingsType>,
- content_settings::ContentSettingConstraints>
-SiteSettingsPermissionsHandler::GetUnusedSitePermissionsFromDict(
- const base::Value::Dict& unused_site_permissions) {
- const std::string* origin_str =
- unused_site_permissions.FindString(site_settings::kOrigin);
- CHECK(origin_str);
- const auto url = GURL(*origin_str);
- CHECK(url.is_valid());
- const url::Origin origin = url::Origin::Create(url);
-
- const base::Value::List* permissions =
- unused_site_permissions.FindList(site_settings::kPermissions);
- CHECK(permissions);
- std::set<ContentSettingsType> permission_types;
- for (const auto& permission : *permissions) {
- CHECK(permission.is_string());
- const std::string& type_string = permission.GetString();
- ContentSettingsType type =
- site_settings::ContentSettingsTypeFromGroupName(type_string);
- CHECK(type != ContentSettingsType::DEFAULT)
- << type_string << " is not expected to have a UI representation.";
- permission_types.insert(type);
- }
-
- const base::Value* js_expiration =
- unused_site_permissions.Find(kExpirationKey);
- CHECK(js_expiration);
- auto expiration = base::ValueToTime(js_expiration);
-
- const content_settings::ContentSettingConstraints constraints{
- .expiration = *expiration};
-
- return std::make_tuple(origin, permission_types, constraints);
-}
-
-void SiteSettingsPermissionsHandler::RegisterMessages() {
- // Usage of base::Unretained(this) is safe, because web_ui() owns `this` and
- // won't release ownership until destruction.
- web_ui()->RegisterMessageCallback(
- "getRevokedUnusedSitePermissionsList",
- base::BindRepeating(&SiteSettingsPermissionsHandler::
- HandleGetRevokedUnusedSitePermissionsList,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback(
- "allowPermissionsAgainForUnusedSite",
- base::BindRepeating(&SiteSettingsPermissionsHandler::
- HandleAllowPermissionsAgainForUnusedSite,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback(
- "undoAllowPermissionsAgainForUnusedSite",
- base::BindRepeating(&SiteSettingsPermissionsHandler::
- HandleUndoAllowPermissionsAgainForUnusedSite,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback(
- "acknowledgeRevokedUnusedSitePermissionsList",
- base::BindRepeating(&SiteSettingsPermissionsHandler::
- HandleAcknowledgeRevokedUnusedSitePermissionsList,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback(
- "undoAcknowledgeRevokedUnusedSitePermissionsList",
- base::BindRepeating(
- &SiteSettingsPermissionsHandler::
- HandleUndoAcknowledgeRevokedUnusedSitePermissionsList,
- base::Unretained(this)));
-}
-
-void SiteSettingsPermissionsHandler::SendUnusedSitePermissionsReviewList() {
- // Notify observers that the unused site permission review list could have
- // changed. Note that the list is not guaranteed to have changed. In places
- // where determining whether the list has changed is cause for performance
- // concerns, an unchanged list may be sent.
- FireWebUIListener("unused-permission-review-list-maybe-changed",
- PopulateUnusedSitePermissionsData());
-}
-
-void SiteSettingsPermissionsHandler::SetClockForTesting(base::Clock* clock) {
- clock_ = clock;
-}
-
-void SiteSettingsPermissionsHandler::OnJavascriptAllowed() {}
-
-void SiteSettingsPermissionsHandler::OnJavascriptDisallowed() {}
diff --git a/chromium/chrome/browser/ui/webui/settings/site_settings_permissions_handler.h b/chromium/chrome/browser/ui/webui/settings/site_settings_permissions_handler.h
deleted file mode 100644
index 414f949d423..00000000000
--- a/chromium/chrome/browser/ui/webui/settings/site_settings_permissions_handler.h
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// 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_SITE_SETTINGS_PERMISSIONS_HANDLER_H_
-#define CHROME_BROWSER_UI_WEBUI_SETTINGS_SITE_SETTINGS_PERMISSIONS_HANDLER_H_
-
-#include "base/memory/raw_ptr.h"
-#include "base/time/clock.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
-#include "components/content_settings/core/common/content_settings_constraints.h"
-#include "components/content_settings/core/common/content_settings_types.h"
-#include "url/origin.h"
-
-/**
- * This handler deals with the permission-related operations on the site
- * settings page.
- */
-
-class SiteSettingsPermissionsHandler : public settings::SettingsPageUIHandler {
- public:
- explicit SiteSettingsPermissionsHandler(Profile* profile);
-
- ~SiteSettingsPermissionsHandler() override;
-
- private:
- friend class SiteSettingsPermissionsHandlerTest;
- FRIEND_TEST_ALL_PREFIXES(SiteSettingsPermissionsHandlerTest,
- PopulateUnusedSitePermissionsData);
- FRIEND_TEST_ALL_PREFIXES(SiteSettingsPermissionsHandlerTest,
- HandleAllowPermissionsAgainForUnusedSite);
- FRIEND_TEST_ALL_PREFIXES(SiteSettingsPermissionsHandlerTest,
- HandleAcknowledgeRevokedUnusedSitePermissionsList);
-
- // SettingsPageUIHandler implementation.
- void OnJavascriptAllowed() override;
- void OnJavascriptDisallowed() override;
-
- // WebUIMessageHandler implementation.
- void RegisterMessages() override;
-
- // Returns the list of revoked permissions to be used in
- // "Unused site permissions" module.
- void HandleGetRevokedUnusedSitePermissionsList(const base::Value::List& args);
-
- // Re-grant the revoked permissions and remove the given origin from the
- // revoked permissions list.
- void HandleAllowPermissionsAgainForUnusedSite(const base::Value::List& args);
-
- // Reverse the changes made by |HandleAllowPermissionsAgainForUnusedSite| for
- // the given |UnusedSitePermission| object.
- void HandleUndoAllowPermissionsAgainForUnusedSite(
- const base::Value::List& args);
-
- // Clear the list of revoked permissions so they are not shown again.
- // Permission settings themselves are not affected by this.
- void HandleAcknowledgeRevokedUnusedSitePermissionsList(
- const base::Value::List& args);
-
- // Reverse the changes made by
- // |HandleAcknowledgeRevokedUnusedSitePermissionsList| for the given list of
- // |UnusedSitePermission| objects. List of revoked
- // permissions is repopulated. Permission settings are not changed.
- void HandleUndoAcknowledgeRevokedUnusedSitePermissionsList(
- const base::Value::List& args);
-
- // Returns the list of revoked permissions that belongs to origins which
- // haven't been visited recently.
- base::Value::List PopulateUnusedSitePermissionsData();
-
- // Sends the list of unused site permissions to review to the WebUI.
- void SendUnusedSitePermissionsReviewList();
-
- // Get values from |UnusedSitePermission| object in
- // site_settings_permissions_browser_proxy.ts.
- std::tuple<url::Origin,
- std::set<ContentSettingsType>,
- content_settings::ContentSettingConstraints>
- GetUnusedSitePermissionsFromDict(
- const base::Value::Dict& unused_site_permissions);
-
- const raw_ptr<Profile> profile_;
-
- raw_ptr<base::Clock> clock_;
-
- void SetClockForTesting(base::Clock* clock);
-};
-
-#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_SITE_SETTINGS_PERMISSIONS_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/site_settings_permissions_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/site_settings_permissions_handler_unittest.cc
deleted file mode 100644
index 186208b69ce..00000000000
--- a/chromium/chrome/browser/ui/webui/settings/site_settings_permissions_handler_unittest.cc
+++ /dev/null
@@ -1,209 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <ctime>
-#include <memory>
-
-#include "base/memory/scoped_refptr.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "base/test/simple_test_clock.h"
-#include "base/time/clock.h"
-#include "base/time/time.h"
-#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
-#include "chrome/browser/history/history_service_factory.h"
-#include "chrome/browser/ui/webui/settings/site_settings_helper.h"
-#include "chrome/browser/ui/webui/settings/site_settings_permissions_handler.h"
-#include "chrome/test/base/testing_profile.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_types.h"
-#include "components/content_settings/core/common/features.h"
-#include "components/permissions/constants.h"
-#include "components/permissions/unused_site_permissions_service.h"
-#include "content/public/browser/storage_partition.h"
-#include "content/public/test/browser_task_environment.h"
-#include "content/public/test/test_web_ui.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "url/gurl.h"
-
-constexpr char kUnusedTestSite[] = "https://example1.com";
-constexpr char kUsedTestSite[] = "https://example2.com";
-constexpr ContentSettingsType kUnusedPermission =
- ContentSettingsType::GEOLOCATION;
-
-class SiteSettingsPermissionsHandlerTest : public testing::Test {
- public:
- SiteSettingsPermissionsHandlerTest() {
- feature_list_.InitAndEnableFeature(
- content_settings::features::kSafetyCheckUnusedSitePermissions);
- }
-
- void SetUp() override {
- // Fully initialize |profile_| in the constructor since some children
- // classes need it right away for SetUp().
- TestingProfile::Builder profile_builder;
- profile_builder.AddTestingFactory(
- HistoryServiceFactory::GetInstance(),
- HistoryServiceFactory::GetDefaultFactory());
- profile_ = profile_builder.Build();
-
- // Set clock for HostContentSettingsMap.
- base::Time time;
- ASSERT_TRUE(base::Time::FromString("2022-09-07 13:00", &time));
- clock_.SetNow(time);
- hcsm_ = HostContentSettingsMapFactory::GetForProfile(profile());
- hcsm_->SetClockForTesting(&clock_);
-
- handler_ = std::make_unique<SiteSettingsPermissionsHandler>(profile());
- handler()->set_web_ui(web_ui());
- handler()->AllowJavascript();
-
- // Create a revoked permission.
- base::Value::Dict dict = base::Value::Dict();
- base::Value::List permission_type_list = base::Value::List();
- permission_type_list.Append(
- static_cast<int32_t>(ContentSettingsType::GEOLOCATION));
- dict.Set(permissions::kRevokedKey,
- base::Value::List(std::move(permission_type_list)));
- const content_settings::ContentSettingConstraints constraint{
- .expiration =
- clock()->Now() +
- content_settings::features::
- kSafetyCheckUnusedSitePermissionsRevocationCleanUpThreshold
- .Get()};
-
- hcsm()->SetWebsiteSettingDefaultScope(
- GURL(kUnusedTestSite), GURL(kUnusedTestSite),
- ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS,
- base::Value(dict.Clone()), constraint);
-
- // There should be only an unused URL in the revoked permissions list.
- const auto& revoked_permissions =
- handler()->PopulateUnusedSitePermissionsData();
- EXPECT_EQ(revoked_permissions.size(), 1UL);
- EXPECT_EQ(GURL(kUnusedTestSite),
- GURL(*revoked_permissions[0].GetDict().FindString(
- site_settings::kOrigin)));
- handler()->SetClockForTesting(&clock_);
- }
-
- void TearDown() override {
- if (profile_) {
- auto* partition = profile_->GetDefaultStoragePartition();
- if (partition) {
- partition->WaitForDeletionTasksForTesting();
- }
- }
- }
-
- void ExpectRevokedPermission() {
- ContentSettingsForOneType revoked_permissions_list;
- hcsm()->GetSettingsForOneType(
- ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS,
- &revoked_permissions_list);
- EXPECT_EQ(1U, revoked_permissions_list.size());
- EXPECT_EQ(
- ContentSetting::CONTENT_SETTING_ASK,
- hcsm()->GetContentSetting(GURL(kUnusedTestSite), GURL(kUnusedTestSite),
- kUnusedPermission));
- }
-
- TestingProfile* profile() { return profile_.get(); }
- content::TestWebUI* web_ui() { return &web_ui_; }
- SiteSettingsPermissionsHandler* handler() { return handler_.get(); }
- HostContentSettingsMap* hcsm() { return hcsm_.get(); }
- base::SimpleTestClock* clock() { return &clock_; }
-
- private:
- base::test::ScopedFeatureList feature_list_;
- content::BrowserTaskEnvironment task_environment_;
- std::unique_ptr<SiteSettingsPermissionsHandler> handler_;
- std::unique_ptr<TestingProfile> profile_;
- content::TestWebUI web_ui_;
- scoped_refptr<HostContentSettingsMap> hcsm_;
- base::SimpleTestClock clock_;
-};
-
-TEST_F(SiteSettingsPermissionsHandlerTest, PopulateUnusedSitePermissionsData) {
- // Add GEOLOCATION setting for url but do not add to revoked list.
- const content_settings::ContentSettingConstraints constraint{
- .expiration =
- clock()->Now() +
- content_settings::features::
- kSafetyCheckUnusedSitePermissionsRevocationCleanUpThreshold.Get(),
- .track_last_visit_for_autoexpiration = true};
- hcsm()->SetContentSettingDefaultScope(
- GURL(kUsedTestSite), GURL(kUsedTestSite),
- ContentSettingsType::GEOLOCATION, ContentSetting::CONTENT_SETTING_ALLOW,
- constraint);
-
- // Revoked permissions list should still only contain the initial unused site.
- const auto& revoked_permissions =
- handler()->PopulateUnusedSitePermissionsData();
- EXPECT_EQ(revoked_permissions.size(), 1UL);
- EXPECT_EQ(GURL(kUnusedTestSite),
- GURL(*revoked_permissions[0].GetDict().FindString(
- site_settings::kOrigin)));
-}
-
-TEST_F(SiteSettingsPermissionsHandlerTest,
- HandleAllowPermissionsAgainForUnusedSite) {
- // Advance 14 days; this will be the expected histogram sample.
- clock()->Advance(base::Days(14));
- base::HistogramTester histogram_tester;
- base::Value::List initial_unused_site_permissions =
- handler()->PopulateUnusedSitePermissionsData();
- ExpectRevokedPermission();
-
- // Allow the revoked permission for the unused site again.
- base::Value::List args;
- args.Append(base::Value(kUnusedTestSite));
- handler()->HandleAllowPermissionsAgainForUnusedSite(args);
-
- // Only a single entry should be recorded in the histogram.
- const std::vector<base::Bucket> buckets = histogram_tester.GetAllSamples(
- "Settings.SafetyCheck.UnusedSitePermissionsAllowAgainDays");
- EXPECT_EQ(1U, buckets.size());
- // The recorded metric should be the elapsed days since the revocation.
- histogram_tester.ExpectUniqueSample(
- "Settings.SafetyCheck.UnusedSitePermissionsAllowAgainDays", 14, 1);
-
- // Check there is no origin in revoked permissions list.
- ContentSettingsForOneType revoked_permissions_list;
- hcsm()->GetSettingsForOneType(
- ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS,
- &revoked_permissions_list);
- EXPECT_EQ(0U, revoked_permissions_list.size());
- // Check if the permissions of url is regranted.
- EXPECT_EQ(
- ContentSetting::CONTENT_SETTING_ALLOW,
- hcsm()->GetContentSetting(GURL(kUnusedTestSite), GURL(kUnusedTestSite),
- kUnusedPermission));
-
- // Undoing restores the initial state.
- handler()->HandleUndoAllowPermissionsAgainForUnusedSite(
- std::move(initial_unused_site_permissions));
- ExpectRevokedPermission();
-}
-
-TEST_F(SiteSettingsPermissionsHandlerTest,
- HandleAcknowledgeRevokedUnusedSitePermissionsList) {
- const auto& revoked_permissions_before =
- handler()->PopulateUnusedSitePermissionsData();
- EXPECT_GT(revoked_permissions_before.size(), 0U);
- // Acknowledging revoked permissions from unused sites clears the list.
- base::Value::List args;
- handler()->HandleAcknowledgeRevokedUnusedSitePermissionsList(args);
- const auto& revoked_permissions_after =
- handler()->PopulateUnusedSitePermissionsData();
- EXPECT_EQ(revoked_permissions_after.size(), 0U);
-
- // Undo reverts the list to its initial state.
- base::Value::List undo_args;
- undo_args.Append(revoked_permissions_before.Clone());
- handler()->HandleUndoAcknowledgeRevokedUnusedSitePermissionsList(undo_args);
- EXPECT_EQ(revoked_permissions_before,
- handler()->PopulateUnusedSitePermissionsData());
-}