summaryrefslogtreecommitdiffstats
path: root/chromium/chrome/browser/ui/webui/settings/chromeos
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-07-16 11:45:35 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-07-17 08:59:23 +0000
commit552906b0f222c5d5dd11b9fd73829d510980461a (patch)
tree3a11e6ed0538a81dd83b20cf3a4783e297f26d91 /chromium/chrome/browser/ui/webui/settings/chromeos
parent1b05827804eaf047779b597718c03e7d38344261 (diff)
BASELINE: Update Chromium to 83.0.4103.122
Change-Id: Ie3a82f5bb0076eec2a7c6a6162326b4301ee291e Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/chrome/browser/ui/webui/settings/chromeos')
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/DEPS4
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/OWNERS4
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc85
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h28
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler_unittest.cc103
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc29
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.h3
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.cc32
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.h39
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.cc393
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.h296
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator_test_api.h156
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc5
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h2
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc335
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.h42
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc120
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h24
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/date_time_handler.cc4
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc46
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler_unittest.cc68
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc312
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.h57
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler_browsertest.cc322
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc520
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h169
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler_unittest.cc516
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.cc8
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/internet_handler.cc6
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/internet_strings_provider.cc252
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/internet_strings_provider.h59
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h2
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.cc2136
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.h91
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_factory.cc66
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_factory.h47
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_unittest.cc104
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_per_page_strings_provider.cc32
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_per_page_strings_provider.h73
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc350
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.h47
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.cc33
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.h4
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/pref_names.cc20
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/pref_names.h18
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/quick_unlock_handler.cc38
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/quick_unlock_handler.h42
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/BUILD.gn17
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/OWNERS7
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/search.mojom33
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/search_concept.h62
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc107
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.h77
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_factory.cc61
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_factory.h45
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc78
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/search_result_icon.mojom14
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker.cc131
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker.h74
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker_unittest.cc176
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/search/user_action_recorder.mojom28
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/server_printer_url_util.cc73
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/server_printer_url_util.h30
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/server_printer_url_util_unittest.cc89
64 files changed, 7354 insertions, 890 deletions
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/DEPS b/chromium/chrome/browser/ui/webui/settings/chromeos/DEPS
new file mode 100644
index 00000000000..eb3c6b1fa0c
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+ "+chrome/services/local_search_service",
+ "+device/udev_linux/fake_udev_loader.h", # For keyboard unit test.
+]
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/OWNERS b/chromium/chrome/browser/ui/webui/settings/chromeos/OWNERS
index f42990c5d35..ff0d48d0403 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/OWNERS
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/OWNERS
@@ -1,3 +1,5 @@
+file://chrome/browser/resources/settings/chromeos/OWNERS
+
per-file multidevice_handler*=file://chromeos/components/multidevice/OWNERS
-# COMPONENT: UI>Settings
+# COMPONENT: OS>Systems>Settings
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc
index 34dbb5b6fac..e1d62743ff2 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc
@@ -4,8 +4,10 @@
#include "chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h"
+#include "ash/public/cpp/tablet_mode.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/metrics/histogram_functions.h"
#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/profiles/profile.h"
@@ -18,11 +20,24 @@
namespace chromeos {
namespace settings {
-AccessibilityHandler::AccessibilityHandler(content::WebUI* webui)
- : profile_(Profile::FromWebUI(webui)) {
+namespace {
+
+void RecordShowShelfNavigationButtonsValueChange(bool enabled) {
+ base::UmaHistogramBoolean(
+ "Accessibility.CrosShelfNavigationButtonsInTabletModeChanged."
+ "OsSettings",
+ enabled);
}
-AccessibilityHandler::~AccessibilityHandler() {}
+} // namespace
+
+AccessibilityHandler::AccessibilityHandler(Profile* profile)
+ : profile_(profile) {}
+
+AccessibilityHandler::~AccessibilityHandler() {
+ if (a11y_nav_buttons_toggle_metrics_reporter_timer_.IsRunning())
+ a11y_nav_buttons_toggle_metrics_reporter_timer_.FireNow();
+}
void AccessibilityHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(
@@ -35,13 +50,21 @@ void AccessibilityHandler::RegisterMessages() {
&AccessibilityHandler::HandleShowSelectToSpeakSettings,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
- "getStartupSoundEnabled",
- base::BindRepeating(&AccessibilityHandler::HandleGetStartupSoundEnabled,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback(
"setStartupSoundEnabled",
base::BindRepeating(&AccessibilityHandler::HandleSetStartupSoundEnabled,
base::Unretained(this)));
+
+ web_ui()->RegisterMessageCallback(
+ "recordSelectedShowShelfNavigationButtonValue",
+ base::BindRepeating(
+ &AccessibilityHandler::
+ HandleRecordSelectedShowShelfNavigationButtonsValue,
+ base::Unretained(this)));
+
+ web_ui()->RegisterMessageCallback(
+ "manageA11yPageReady",
+ base::BindRepeating(&AccessibilityHandler::HandleManageA11yPageReady,
+ base::Unretained(this)));
}
void AccessibilityHandler::HandleShowChromeVoxSettings(
@@ -54,20 +77,54 @@ void AccessibilityHandler::HandleShowSelectToSpeakSettings(
OpenExtensionOptionsPage(extension_misc::kSelectToSpeakExtensionId);
}
-void AccessibilityHandler::HandleGetStartupSoundEnabled(
+void AccessibilityHandler::HandleSetStartupSoundEnabled(
const base::ListValue* args) {
- AllowJavascript();
- FireWebUIListener(
- "startup-sound-enabled-updated",
- base::Value(AccessibilityManager::Get()->GetStartupSoundEnabled()));
+ DCHECK_EQ(1U, args->GetSize());
+ bool enabled;
+ args->GetBoolean(0, &enabled);
+ AccessibilityManager::Get()->SetStartupSoundEnabled(enabled);
}
-void AccessibilityHandler::HandleSetStartupSoundEnabled(
+void AccessibilityHandler::HandleRecordSelectedShowShelfNavigationButtonsValue(
const base::ListValue* args) {
DCHECK_EQ(1U, args->GetSize());
bool enabled;
args->GetBoolean(0, &enabled);
- AccessibilityManager::Get()->SetStartupSoundEnabled(enabled);
+
+ a11y_nav_buttons_toggle_metrics_reporter_timer_.Start(
+ FROM_HERE, base::TimeDelta::FromSeconds(10),
+ base::BindOnce(&RecordShowShelfNavigationButtonsValueChange, enabled));
+}
+
+void AccessibilityHandler::HandleManageA11yPageReady(
+ const base::ListValue* args) {
+ AllowJavascript();
+
+ // When tablet mode is active we can return early since tablet mode
+ // is supported.
+ if (ash::TabletMode::Get()->InTabletMode()) {
+ FireWebUIListener(
+ "initial-data-ready",
+ base::Value(AccessibilityManager::Get()->GetStartupSoundEnabled()),
+ base::Value(true /* tablet_mode_supported */));
+ return;
+ }
+
+ PowerManagerClient::Get()->GetSwitchStates(
+ base::BindOnce(&AccessibilityHandler::OnReceivedSwitchStates,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void AccessibilityHandler::OnReceivedSwitchStates(
+ base::Optional<PowerManagerClient::SwitchStates> switch_states) {
+ bool tablet_mode_supported =
+ switch_states.has_value() &&
+ switch_states->tablet_mode != PowerManagerClient::TabletMode::UNSUPPORTED;
+
+ FireWebUIListener(
+ "initial-data-ready",
+ base::Value(AccessibilityManager::Get()->GetStartupSoundEnabled()),
+ base::Value(tablet_mode_supported));
}
void AccessibilityHandler::OpenExtensionOptionsPage(const char extension_id[]) {
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h
index 80d735832cb..54290f81dd8 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h
@@ -6,16 +6,14 @@
#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_ACCESSIBILITY_HANDLER_H_
#include "base/macros.h"
+#include "base/timer/timer.h"
#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+#include "chromeos/dbus/power/power_manager_client.h"
namespace base {
class ListValue;
}
-namespace content {
-class WebUI;
-}
-
class Profile;
namespace chromeos {
@@ -23,7 +21,7 @@ namespace settings {
class AccessibilityHandler : public ::settings::SettingsPageUIHandler {
public:
- explicit AccessibilityHandler(content::WebUI* webui);
+ explicit AccessibilityHandler(Profile* profile);
~AccessibilityHandler() override;
// SettingsPageUIHandler implementation.
@@ -31,18 +29,36 @@ class AccessibilityHandler : public ::settings::SettingsPageUIHandler {
void OnJavascriptAllowed() override {}
void OnJavascriptDisallowed() override {}
+ // Callback which updates if startup sound is enabled and if tablet
+ // mode is supported. Visible for testing.
+ void HandleManageA11yPageReady(const base::ListValue* args);
+
private:
// Callback for the messages to show settings for ChromeVox or
// Select To Speak.
void HandleShowChromeVoxSettings(const base::ListValue* args);
void HandleShowSelectToSpeakSettings(const base::ListValue* args);
- void HandleGetStartupSoundEnabled(const base::ListValue* args);
void HandleSetStartupSoundEnabled(const base::ListValue* args);
+ void HandleRecordSelectedShowShelfNavigationButtonsValue(
+ const base::ListValue* args);
+
+ // Callback which updates visibility for the shelf navigation buttons
+ // accessibility setting, depending on whether tablet mode is supported.
+ void OnReceivedSwitchStates(
+ base::Optional<chromeos::PowerManagerClient::SwitchStates> switch_states);
void OpenExtensionOptionsPage(const char extension_id[]);
Profile* profile_; // Weak pointer.
+ // Timer to record user changed value for the accessibility setting to turn
+ // shelf navigation buttons on in tablet mode. The metric is recorded with 10
+ // second delay to avoid overreporting when the user keeps toggling the
+ // setting value in the screen UI.
+ base::OneShotTimer a11y_nav_buttons_toggle_metrics_reporter_timer_;
+
+ base::WeakPtrFactory<AccessibilityHandler> weak_ptr_factory_{this};
+
DISALLOW_COPY_AND_ASSIGN(AccessibilityHandler);
};
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler_unittest.cc
new file mode 100644
index 00000000000..8ee78caacd8
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler_unittest.cc
@@ -0,0 +1,103 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h"
+
+#include <memory>
+
+#include "ash/public/cpp/test/test_tablet_mode.h"
+#include "chrome/test/base/chrome_render_view_host_test_harness.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chromeos/dbus/power/fake_power_manager_client.h"
+#include "content/public/test/test_web_ui.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+namespace settings {
+
+class TestingAccessibilityHandler : public AccessibilityHandler {
+ public:
+ explicit TestingAccessibilityHandler(content::WebUI* web_ui)
+ : AccessibilityHandler(/* profile */ nullptr) {
+ set_web_ui(web_ui);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestingAccessibilityHandler);
+};
+
+class AccessibilityHandlerTest : public ChromeRenderViewHostTestHarness {
+ public:
+ AccessibilityHandlerTest() = default;
+ AccessibilityHandlerTest(const AccessibilityHandlerTest&) = delete;
+ AccessibilityHandlerTest& operator=(const AccessibilityHandlerTest&) = delete;
+
+ void SetUp() override {
+ ChromeRenderViewHostTestHarness::SetUp();
+ PowerManagerClient::InitializeFake();
+ test_tablet_mode_ = std::make_unique<ash::TestTabletMode>();
+ handler_ = std::make_unique<TestingAccessibilityHandler>(&web_ui_);
+ }
+
+ void TearDown() override {
+ handler_.reset();
+ test_tablet_mode_.reset();
+ PowerManagerClient::Shutdown();
+ ChromeRenderViewHostTestHarness::TearDown();
+ }
+
+ content::TestWebUI web_ui_;
+ std::unique_ptr<ash::TestTabletMode> test_tablet_mode_;
+ std::unique_ptr<TestingAccessibilityHandler> handler_;
+};
+
+// Test that when tablet mode is supported, the correct data is returned by
+// HandleManageA11yPageReady().
+TEST_F(AccessibilityHandlerTest, ManageA11yPageReadyTabletModeSupported) {
+ // Set tablet mode as supported.
+ chromeos::FakePowerManagerClient::Get()->SetTabletMode(
+ chromeos::PowerManagerClient::TabletMode::OFF, base::TimeTicks());
+
+ handler_->HandleManageA11yPageReady(/* args */ nullptr);
+
+ // Wait for the AccessibilityHandler to receive data from PowerManagerClient.
+ base::RunLoop().RunUntilIdle();
+
+ const content::TestWebUI::CallData& call_data = *web_ui_.call_data().back();
+
+ // Ensure tablet mode is returned as supported.
+ EXPECT_TRUE(call_data.arg3()->GetBool());
+}
+
+// Test that when tablet mode is unsupported, the correct data is returned by
+// HandleManageA11yPageReady().
+TEST_F(AccessibilityHandlerTest, ManageA11yPageReadyTabletModeUnsupported) {
+ // Set tablet mode as unsupported.
+ chromeos::FakePowerManagerClient::Get()->SetTabletMode(
+ chromeos::PowerManagerClient::TabletMode::UNSUPPORTED, base::TimeTicks());
+ handler_->HandleManageA11yPageReady(/* args */ nullptr);
+
+ // Wait for the AccessibilityHandler to receive data from PowerManagerClient.
+ base::RunLoop().RunUntilIdle();
+
+ const content::TestWebUI::CallData& call_data = *web_ui_.call_data().back();
+
+ // Ensure tablet mode is returned as unsupported.
+ EXPECT_FALSE(call_data.arg3()->GetBool());
+}
+
+// Test that when tablet mode is enabled, the correct data is returned by
+// HandleManageA11yPageReady().
+TEST_F(AccessibilityHandlerTest, ManageA11yPageReadyTabletModeEnabled) {
+ test_tablet_mode_->SetEnabledForTest(true);
+ handler_->HandleManageA11yPageReady(/* args */ nullptr);
+
+ const content::TestWebUI::CallData& call_data = *web_ui_.call_data().back();
+
+ // Ensure tablet mode is returned as supported.
+ EXPECT_TRUE(call_data.arg3()->GetBool());
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc
index a8b296703d0..e6d80c5a757 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.cc
@@ -23,6 +23,7 @@
#include "chrome/browser/ui/webui/signin/inline_login_handler_dialog_chromeos.h"
#include "chrome/grit/generated_resources.h"
#include "chromeos/components/account_manager/account_manager_factory.h"
+#include "components/signin/public/identity_manager/consent_level.h"
#include "components/user_manager/user.h"
#include "google_apis/gaia/gaia_auth_util.h"
#include "google_apis/gaia/google_service_auth_error.h"
@@ -273,12 +274,13 @@ void AccountManagerUIHandler::OnGetAccounts(
GetEnterpriseDomainFromUsername(user->GetDisplayEmail()));
} else if (profile_->GetProfilePolicyConnector()->IsManaged()) {
device_account.SetOrganization(GetEnterpriseDomainFromUsername(
- identity_manager_->GetPrimaryAccountInfo().email));
+ identity_manager_
+ ->GetPrimaryAccountInfo(signin::ConsentLevel::kNotRequired)
+ .email));
}
// Device account must show up at the top.
- accounts.GetList().insert(accounts.GetList().begin(),
- device_account.Build());
+ accounts.Insert(accounts.GetList().begin(), device_account.Build());
}
ResolveJavascriptCallback(callback_id, accounts);
@@ -418,17 +420,26 @@ void AccountManagerUIHandler::OnAccountRemoved(
RefreshUI();
}
-// |signin::IdentityManager::Observer| overrides. For newly added accounts,
-// |signin::IdentityManager| may take some time to fetch user's full name and
-// account image. Whenever that is completed, we may need to update the UI with
-// this new set of information. Note that we may be listening to
-// |signin::IdentityManager| but we still consider |AccountManager| to be the
-// source of truth for account list.
+// |signin::IdentityManager::Observer| overrides.
+//
+// For newly added accounts, |signin::IdentityManager| may take some time to
+// fetch user's full name and account image. Whenever that is completed, we may
+// need to update the UI with this new set of information. Note that we may be
+// listening to |signin::IdentityManager| but we still consider |AccountManager|
+// to be the source of truth for account list.
void AccountManagerUIHandler::OnExtendedAccountInfoUpdated(
const AccountInfo& info) {
RefreshUI();
}
+void AccountManagerUIHandler::OnErrorStateOfRefreshTokenUpdatedForAccount(
+ const CoreAccountInfo& account_info,
+ const GoogleServiceAuthError& error) {
+ if (error.state() != GoogleServiceAuthError::NONE) {
+ RefreshUI();
+ }
+}
+
void AccountManagerUIHandler::RefreshUI() {
FireWebUIListener("accounts-changed");
}
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.h
index 39f24fbbbec..21e8adf1bc8 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/account_manager_handler.h
@@ -44,6 +44,9 @@ class AccountManagerUIHandler : public ::settings::SettingsPageUIHandler,
// |signin::IdentityManager::Observer| overrides.
void OnExtendedAccountInfoUpdated(const AccountInfo& info) override;
+ void OnErrorStateOfRefreshTokenUpdatedForAccount(
+ const CoreAccountInfo& account_info,
+ const GoogleServiceAuthError& error) override;
private:
friend class AccountManagerUIHandlerTest;
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.cc
new file mode 100644
index 00000000000..e3c7e6d7645
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.cc
@@ -0,0 +1,32 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.h"
+
+#include "base/bind.h"
+#include "base/values.h"
+
+namespace chromeos {
+namespace settings {
+
+AmbientModeHandler::AmbientModeHandler() = default;
+
+AmbientModeHandler::~AmbientModeHandler() = default;
+
+void AmbientModeHandler::RegisterMessages() {
+ web_ui()->RegisterMessageCallback(
+ "onAmbientModePageReady",
+ base::BindRepeating(&AmbientModeHandler::HandleInitialized,
+ base::Unretained(this)));
+}
+
+void AmbientModeHandler::HandleInitialized(const base::ListValue* args) {
+ CHECK(args);
+ CHECK(args->empty());
+
+ AllowJavascript();
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.h
new file mode 100644
index 00000000000..a52b109160a
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.h
@@ -0,0 +1,39 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_AMBIENT_MODE_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_AMBIENT_MODE_HANDLER_H_
+
+#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+
+namespace base {
+class ListValue;
+} // namespace base
+
+namespace chromeos {
+namespace settings {
+
+// Chrome OS ambient mode settings page UI handler, to allow users to customize
+// photo frame and other related functionalities.
+class AmbientModeHandler : public ::settings::SettingsPageUIHandler {
+ public:
+ AmbientModeHandler();
+ AmbientModeHandler(const AmbientModeHandler&) = delete;
+ AmbientModeHandler& operator=(const AmbientModeHandler&) = delete;
+ ~AmbientModeHandler() override;
+
+ // settings::SettingsPageUIHandler:
+ void RegisterMessages() override;
+ void OnJavascriptAllowed() override {}
+ void OnJavascriptDisallowed() override {}
+
+ private:
+ // WebUI call to signal js side is ready.
+ void HandleInitialized(const base::ListValue* args);
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_AMBIENT_MODE_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.cc
new file mode 100644
index 00000000000..c9cfb838ce3
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.cc
@@ -0,0 +1,393 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.h"
+
+#include <numeric>
+
+#include "base/system/sys_info.h"
+#include "base/task/post_task.h"
+#include "base/task/thread_pool.h"
+#include "base/values.h"
+#include "chrome/browser/browsing_data/browsing_data_appcache_helper.h"
+#include "chrome/browser/browsing_data/browsing_data_cache_storage_helper.h"
+#include "chrome/browser/browsing_data/browsing_data_cookie_helper.h"
+#include "chrome/browser/browsing_data/browsing_data_database_helper.h"
+#include "chrome/browser/browsing_data/browsing_data_file_system_helper.h"
+#include "chrome/browser/browsing_data/browsing_data_flash_lso_helper.h"
+#include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h"
+#include "chrome/browser/browsing_data/browsing_data_service_worker_helper.h"
+#include "chrome/browser/chromeos/crostini/crostini_features.h"
+#include "chrome/browser/chromeos/file_manager/path_util.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chromeos/cryptohome/cryptohome_util.h"
+#include "chromeos/dbus/cryptohome/cryptohome_client.h"
+#include "components/arc/arc_service_manager.h"
+#include "components/arc/session/arc_bridge_service.h"
+#include "components/arc/storage_manager/arc_storage_manager.h"
+#include "components/browsing_data/content/conditional_cache_counting_helper.h"
+#include "components/browsing_data/content/local_storage_helper.h"
+#include "components/user_manager/user_manager.h"
+#include "content/public/browser/storage_partition.h"
+
+namespace chromeos {
+namespace settings {
+namespace calculator {
+
+namespace {
+
+void GetSizeStatBlocking(const base::FilePath& mount_path,
+ int64_t* total_size,
+ int64_t* available_size) {
+ int64_t size = base::SysInfo::AmountOfTotalDiskSpace(mount_path);
+ if (size >= 0)
+ *total_size = size;
+ size = base::SysInfo::AmountOfFreeDiskSpace(mount_path);
+ if (size >= 0)
+ *available_size = size;
+}
+
+} // namespace
+
+SizeCalculator::SizeCalculator(const CalculationType& calculation_type)
+ : calculation_type_(calculation_type) {}
+
+SizeCalculator::~SizeCalculator() {}
+
+void SizeCalculator::StartCalculation() {
+ if (calculating_)
+ return;
+ calculating_ = true;
+ PerformCalculation();
+}
+
+void SizeCalculator::AddObserver(SizeCalculator::Observer* observer) {
+ observers_.AddObserver(observer);
+}
+
+void SizeCalculator::RemoveObserver(SizeCalculator::Observer* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+void SizeCalculator::NotifySizeCalculated(
+ int64_t total_bytes,
+ const base::Optional<int64_t>& available_bytes) {
+ calculating_ = false;
+ for (SizeCalculator::Observer& observer : observers_) {
+ observer.OnSizeCalculated(calculation_type_, total_bytes, available_bytes);
+ }
+}
+
+SizeStatCalculator::SizeStatCalculator(Profile* profile)
+ : SizeCalculator(CalculationType::kInUse), profile_(profile) {}
+
+SizeStatCalculator::~SizeStatCalculator() = default;
+void SizeStatCalculator::PerformCalculation() {
+ const base::FilePath my_files_path =
+ file_manager::util::GetMyFilesFolderForProfile(profile_);
+
+ int64_t* total_size = new int64_t(0);
+ int64_t* available_size = new int64_t(0);
+ base::ThreadPool::PostTaskAndReply(
+ FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE},
+ base::Bind(&GetSizeStatBlocking, my_files_path, total_size,
+ available_size),
+ base::Bind(&SizeStatCalculator::OnGetSizeStat,
+ weak_ptr_factory_.GetWeakPtr(), base::Owned(total_size),
+ base::Owned(available_size)));
+}
+
+void SizeStatCalculator::OnGetSizeStat(int64_t* total_bytes,
+ int64_t* available_bytes) {
+ NotifySizeCalculated(*total_bytes, *available_bytes);
+}
+
+MyFilesSizeCalculator::MyFilesSizeCalculator(Profile* profile)
+ : SizeCalculator(CalculationType::kMyFiles), profile_(profile) {}
+
+MyFilesSizeCalculator::~MyFilesSizeCalculator() = default;
+
+void MyFilesSizeCalculator::PerformCalculation() {
+ const base::FilePath my_files_path =
+ file_manager::util::GetMyFilesFolderForProfile(profile_);
+
+ const base::FilePath android_files_path =
+ base::FilePath(file_manager::util::GetAndroidFilesPath());
+
+ base::ThreadPool::PostTaskAndReplyWithResult(
+ FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
+ base::BindOnce(&MyFilesSizeCalculator::ComputeLocalFilesSize,
+ base::Unretained(this), my_files_path, android_files_path),
+ base::BindOnce(&MyFilesSizeCalculator::OnGetMyFilesSize,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+int64_t MyFilesSizeCalculator::ComputeLocalFilesSize(
+ const base::FilePath& my_files_path,
+ const base::FilePath& android_files_path) {
+ int64_t size = 0;
+
+ // Compute directory size of My Files.
+ size += base::ComputeDirectorySize(my_files_path);
+
+ // Compute directory size of Play Files.
+ size += base::ComputeDirectorySize(android_files_path);
+
+ // Remove size of Download. If Android is enabled, the size of the Download
+ // folder is counted in both My Files and Play files. If Android is disabled,
+ // the Download folder doesn't exist and the returned size is 0.
+ const base::FilePath download_files_path =
+ android_files_path.AppendASCII("Download");
+ size -= base::ComputeDirectorySize(download_files_path);
+
+ return size;
+}
+
+void MyFilesSizeCalculator::OnGetMyFilesSize(int64_t total_bytes) {
+ NotifySizeCalculated(total_bytes);
+}
+
+BrowsingDataSizeCalculator::BrowsingDataSizeCalculator(Profile* profile)
+ : SizeCalculator(CalculationType::kBrowsingData), profile_(profile) {}
+
+BrowsingDataSizeCalculator::~BrowsingDataSizeCalculator() = default;
+
+void BrowsingDataSizeCalculator::PerformCalculation() {
+ has_browser_cache_size_ = false;
+ has_browser_site_data_size_ = false;
+
+ // Fetch the size of http cache in browsing data.
+ browsing_data::ConditionalCacheCountingHelper::Count(
+ content::BrowserContext::GetDefaultStoragePartition(profile_),
+ base::Time(), base::Time::Max(),
+ base::BindOnce(&BrowsingDataSizeCalculator::OnGetCacheSize,
+ weak_ptr_factory_.GetWeakPtr()));
+
+ // Fetch the size of site data in browsing data.
+ if (!site_data_size_collector_.get()) {
+ content::StoragePartition* storage_partition =
+ content::BrowserContext::GetDefaultStoragePartition(profile_);
+ site_data_size_collector_ = std::make_unique<SiteDataSizeCollector>(
+ storage_partition->GetPath(),
+ new BrowsingDataCookieHelper(storage_partition),
+ new BrowsingDataDatabaseHelper(profile_),
+ new browsing_data::LocalStorageHelper(profile_),
+ new BrowsingDataAppCacheHelper(storage_partition->GetAppCacheService()),
+ new BrowsingDataIndexedDBHelper(storage_partition),
+ BrowsingDataFileSystemHelper::Create(
+ storage_partition->GetFileSystemContext()),
+ new BrowsingDataServiceWorkerHelper(
+ storage_partition->GetServiceWorkerContext()),
+ new BrowsingDataCacheStorageHelper(
+ storage_partition->GetCacheStorageContext()),
+ BrowsingDataFlashLSOHelper::Create(profile_));
+ }
+ site_data_size_collector_->Fetch(
+ base::Bind(&BrowsingDataSizeCalculator::OnGetBrowsingDataSize,
+ weak_ptr_factory_.GetWeakPtr(), /*is_site_data=*/true));
+}
+
+void BrowsingDataSizeCalculator::OnGetCacheSize(bool is_upper_limit,
+ int64_t size) {
+ DCHECK(!is_upper_limit);
+ OnGetBrowsingDataSize(/*is_site_data=*/false, size);
+}
+
+void BrowsingDataSizeCalculator::OnGetBrowsingDataSize(bool is_site_data,
+ int64_t size) {
+ if (is_site_data) {
+ has_browser_site_data_size_ = true;
+ browser_site_data_size_ = size;
+ } else {
+ has_browser_cache_size_ = true;
+ browser_cache_size_ = size;
+ }
+ if (has_browser_cache_size_ && has_browser_site_data_size_) {
+ int64_t browsing_data_size;
+ if (browser_cache_size_ >= 0 && browser_site_data_size_ >= 0) {
+ browsing_data_size = browser_site_data_size_ + browser_cache_size_;
+ } else {
+ browsing_data_size = -1;
+ }
+ calculating_ = false;
+ NotifySizeCalculated(browsing_data_size);
+ }
+}
+
+AppsSizeCalculator::AppsSizeCalculator(Profile* profile)
+ : SizeCalculator(CalculationType::kAppsExtensions), profile_(profile) {}
+
+AppsSizeCalculator::~AppsSizeCalculator() {
+ arc::ArcServiceManager::Get()
+ ->arc_bridge_service()
+ ->storage_manager()
+ ->RemoveObserver(this);
+}
+
+void AppsSizeCalculator::OnConnectionReady() {
+ is_android_running_ = true;
+ StartCalculation();
+}
+
+void AppsSizeCalculator::OnConnectionClosed() {
+ is_android_running_ = false;
+}
+
+void AppsSizeCalculator::AddObserver(SizeCalculator::Observer* observer) {
+ // Start observing arc mojo connection when the first observer is added, to
+ // allow the calculation of android apps.
+ if (!observers_.might_have_observers()) {
+ arc::ArcServiceManager::Get()
+ ->arc_bridge_service()
+ ->storage_manager()
+ ->AddObserver(this);
+ }
+ observers_.AddObserver(observer);
+}
+
+void AppsSizeCalculator::RemoveObserver(SizeCalculator::Observer* observer) {
+ observers_.RemoveObserver(observer);
+ // Stop observing arc connection if all observers have been removed.
+ if (!observers_.might_have_observers()) {
+ arc::ArcServiceManager::Get()
+ ->arc_bridge_service()
+ ->storage_manager()
+ ->RemoveObserver(this);
+ }
+}
+
+void AppsSizeCalculator::PerformCalculation() {
+ apps_extensions_size_ = 0;
+ has_apps_extensions_size_ = false;
+ android_apps_size_ = 0;
+ has_android_apps_size_ = false;
+
+ UpdateAppsSize();
+ UpdateAndroidAppsSize();
+}
+
+void AppsSizeCalculator::UpdateAppsSize() {
+ // Apps and extensions installed from the web store located in
+ // [user-hash]/Extensions.
+ const base::FilePath extensions_path =
+ profile_->GetPath().AppendASCII("Extensions");
+
+ base::ThreadPool::PostTaskAndReplyWithResult(
+ FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
+ base::BindOnce(&base::ComputeDirectorySize, extensions_path),
+ base::BindOnce(&AppsSizeCalculator::OnGetAppsSize,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void AppsSizeCalculator::OnGetAppsSize(int64_t total_bytes) {
+ apps_extensions_size_ = total_bytes;
+ has_apps_extensions_size_ = true;
+ UpdateAppsAndExtensionsSize();
+}
+
+void AppsSizeCalculator::UpdateAndroidAppsSize() {
+ if (!is_android_running_) {
+ has_android_apps_size_ = true;
+ UpdateAppsAndExtensionsSize();
+ return;
+ }
+
+ bool success = false;
+ auto* arc_storage_manager =
+ arc::ArcStorageManager::GetForBrowserContext(profile_);
+ if (arc_storage_manager) {
+ success = arc_storage_manager->GetApplicationsSize(
+ base::BindOnce(&AppsSizeCalculator::OnGetAndroidAppsSize,
+ weak_ptr_factory_.GetWeakPtr()));
+ }
+ if (!success) {
+ has_android_apps_size_ = true;
+ UpdateAppsAndExtensionsSize();
+ }
+}
+
+void AppsSizeCalculator::OnGetAndroidAppsSize(
+ bool succeeded,
+ arc::mojom::ApplicationsSizePtr size) {
+ has_android_apps_size_ = true;
+ if (succeeded) {
+ android_apps_size_ = size->total_code_bytes + size->total_data_bytes +
+ size->total_cache_bytes;
+ }
+ UpdateAppsAndExtensionsSize();
+}
+
+void AppsSizeCalculator::UpdateAppsAndExtensionsSize() {
+ if (has_apps_extensions_size_ && has_android_apps_size_) {
+ calculating_ = false;
+ NotifySizeCalculated(apps_extensions_size_ + android_apps_size_);
+ }
+}
+
+CrostiniSizeCalculator::CrostiniSizeCalculator(Profile* profile)
+ : SizeCalculator(CalculationType::kCrostini), profile_(profile) {}
+
+CrostiniSizeCalculator::~CrostiniSizeCalculator() = default;
+
+void CrostiniSizeCalculator::PerformCalculation() {
+ if (!crostini::CrostiniFeatures::Get()->IsEnabled(profile_)) {
+ NotifySizeCalculated(0);
+ return;
+ }
+
+ crostini::CrostiniManager::GetForProfile(profile_)->ListVmDisks(
+ base::BindOnce(&CrostiniSizeCalculator::OnGetCrostiniSize,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void CrostiniSizeCalculator::OnGetCrostiniSize(crostini::CrostiniResult result,
+ int64_t total_bytes) {
+ calculating_ = false;
+ NotifySizeCalculated(total_bytes);
+}
+
+OtherUsersSizeCalculator::OtherUsersSizeCalculator()
+ : SizeCalculator(CalculationType::kOtherUsers) {}
+
+OtherUsersSizeCalculator::~OtherUsersSizeCalculator() = default;
+
+void OtherUsersSizeCalculator::PerformCalculation() {
+ other_users_.clear();
+ user_sizes_.clear();
+ const user_manager::UserList& users =
+ user_manager::UserManager::Get()->GetUsers();
+ for (auto* user : users) {
+ if (user->is_active())
+ continue;
+ other_users_.push_back(user);
+ CryptohomeClient::Get()->GetAccountDiskUsage(
+ cryptohome::CreateAccountIdentifierFromAccountId(user->GetAccountId()),
+ base::BindOnce(&OtherUsersSizeCalculator::OnGetOtherUserSize,
+ weak_ptr_factory_.GetWeakPtr()));
+ }
+ // We should show "0 B" if there is no other user.
+ if (other_users_.empty()) {
+ NotifySizeCalculated(0);
+ }
+}
+
+void OtherUsersSizeCalculator::OnGetOtherUserSize(
+ base::Optional<cryptohome::BaseReply> reply) {
+ user_sizes_.push_back(cryptohome::AccountDiskUsageReplyToUsageSize(reply));
+ if (user_sizes_.size() != other_users_.size())
+ return;
+ int64_t other_users_total_bytes;
+ // If all the requests succeed, shows the total bytes in the UI.
+ if (std::count(user_sizes_.begin(), user_sizes_.end(), -1) == 0) {
+ other_users_total_bytes =
+ std::accumulate(user_sizes_.begin(), user_sizes_.end(), 0LL);
+ } else {
+ other_users_total_bytes = -1;
+ }
+ NotifySizeCalculated(other_users_total_bytes);
+}
+
+} // namespace calculator
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.h b/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.h
new file mode 100644
index 00000000000..8f483f50b95
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.h
@@ -0,0 +1,296 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_CALCULATOR_SIZE_CALCULATOR_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_CALCULATOR_SIZE_CALCULATOR_H_
+
+#include <array>
+#include <bitset>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/files/file_util.h"
+#include "base/memory/weak_ptr.h"
+#include "base/observer_list_types.h"
+#include "base/values.h"
+#include "chrome/browser/browsing_data/site_data_size_collector.h"
+#include "chrome/browser/chromeos/crostini/crostini_manager.h"
+#include "chromeos/dbus/cryptohome/rpc.pb.h"
+#include "components/arc/mojom/storage_manager.mojom.h"
+#include "components/arc/session/connection_observer.h"
+#include "components/arc/storage_manager/arc_storage_manager.h"
+#include "components/user_manager/user.h"
+
+class Profile;
+
+namespace chromeos {
+namespace settings {
+namespace calculator {
+
+// Base class for the calculation of a specific storage item. Instances of this
+// class rely on their observers calling StartCalculation, and are designed to
+// notify observers about the calculated sizes.
+class SizeCalculator {
+ public:
+ // Enumeration listing the items displayed on the storage page.
+ enum class CalculationType {
+ kInUse = 0,
+ kMyFiles,
+ kBrowsingData,
+ kAppsExtensions,
+ kCrostini,
+ kOtherUsers,
+ kLast = kOtherUsers,
+ kSystem,
+ };
+
+ // Implement this interface to be notified about item size callbacks.
+ class Observer : public base::CheckedObserver {
+ public:
+ virtual void OnSizeCalculated(
+ const CalculationType& item_id,
+ int64_t total_bytes,
+ const base::Optional<int64_t>& available_bytes) = 0;
+ };
+
+ // Total number of storage items.
+ static constexpr int kCalculationTypeCount =
+ static_cast<int>(CalculationType::kLast) + 1;
+
+ explicit SizeCalculator(const CalculationType& calculation_type);
+ virtual ~SizeCalculator();
+
+ // Starts the size calculation of a given storage item.
+ void StartCalculation();
+
+ // Adds an observer.
+ virtual void AddObserver(Observer* observer);
+
+ // Removes an observer.
+ virtual void RemoveObserver(Observer* observer);
+
+ protected:
+ // Performs the size calculation.
+ virtual void PerformCalculation() = 0;
+
+ // Notify the StorageHandler about the calculated storage item size
+ void NotifySizeCalculated(
+ int64_t total_bytes,
+ const base::Optional<int64_t>& available_bytes = base::nullopt);
+
+ // Item id.
+ const CalculationType calculation_type_;
+
+ // Flag indicating that fetch operations for storage size are ongoing.
+ bool calculating_ = false;
+ // Observers being notified about storage items size changes.
+ base::ObserverList<SizeCalculator::Observer> observers_;
+};
+
+// Class handling the interactions with the filesystem to get storage
+// statistics, using OnSizeStatCalculated to notify observers.
+class SizeStatCalculator : public SizeCalculator {
+ public:
+ explicit SizeStatCalculator(Profile* profile);
+ ~SizeStatCalculator() override;
+
+ SizeStatCalculator(const SizeStatCalculator&) = delete;
+ SizeStatCalculator& operator=(const SizeStatCalculator&) = delete;
+
+ private:
+ friend class SizeStatTestAPI;
+
+ void PerformCalculation() override;
+
+ // Updates disk space information.
+ void OnGetSizeStat(int64_t* total_bytes, int64_t* available_bytes);
+
+ Profile* profile_;
+ base::WeakPtrFactory<SizeStatCalculator> weak_ptr_factory_{this};
+};
+
+// Class handling the calculation of the size of the user's personal files: My
+// files + Android Play files.
+class MyFilesSizeCalculator : public SizeCalculator {
+ public:
+ explicit MyFilesSizeCalculator(Profile* profile);
+ ~MyFilesSizeCalculator() override;
+
+ MyFilesSizeCalculator(const MyFilesSizeCalculator&) = delete;
+ MyFilesSizeCalculator& operator=(const MyFilesSizeCalculator&) = delete;
+
+ private:
+ friend class MyFilesSizeTestAPI;
+
+ void PerformCalculation() override;
+
+ // Computes the size of My Files and Play files.
+ int64_t ComputeLocalFilesSize(const base::FilePath& my_files_path,
+ const base::FilePath& android_files_path);
+
+ // Updates the size of My Files and Play files.
+ void OnGetMyFilesSize(int64_t total_bytes);
+
+ Profile* profile_;
+ base::WeakPtrFactory<MyFilesSizeCalculator> weak_ptr_factory_{this};
+};
+
+// Class handling the calculation of browsing data and cache.
+class BrowsingDataSizeCalculator : public SizeCalculator {
+ public:
+ explicit BrowsingDataSizeCalculator(Profile* profile);
+ ~BrowsingDataSizeCalculator() override;
+
+ BrowsingDataSizeCalculator(const BrowsingDataSizeCalculator&) = delete;
+ BrowsingDataSizeCalculator& operator=(const BrowsingDataSizeCalculator&) =
+ delete;
+
+ private:
+ friend class BrowsingDataSizeTestAPI;
+
+ void PerformCalculation() override;
+
+ // Callback to receive the cache size.
+ void OnGetCacheSize(bool is_upper_limit, int64_t size);
+
+ // Callback to update the size of browsing data.
+ void OnGetBrowsingDataSize(bool is_site_data, int64_t size);
+
+ // Total size of cache data in browsing data.
+ int64_t browser_cache_size_ = -1;
+
+ // True if we have already received the size of http cache.
+ bool has_browser_cache_size_ = false;
+
+ // Total size of site data in browsing data.
+ int64_t browser_site_data_size_ = -1;
+
+ // True if we have already received the size of http cache.
+ bool has_browser_site_data_size_ = false;
+
+ // Helper to compute the total size of all types of site date.
+ std::unique_ptr<SiteDataSizeCollector> site_data_size_collector_;
+
+ Profile* profile_;
+ base::WeakPtrFactory<BrowsingDataSizeCalculator> weak_ptr_factory_{this};
+};
+
+// Class handling the calculation of the size of the user's apps and extensions.
+class AppsSizeCalculator
+ : public SizeCalculator,
+ public arc::ConnectionObserver<arc::mojom::StorageManagerInstance> {
+ public:
+ explicit AppsSizeCalculator(Profile* profile);
+ ~AppsSizeCalculator() override;
+
+ AppsSizeCalculator(const AppsSizeCalculator&) = delete;
+ AppsSizeCalculator& operator=(const AppsSizeCalculator&) = delete;
+
+ // arc::ConnectionObserver<arc::mojom::StorageManagerInstance>:
+ void OnConnectionReady() override;
+ void OnConnectionClosed() override;
+
+ // Adds an observer. When the first observer is added, start observing the arc
+ // mojo connection UpdateAndroidAppsSize relies on.
+ void AddObserver(Observer* observer) override;
+
+ // Removes an observer. When the last observer is removed, stop observing the
+ // arc mojo connection.
+ void RemoveObserver(Observer* observer) override;
+
+ private:
+ friend class AppsSizeTestAPI;
+
+ void PerformCalculation() override;
+
+ // Requests updating the size of web store apps and extensions.
+ void UpdateAppsSize();
+
+ // Callback to update web store apps and extensions size.
+ void OnGetAppsSize(int64_t total_bytes);
+
+ // Requests updating the size of android apps.
+ void UpdateAndroidAppsSize();
+
+ // Callback to update Android apps and cache.
+ void OnGetAndroidAppsSize(bool succeeded,
+ arc::mojom::ApplicationsSizePtr size);
+
+ // Updates apps and extensions size.
+ void UpdateAppsAndExtensionsSize();
+
+ // Total size of apps and extensions
+ int64_t apps_extensions_size_ = 0;
+
+ // True if we have already received the size of apps and extensions.
+ bool has_apps_extensions_size_ = false;
+
+ // Total size of android apps
+ int64_t android_apps_size_ = 0;
+
+ // True if we have already received the size of Android apps.
+ bool has_android_apps_size_ = false;
+
+ // A flag for keeping track of the mojo connection status to the ARC
+ // container.
+ bool is_android_running_ = false;
+
+ Profile* profile_;
+ base::WeakPtrFactory<AppsSizeCalculator> weak_ptr_factory_{this};
+};
+
+// Class handling the calculation of crostini VM size.
+class CrostiniSizeCalculator : public SizeCalculator {
+ public:
+ explicit CrostiniSizeCalculator(Profile* profile);
+ ~CrostiniSizeCalculator() override;
+
+ CrostiniSizeCalculator(const CrostiniSizeCalculator&) = delete;
+ CrostiniSizeCalculator& operator=(const CrostiniSizeCalculator&) = delete;
+
+ private:
+ friend class CrostiniSizeTestAPI;
+
+ void PerformCalculation() override;
+
+ // Callback to update the size of Crostini VMs.
+ void OnGetCrostiniSize(crostini::CrostiniResult result, int64_t size);
+
+ Profile* profile_;
+ base::WeakPtrFactory<CrostiniSizeCalculator> weak_ptr_factory_{this};
+};
+
+// Class handling the calculation of other users' cryptohomes.
+class OtherUsersSizeCalculator : public SizeCalculator {
+ public:
+ OtherUsersSizeCalculator();
+ ~OtherUsersSizeCalculator() override;
+
+ OtherUsersSizeCalculator(const OtherUsersSizeCalculator&) = delete;
+ OtherUsersSizeCalculator& operator=(const OtherUsersSizeCalculator&) = delete;
+
+ private:
+ friend class OtherUsersSizeTestAPI;
+
+ void PerformCalculation() override;
+
+ // Callback to update the sizes of the other users.
+ void OnGetOtherUserSize(base::Optional<cryptohome::BaseReply> reply);
+
+ // The list of other users whose directory sizes will be accumulated as the
+ // size of "Other users".
+ user_manager::UserList other_users_;
+
+ // Fetched sizes of user directories.
+ std::vector<int64_t> user_sizes_;
+
+ base::WeakPtrFactory<OtherUsersSizeCalculator> weak_ptr_factory_{this};
+};
+
+} // namespace calculator
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_CALCULATOR_SIZE_CALCULATOR_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator_test_api.h b/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator_test_api.h
new file mode 100644
index 00000000000..2e0850df244
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator_test_api.h
@@ -0,0 +1,156 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_CALCULATOR_SIZE_CALCULATOR_TEST_API_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_CALCULATOR_SIZE_CALCULATOR_TEST_API_H_
+
+#include <utility>
+
+#include "chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.h"
+#include "chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h"
+
+namespace chromeos {
+namespace settings {
+namespace calculator {
+
+class SizeStatTestAPI {
+ public:
+ explicit SizeStatTestAPI(StorageHandler* handler,
+ SizeStatCalculator* size_stat_calculator) {
+ size_stat_calculator_ = size_stat_calculator;
+ size_stat_calculator_->AddObserver(handler);
+ }
+
+ void StartCalculation() { size_stat_calculator_->StartCalculation(); }
+
+ void SimulateOnGetSizeStat(int64_t* total_size, int64_t* available_size) {
+ size_stat_calculator_->OnGetSizeStat(total_size, available_size);
+ }
+
+ private:
+ SizeStatCalculator* size_stat_calculator_;
+};
+
+class MyFilesSizeTestAPI {
+ public:
+ explicit MyFilesSizeTestAPI(StorageHandler* handler,
+ MyFilesSizeCalculator* my_files_size_calculator) {
+ my_files_size_calculator_ = my_files_size_calculator;
+ my_files_size_calculator_->AddObserver(handler);
+ }
+
+ void StartCalculation() { my_files_size_calculator_->StartCalculation(); }
+
+ void SimulateOnGetTotalBytes(int64_t total_bytes) {
+ my_files_size_calculator_->NotifySizeCalculated(total_bytes);
+ }
+
+ private:
+ MyFilesSizeCalculator* my_files_size_calculator_;
+};
+
+class BrowsingDataSizeTestAPI {
+ public:
+ explicit BrowsingDataSizeTestAPI(
+ StorageHandler* handler,
+ BrowsingDataSizeCalculator* browsing_data_size_calculator) {
+ browsing_data_size_calculator_ = browsing_data_size_calculator;
+ browsing_data_size_calculator_->AddObserver(handler);
+ }
+
+ void StartCalculation() {
+ browsing_data_size_calculator_->StartCalculation();
+ }
+
+ void SimulateOnGetBrowsingDataSize(bool is_site_data, int64_t size) {
+ browsing_data_size_calculator_->OnGetBrowsingDataSize(is_site_data, size);
+ }
+
+ private:
+ BrowsingDataSizeCalculator* browsing_data_size_calculator_;
+};
+
+class AppsSizeTestAPI {
+ public:
+ explicit AppsSizeTestAPI(StorageHandler* handler,
+ AppsSizeCalculator* apps_size_calculator) {
+ apps_size_calculator_ = apps_size_calculator;
+ apps_size_calculator_->AddObserver(handler);
+ }
+
+ void StartCalculation() { apps_size_calculator_->StartCalculation(); }
+
+ void SimulateOnGetAppsSize(int64_t total_bytes) {
+ apps_size_calculator_->OnGetAppsSize(total_bytes);
+ }
+
+ void SimulateOnGetAndroidAppsSize(bool succeeded,
+ uint64_t total_code_bytes,
+ uint64_t total_data_bytes,
+ uint64_t total_cache_bytes) {
+ arc::mojom::ApplicationsSizePtr result(
+ ::arc::mojom::ApplicationsSize::New());
+ result->total_code_bytes = total_code_bytes;
+ result->total_data_bytes = total_data_bytes;
+ result->total_cache_bytes = total_cache_bytes;
+ apps_size_calculator_->OnGetAndroidAppsSize(succeeded, std::move(result));
+ }
+
+ private:
+ AppsSizeCalculator* apps_size_calculator_;
+};
+
+class CrostiniSizeTestAPI {
+ public:
+ explicit CrostiniSizeTestAPI(
+ StorageHandler* handler,
+ CrostiniSizeCalculator* crostini_size_calculator) {
+ crostini_size_calculator_ = crostini_size_calculator;
+ crostini_size_calculator_->AddObserver(handler);
+ }
+
+ void StartCalculation() { crostini_size_calculator_->StartCalculation(); }
+
+ void SimulateOnGetCrostiniSize(int64_t size) {
+ crostini_size_calculator_->OnGetCrostiniSize(
+ crostini::CrostiniResult::SUCCESS, size);
+ }
+
+ private:
+ CrostiniSizeCalculator* crostini_size_calculator_;
+};
+
+class OtherUsersSizeTestAPI {
+ public:
+ explicit OtherUsersSizeTestAPI(
+ StorageHandler* handler,
+ OtherUsersSizeCalculator* other_users_size_calculator) {
+ other_users_size_calculator_ = other_users_size_calculator;
+ other_users_size_calculator_->AddObserver(handler);
+ }
+
+ void StartCalculation() { other_users_size_calculator_->StartCalculation(); }
+
+ void InitializeOtherUserSize(int user_count) {
+ // When calling OnGetOtherUserSize, a callback is fired when
+ // user_sizes_.size() == other_users_.size(). We want to control the size of
+ // |other_users_|, rather than its content. This function initializes
+ // other_users_ as a list of |user_count| nullptrs.
+ other_users_size_calculator_->other_users_ =
+ user_manager::UserList(user_count);
+ }
+
+ void SimulateOnGetOtherUserSize(base::Optional<cryptohome::BaseReply> reply) {
+ other_users_size_calculator_->OnGetOtherUserSize(reply);
+ }
+
+ private:
+ OtherUsersSizeCalculator* other_users_size_calculator_;
+};
+
+} // namespace calculator
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_CALCULATOR_SIZE_CALCULATOR_TEST_API_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc
index ed3cdc8465d..4bd641f16e6 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc
@@ -18,6 +18,7 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
+#include "base/task/thread_pool.h"
#include "base/values.h"
#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
#include "chrome/browser/chromeos/camera_presence_notifier.h"
@@ -228,8 +229,8 @@ void ChangePictureHandler::SendSelectedImage() {
DCHECK(previous_image_.IsThreadSafe());
// Post a task because GetBitmapDataUrl does PNG encoding, which is
// slow for large images.
- base::PostTaskAndReplyWithResult(
- FROM_HERE, {base::ThreadPool(), base::TaskPriority::USER_BLOCKING},
+ base::ThreadPool::PostTaskAndReplyWithResult(
+ FROM_HERE, {base::TaskPriority::USER_BLOCKING},
base::BindOnce(&webui::GetBitmapDataUrl, *previous_image_.bitmap()),
base::BindOnce(&ChangePictureHandler::SendOldImage,
weak_ptr_factory_.GetWeakPtr()));
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h
index a3bb95d292e..1be240f6115 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h
@@ -9,7 +9,7 @@
#include "base/memory/weak_ptr.h"
#include "base/scoped_observer.h"
#include "chrome/browser/chromeos/camera_presence_notifier.h"
-#include "chrome/browser/image_decoder.h"
+#include "chrome/browser/image_decoder/image_decoder.h"
#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
#include "components/user_manager/user_manager.h"
#include "ui/gfx/image/image_skia.h"
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc
index 1c966904f49..1351b63b654 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc
@@ -9,21 +9,27 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/callback_forward.h"
#include "base/metrics/histogram_functions.h"
#include "chrome/browser/browser_process.h"
-#include "chrome/browser/browser_process_platform_part.h"
+#include "chrome/browser/chromeos/crostini/crostini_disk.h"
+#include "chrome/browser/chromeos/crostini/crostini_features.h"
+#include "chrome/browser/chromeos/crostini/crostini_installer.h"
+#include "chrome/browser/chromeos/crostini/crostini_port_forwarder.h"
+#include "chrome/browser/chromeos/crostini/crostini_pref_names.h"
+#include "chrome/browser/chromeos/crostini/crostini_types.mojom.h"
#include "chrome/browser/chromeos/crostini/crostini_util.h"
#include "chrome/browser/chromeos/file_manager/path_util.h"
#include "chrome/browser/chromeos/guest_os/guest_os_share_path.h"
-#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/lifetime/application_lifetime.h"
-#include "chrome/browser/policy/profile_policy_connector.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/webui/chromeos/crostini_upgrader/crostini_upgrader_dialog.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "components/user_manager/user_manager.h"
#include "content/public/browser/browser_thread.h"
+#include "ui/display/screen.h"
namespace chromeos {
namespace settings {
@@ -105,11 +111,42 @@ void CrostiniHandler::RegisterMessages() {
"disableArcAdbSideload",
base::BindRepeating(&CrostiniHandler::HandleDisableArcAdbRequest,
weak_ptr_factory_.GetWeakPtr()));
+ web_ui()->RegisterMessageCallback(
+ "requestCrostiniContainerUpgradeView",
+ base::BindRepeating(&CrostiniHandler::HandleRequestContainerUpgradeView,
+ weak_ptr_factory_.GetWeakPtr()));
+ web_ui()->RegisterMessageCallback(
+ "requestCrostiniUpgraderDialogStatus",
+ base::BindRepeating(
+ &CrostiniHandler::HandleCrostiniUpgraderDialogStatusRequest,
+ weak_ptr_factory_.GetWeakPtr()));
+ web_ui()->RegisterMessageCallback(
+ "requestCrostiniContainerUpgradeAvailable",
+ base::BindRepeating(
+ &CrostiniHandler::HandleCrostiniContainerUpgradeAvailableRequest,
+ weak_ptr_factory_.GetWeakPtr()));
+ web_ui()->RegisterMessageCallback(
+ "addCrostiniPortForward",
+ base::BindRepeating(&CrostiniHandler::HandleAddCrostiniPortForward,
+ weak_ptr_factory_.GetWeakPtr()));
+ web_ui()->RegisterMessageCallback(
+ "getCrostiniDiskInfo",
+ base::BindRepeating(&CrostiniHandler::HandleGetCrostiniDiskInfo,
+ weak_ptr_factory_.GetWeakPtr()));
+ web_ui()->RegisterMessageCallback(
+ "resizeCrostiniDisk",
+ base::BindRepeating(&CrostiniHandler::HandleResizeCrostiniDisk,
+ weak_ptr_factory_.GetWeakPtr()));
+ web_ui()->RegisterMessageCallback(
+ "checkCrostiniMicSharingStatus",
+ base::BindRepeating(&CrostiniHandler::HandleCheckCrostiniMicSharingStatus,
+ weak_ptr_factory_.GetWeakPtr()));
}
void CrostiniHandler::OnJavascriptAllowed() {
- crostini::CrostiniManager::GetForProfile(profile_)
- ->AddInstallerViewStatusObserver(this);
+ auto* crostini_manager = crostini::CrostiniManager::GetForProfile(profile_);
+ crostini_manager->AddCrostiniDialogStatusObserver(this);
+ crostini_manager->AddCrostiniContainerPropertiesObserver(this);
if (chromeos::CrosUsbDetector::Get()) {
chromeos::CrosUsbDetector::Get()->AddUsbDeviceObserver(this);
}
@@ -117,11 +154,9 @@ void CrostiniHandler::OnJavascriptAllowed() {
}
void CrostiniHandler::OnJavascriptDisallowed() {
- if (crostini::CrostiniManager::GetForProfile(profile_)
- ->HasInstallerViewStatusObserver(this)) {
- crostini::CrostiniManager::GetForProfile(profile_)
- ->RemoveInstallerViewStatusObserver(this);
- }
+ auto* crostini_manager = crostini::CrostiniManager::GetForProfile(profile_);
+ crostini_manager->RemoveCrostiniDialogStatusObserver(this);
+ crostini_manager->RemoveCrostiniContainerPropertiesObserver(this);
if (chromeos::CrosUsbDetector::Get()) {
chromeos::CrosUsbDetector::Get()->RemoveUsbDeviceObserver(this);
}
@@ -131,8 +166,8 @@ void CrostiniHandler::OnJavascriptDisallowed() {
void CrostiniHandler::HandleRequestCrostiniInstallerView(
const base::ListValue* args) {
AllowJavascript();
- ShowCrostiniInstallerView(Profile::FromWebUI(web_ui()),
- crostini::CrostiniUISurface::kSettings);
+ crostini::CrostiniInstaller::GetForProfile(Profile::FromWebUI(web_ui()))
+ ->ShowDialog(crostini::CrostiniUISurface::kSettings);
}
void CrostiniHandler::HandleRequestRemoveCrostini(const base::ListValue* args) {
@@ -144,40 +179,42 @@ void CrostiniHandler::HandleRequestRemoveCrostini(const base::ListValue* args) {
void CrostiniHandler::HandleGetCrostiniSharedPathsDisplayText(
const base::ListValue* args) {
AllowJavascript();
- CHECK_EQ(2U, args->GetSize());
- std::string callback_id;
- const base::ListValue* paths;
- CHECK(args->GetString(0, &callback_id));
- CHECK(args->GetList(1, &paths));
+ CHECK_EQ(2U, args->GetList().size());
+ std::string callback_id = args->GetList()[0].GetString();
+ base::Value::ConstListView paths = args->GetList()[1].GetList();
base::ListValue texts;
- for (auto it = paths->begin(); it != paths->end(); ++it) {
+ for (size_t i = 0; i < paths.size(); ++i) {
texts.AppendString(file_manager::util::GetPathDisplayTextForSettings(
- profile_, it->GetString()));
+ profile_, paths[i].GetString()));
}
ResolveJavascriptCallback(base::Value(callback_id), texts);
}
void CrostiniHandler::HandleRemoveCrostiniSharedPath(
const base::ListValue* args) {
- CHECK_EQ(2U, args->GetSize());
- std::string vm_name;
- CHECK(args->GetString(0, &vm_name));
- std::string path;
- CHECK(args->GetString(1, &path));
+ AllowJavascript();
+ CHECK_EQ(3U, args->GetList().size());
+ std::string callback_id = args->GetList()[0].GetString();
+ std::string vm_name = args->GetList()[1].GetString();
+ std::string path = args->GetList()[2].GetString();
guest_os::GuestOsSharePath::GetForProfile(profile_)->UnsharePath(
vm_name, base::FilePath(path),
/*unpersist=*/true,
- base::BindOnce(
- [](const std::string& path, bool result,
- const std::string& failure_reason) {
- if (!result) {
- LOG(ERROR) << "Error unsharing " << path << ": "
- << failure_reason;
- }
- },
- path));
+ base::BindOnce(&CrostiniHandler::OnCrostiniSharedPathRemoved,
+ weak_ptr_factory_.GetWeakPtr(), callback_id, path));
+}
+
+void CrostiniHandler::OnCrostiniSharedPathRemoved(
+ const std::string& callback_id,
+ const std::string& path,
+ bool result,
+ const std::string& failure_reason) {
+ if (!result) {
+ LOG(ERROR) << "Error unsharing " << path << ": " << failure_reason;
+ }
+ ResolveJavascriptCallback(base::Value(callback_id), base::Value(result));
}
namespace {
@@ -195,12 +232,35 @@ base::ListValue UsbDevicesToListValue(
}
return usb_devices_list;
}
+
+base::Value CrostiniDiskInfoToValue(
+ std::unique_ptr<crostini::CrostiniDiskInfo> disk_info) {
+ base::Value disk_value(base::Value::Type::DICTIONARY);
+ if (!disk_info) {
+ disk_value.SetBoolKey("succeeded", false);
+ return disk_value;
+ }
+ disk_value.SetBoolKey("succeeded", true);
+ disk_value.SetBoolKey("canResize", disk_info->can_resize);
+ disk_value.SetBoolKey("isUserChosenSize", disk_info->is_user_chosen_size);
+ disk_value.SetIntKey("defaultIndex", disk_info->default_index);
+ base::Value ticks(base::Value::Type::LIST);
+ for (const auto& tick : disk_info->ticks) {
+ base::Value t(base::Value::Type::DICTIONARY);
+ t.SetDoubleKey("value", static_cast<double>(tick->value));
+ t.SetStringKey("ariaValue", tick->aria_value);
+ t.SetStringKey("label", tick->label);
+ ticks.Append(std::move(t));
+ }
+ disk_value.SetKey("ticks", std::move(ticks));
+ return disk_value;
+}
} // namespace
void CrostiniHandler::HandleGetCrostiniSharedUsbDevices(
const base::ListValue* args) {
AllowJavascript();
- CHECK_EQ(1U, args->GetSize());
+ CHECK_EQ(1U, args->GetList().size());
std::string callback_id = args->GetList()[0].GetString();
@@ -217,7 +277,7 @@ void CrostiniHandler::HandleGetCrostiniSharedUsbDevices(
void CrostiniHandler::HandleSetCrostiniUsbDeviceShared(
const base::ListValue* args) {
- CHECK_EQ(2U, args->GetSize());
+ CHECK_EQ(2U, args->GetList().size());
const auto& args_list = args->GetList();
std::string guid = args_list[0].GetString();
bool shared = args_list[1].GetBool();
@@ -245,14 +305,14 @@ void CrostiniHandler::OnUsbDevicesChanged() {
void CrostiniHandler::HandleExportCrostiniContainer(
const base::ListValue* args) {
- CHECK_EQ(0U, args->GetSize());
+ CHECK_EQ(0U, args->GetList().size());
crostini::CrostiniExportImport::GetForProfile(profile_)->ExportContainer(
web_ui()->GetWebContents());
}
void CrostiniHandler::HandleImportCrostiniContainer(
const base::ListValue* args) {
- CHECK_EQ(0U, args->GetSize());
+ CHECK_EQ(0U, args->GetList().size());
crostini::CrostiniExportImport::GetForProfile(profile_)->ImportContainer(
web_ui()->GetWebContents());
}
@@ -260,45 +320,57 @@ void CrostiniHandler::HandleImportCrostiniContainer(
void CrostiniHandler::HandleCrostiniInstallerStatusRequest(
const base::ListValue* args) {
AllowJavascript();
- CHECK_EQ(0U, args->GetSize());
+ CHECK_EQ(0U, args->GetList().size());
bool status = crostini::CrostiniManager::GetForProfile(profile_)
- ->GetInstallerViewStatus();
- OnCrostiniInstallerViewStatusChanged(status);
+ ->GetCrostiniDialogStatus(crostini::DialogType::INSTALLER);
+ OnCrostiniDialogStatusChanged(crostini::DialogType::INSTALLER, status);
}
void CrostiniHandler::HandleCrostiniExportImportOperationStatusRequest(
const base::ListValue* args) {
AllowJavascript();
- CHECK_EQ(0U, args->GetSize());
+ CHECK_EQ(0U, args->GetList().size());
bool in_progress = crostini::CrostiniExportImport::GetForProfile(profile_)
->GetExportImportOperationStatus();
OnCrostiniExportImportOperationStatusChanged(in_progress);
}
-void CrostiniHandler::OnCrostiniInstallerViewStatusChanged(bool status) {
+void CrostiniHandler::OnCrostiniDialogStatusChanged(
+ crostini::DialogType dialog_type,
+ bool status) {
// It's technically possible for this to be called before Javascript is
// enabled, in which case we must not call FireWebUIListener
if (IsJavascriptAllowed()) {
// Other side listens with cr.addWebUIListener
- FireWebUIListener("crostini-installer-status-changed", base::Value(status));
+ switch (dialog_type) {
+ case crostini::DialogType::INSTALLER:
+ FireWebUIListener("crostini-installer-status-changed",
+ base::Value(status));
+ break;
+ case crostini::DialogType::UPGRADER:
+ FireWebUIListener("crostini-upgrader-status-changed",
+ base::Value(status));
+ break;
+ case crostini::DialogType::REMOVER:
+ FireWebUIListener("crostini-remover-status-changed",
+ base::Value(status));
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
}
}
-void CrostiniHandler::OnCrostiniExportImportOperationStatusChanged(
- bool in_progress) {
- // Other side listens with cr.addWebUIListener
- FireWebUIListener("crostini-export-import-operation-status-changed",
- base::Value(in_progress));
-}
-
-void CrostiniHandler::HandleQueryArcAdbRequest(const base::ListValue* args) {
- AllowJavascript();
- CHECK_EQ(0U, args->GetSize());
-
- chromeos::SessionManagerClient* client =
- chromeos::SessionManagerClient::Get();
- client->QueryAdbSideload(base::Bind(&CrostiniHandler::OnQueryAdbSideload,
- weak_ptr_factory_.GetWeakPtr()));
+void CrostiniHandler::OnContainerOsReleaseChanged(
+ const crostini::ContainerId& container_id,
+ bool can_upgrade) {
+ if (crostini::CrostiniFeatures::Get()->IsContainerUpgradeUIAllowed(
+ profile_) &&
+ container_id == crostini::DefaultContainerId()) {
+ FireWebUIListener("crostini-container-upgrade-available-changed",
+ base::Value(can_upgrade));
+ }
}
void CrostiniHandler::OnQueryAdbSideload(
@@ -317,7 +389,7 @@ void CrostiniHandler::OnQueryAdbSideload(
}
void CrostiniHandler::HandleEnableArcAdbRequest(const base::ListValue* args) {
- CHECK_EQ(0U, args->GetSize());
+ CHECK_EQ(0U, args->GetList().size());
if (!CheckEligibilityToChangeArcAdbSideloading())
return;
@@ -331,7 +403,7 @@ void CrostiniHandler::HandleEnableArcAdbRequest(const base::ListValue* args) {
}
void CrostiniHandler::HandleDisableArcAdbRequest(const base::ListValue* args) {
- CHECK_EQ(0U, args->GetSize());
+ CHECK_EQ(0U, args->GetList().size());
if (!CheckEligibilityToChangeArcAdbSideloading())
return;
@@ -346,28 +418,133 @@ void CrostiniHandler::HandleDisableArcAdbRequest(const base::ListValue* args) {
}
bool CrostiniHandler::CheckEligibilityToChangeArcAdbSideloading() const {
- if (!chromeos::ProfileHelper::IsOwnerProfile(profile_)) {
- DVLOG(1) << "Only the owner can change adb sideloading status";
- return false;
- }
+ return crostini::CrostiniFeatures::Get()->CanChangeAdbSideloading(profile_);
+}
- if (user_manager::UserManager::Get()->IsLoggedInAsChildUser()) {
- DVLOG(1) << "adb sideloading is currently unsupported for child account";
- return false;
- }
+void CrostiniHandler::LaunchTerminal() {
+ crostini::LaunchCrostiniApp(
+ profile_, crostini::GetTerminalId(),
+ display::Screen::GetScreen()->GetPrimaryDisplay().id());
+}
- if (profile_->GetProfilePolicyConnector()->IsManaged()) {
- DVLOG(1) << "adb sideloading is currently unsupported for managed user";
- return false;
- }
+void CrostiniHandler::HandleRequestContainerUpgradeView(
+ const base::ListValue* args) {
+ CHECK_EQ(0U, args->GetList().size());
+ chromeos::CrostiniUpgraderDialog::Show(
+ base::BindOnce(&CrostiniHandler::LaunchTerminal,
+ weak_ptr_factory_.GetWeakPtr()),
+ // If the user cancels the upgrade, we won't need to restart Crostini and
+ // we don't want to run the launch closure which would launch Terminal.
+ /*only_run_launch_closure_on_restart=*/true);
+}
- policy::BrowserPolicyConnectorChromeOS* connector =
- g_browser_process->platform_part()->browser_policy_connector_chromeos();
- if (connector->IsEnterpriseManaged()) {
- DVLOG(1) << "adb sideloading is currently unsupported on managed device";
- return false;
- }
- return true;
+void CrostiniHandler::OnCrostiniExportImportOperationStatusChanged(
+ bool in_progress) {
+ // Other side listens with cr.addWebUIListener
+ FireWebUIListener("crostini-export-import-operation-status-changed",
+ base::Value(in_progress));
+}
+
+void CrostiniHandler::HandleQueryArcAdbRequest(const base::ListValue* args) {
+ AllowJavascript();
+ CHECK_EQ(0U, args->GetList().size());
+
+ chromeos::SessionManagerClient* client =
+ chromeos::SessionManagerClient::Get();
+ client->QueryAdbSideload(base::Bind(&CrostiniHandler::OnQueryAdbSideload,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void CrostiniHandler::HandleCrostiniUpgraderDialogStatusRequest(
+ const base::ListValue* args) {
+ AllowJavascript();
+ CHECK_EQ(0U, args->GetList().size());
+ bool is_open = crostini::CrostiniManager::GetForProfile(profile_)
+ ->GetCrostiniDialogStatus(crostini::DialogType::UPGRADER);
+ OnCrostiniDialogStatusChanged(crostini::DialogType::UPGRADER, is_open);
+}
+
+void CrostiniHandler::HandleCrostiniContainerUpgradeAvailableRequest(
+ const base::ListValue* args) {
+ AllowJavascript();
+
+ bool can_upgrade = crostini::ShouldAllowContainerUpgrade(profile_);
+ OnContainerOsReleaseChanged(crostini::DefaultContainerId(), can_upgrade);
+}
+
+void CrostiniHandler::HandleAddCrostiniPortForward(
+ const base::ListValue* args) {
+ CHECK_EQ(6U, args->GetList().size());
+
+ std::string callback_id = args->GetList()[0].GetString();
+ std::string vm_name = args->GetList()[1].GetString();
+ std::string container_name = args->GetList()[2].GetString();
+ int port_number = args->GetList()[3].GetInt();
+ int protocol_type = args->GetList()[4].GetInt();
+ std::string label = args->GetList()[5].GetString();
+
+ crostini::CrostiniPortForwarder::GetForProfile(profile_)->AddPort(
+ crostini::ContainerId(std::move(vm_name), std::move(container_name)),
+ port_number,
+ static_cast<crostini::CrostiniPortForwarder::Protocol>(protocol_type),
+ std::move(label),
+ base::Bind(&CrostiniHandler::OnPortForwardComplete,
+ weak_ptr_factory_.GetWeakPtr(), std::move(callback_id)));
+}
+
+void CrostiniHandler::OnPortForwardComplete(std::string callback_id,
+ bool success) {
+ ResolveJavascriptCallback(base::Value(callback_id), base::Value(success));
+}
+
+void CrostiniHandler::ResolveGetCrostiniDiskInfoCallback(
+ const std::string& callback_id,
+ std::unique_ptr<crostini::CrostiniDiskInfo> disk_info) {
+ ResolveJavascriptCallback(base::Value(std::move(callback_id)),
+ CrostiniDiskInfoToValue(std::move(disk_info)));
+}
+
+void CrostiniHandler::HandleGetCrostiniDiskInfo(const base::ListValue* args) {
+ AllowJavascript();
+ CHECK_EQ(2U, args->GetList().size());
+ std::string callback_id = args->GetList()[0].GetString();
+ std::string vm_name = args->GetList()[1].GetString();
+ crostini::disk::GetDiskInfo(
+ base::BindOnce(&CrostiniHandler::ResolveGetCrostiniDiskInfoCallback,
+ weak_ptr_factory_.GetWeakPtr(), std::move(callback_id)),
+ profile_, std::move(vm_name));
+}
+
+void CrostiniHandler::HandleResizeCrostiniDisk(const base::ListValue* args) {
+ CHECK_EQ(3U, args->GetList().size());
+ std::string callback_id = args->GetList()[0].GetString();
+ std::string vm_name = args->GetList()[1].GetString();
+ double bytes = args->GetList()[2].GetDouble();
+ crostini::disk::ResizeCrostiniDisk(
+ profile_, std::move(vm_name), bytes,
+ base::BindOnce(&CrostiniHandler::ResolveResizeCrostiniDiskCallback,
+ weak_ptr_factory_.GetWeakPtr(), std::move(callback_id)));
+}
+
+void CrostiniHandler::ResolveResizeCrostiniDiskCallback(
+ const std::string& callback_id,
+ bool succeeded) {
+ ResolveJavascriptCallback(base::Value(std::move(callback_id)),
+ base::Value(succeeded));
+}
+
+void CrostiniHandler::HandleCheckCrostiniMicSharingStatus(
+ const base::ListValue* args) {
+ CHECK_EQ(2U, args->GetList().size());
+ std::string callback_id = args->GetList()[0].GetString();
+ bool proposed_value = args->GetList()[1].GetBool();
+ bool requiresRestart =
+ crostini::IsCrostiniRunning(profile_) &&
+ profile_->GetPrefs()->GetBoolean(
+ crostini::prefs::kCrostiniMicSharingAtLastLaunch) != proposed_value;
+
+ ResolveJavascriptCallback(base::Value(std::move(callback_id)),
+ base::Value(requiresRestart));
}
} // namespace settings
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.h
index bab8509806a..f51fc69e1b7 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.h
@@ -18,14 +18,16 @@ class Profile;
namespace crostini {
enum class CrostiniResult;
-}
+struct CrostiniDiskInfo;
+} // namespace crostini
namespace chromeos {
namespace settings {
class CrostiniHandler : public ::settings::SettingsPageUIHandler,
- public crostini::InstallerViewStatusObserver,
+ public crostini::CrostiniDialogStatusObserver,
public crostini::CrostiniExportImport::Observer,
+ public crostini::CrostiniContainerPropertiesObserver,
public chromeos::CrosUsbDeviceObserver {
public:
explicit CrostiniHandler(Profile* profile);
@@ -45,6 +47,10 @@ class CrostiniHandler : public ::settings::SettingsPageUIHandler,
void HandleGetCrostiniSharedPathsDisplayText(const base::ListValue* args);
// Remove a specified path from being shared.
void HandleRemoveCrostiniSharedPath(const base::ListValue* args);
+ void OnCrostiniSharedPathRemoved(const std::string& callback_id,
+ const std::string& path,
+ bool result,
+ const std::string& failure_reason);
// Returns a list of available USB devices.
void HandleGetCrostiniSharedUsbDevices(const base::ListValue* args);
// Set the share state of a USB device.
@@ -57,8 +63,12 @@ class CrostiniHandler : public ::settings::SettingsPageUIHandler,
void HandleImportCrostiniContainer(const base::ListValue* args);
// Handle a request for the CrostiniInstallerView status.
void HandleCrostiniInstallerStatusRequest(const base::ListValue* args);
- // Handle the CrostiniInstallerView opening/closing.
- void OnCrostiniInstallerViewStatusChanged(bool open) override;
+ // crostini::CrostiniDialogStatusObserver
+ void OnCrostiniDialogStatusChanged(crostini::DialogType dialog_type,
+ bool open) override;
+ // crostini::CrostiniContainerPropertiesObserver
+ void OnContainerOsReleaseChanged(const crostini::ContainerId& container_id,
+ bool can_upgrade) override;
// Handle a request for the CrostiniExportImport operation status.
void HandleCrostiniExportImportOperationStatusRequest(
const base::ListValue* args);
@@ -70,6 +80,10 @@ class CrostiniHandler : public ::settings::SettingsPageUIHandler,
void HandleEnableArcAdbRequest(const base::ListValue* args);
// Handle a request for disabling adb sideloading in ARC.
void HandleDisableArcAdbRequest(const base::ListValue* args);
+ // Launch the Crostini terminal.
+ void LaunchTerminal();
+ // Handle a request for showing the container upgrade view.
+ void HandleRequestContainerUpgradeView(const base::ListValue* args);
// Callback of HandleQueryArcAdbRequest.
void OnQueryAdbSideload(
SessionManagerClient::AdbSideloadResponseCode response_code,
@@ -77,6 +91,26 @@ class CrostiniHandler : public ::settings::SettingsPageUIHandler,
// Returns whether the current user can change adb sideloading configuration
// on current device.
bool CheckEligibilityToChangeArcAdbSideloading() const;
+ // Handle a request for the CrostiniUpgraderDialog status.
+ void HandleCrostiniUpgraderDialogStatusRequest(const base::ListValue* args);
+ // Handle a request for the availability of a container upgrade.
+ void HandleCrostiniContainerUpgradeAvailableRequest(
+ const base::ListValue* args);
+ // Handles a request for forwarding a new port.
+ void HandleAddCrostiniPortForward(const base::ListValue* args);
+ // Callback of port forwarding requests.
+ void OnPortForwardComplete(std::string callback_id, bool success);
+ // Fetches disk info for a VM, can be slow (seconds).
+ void HandleGetCrostiniDiskInfo(const base::ListValue* args);
+ void ResolveGetCrostiniDiskInfoCallback(
+ const std::string& callback_id,
+ std::unique_ptr<crostini::CrostiniDiskInfo> disk_info);
+ // Handles a request to resize a Crostini disk.
+ void HandleResizeCrostiniDisk(const base::ListValue* args);
+ void ResolveResizeCrostiniDiskCallback(const std::string& callback_id,
+ bool succeeded);
+ // Checks if a restart is required to update mic sharing settings.
+ void HandleCheckCrostiniMicSharingStatus(const base::ListValue* args);
Profile* profile_;
// weak_ptr_factory_ should always be last member.
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
index 74f1ab84039..fd6f8acdd11 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
@@ -14,12 +14,14 @@
#include "base/files/file_util.h"
#include "base/json/json_string_value_serializer.h"
#include "base/logging.h"
+#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/optional.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/task/post_task.h"
+#include "base/task/thread_pool.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
@@ -37,12 +39,11 @@
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/chrome_select_file_policy.h"
+#include "chrome/browser/ui/webui/settings/chromeos/server_printer_url_util.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/pref_names.h"
-#include "chrome/common/webui_url_constants.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/debug_daemon/debug_daemon_client.h"
-#include "chromeos/printing/ppd_cache.h"
#include "chromeos/printing/ppd_line_reader.h"
#include "chromeos/printing/printer_configuration.h"
#include "chromeos/printing/printer_translator.h"
@@ -58,6 +59,7 @@
#include "net/base/ip_endpoint.h"
#include "net/url_request/url_request_context_getter.h"
#include "printing/backend/print_backend.h"
+#include "printing/printer_status.h"
#include "url/gurl.h"
namespace chromeos {
@@ -113,8 +115,8 @@ void QueryAutoconf(const std::string& printer_uri,
// Behavior for querying a non-IPP uri is undefined and disallowed.
if (!IsIppUri(printer_uri) || !optional.has_value()) {
PRINTER_LOG(ERROR) << "Printer uri is invalid: " << printer_uri;
- std::move(callback).Run(PrinterQueryResult::UNKNOWN_FAILURE, "", "", "", {},
- false);
+ std::move(callback).Run(PrinterQueryResult::UNKNOWN_FAILURE,
+ printing::PrinterStatus(), "", "", "", {}, false);
return;
}
@@ -168,6 +170,7 @@ std::unique_ptr<chromeos::Printer> DictToPrinter(
std::string printer_make_and_model;
std::string printer_address;
std::string printer_protocol;
+ std::string print_server_uri;
if (!printer_dict.GetString("printerId", &printer_id) ||
!printer_dict.GetString("printerName", &printer_name) ||
@@ -176,7 +179,8 @@ std::unique_ptr<chromeos::Printer> DictToPrinter(
!printer_dict.GetString("printerModel", &printer_model) ||
!printer_dict.GetString("printerMakeAndModel", &printer_make_and_model) ||
!printer_dict.GetString("printerAddress", &printer_address) ||
- !printer_dict.GetString("printerProtocol", &printer_protocol)) {
+ !printer_dict.GetString("printerProtocol", &printer_protocol) ||
+ !printer_dict.GetString("printServerUri", &print_server_uri)) {
return nullptr;
}
@@ -195,6 +199,7 @@ std::unique_ptr<chromeos::Printer> DictToPrinter(
printer->set_model(printer_model);
printer->set_make_and_model(printer_make_and_model);
printer->set_uri(printer_uri);
+ printer->set_print_server_uri(print_server_uri);
return printer;
}
@@ -237,11 +242,6 @@ void SetPpdReference(const Printer::PpdReference& ppd_ref, base::Value* info) {
}
}
-bool IsFilledPpdReference(const Printer::PpdReference& ppd_ref) {
- return ppd_ref.autoconf || !ppd_ref.user_supplied_ppd_url.empty() ||
- !ppd_ref.effective_make_and_model.empty();
-}
-
Printer::PpdReference GetPpdReference(const base::Value* info) {
const char ppd_ref_pathname[] = "printerPpdReference";
auto* user_supplied_ppd_url =
@@ -267,40 +267,11 @@ Printer::PpdReference GetPpdReference(const base::Value* info) {
return ret;
}
-bool ConvertToGURL(const std::string& url, GURL* gurl) {
- *gurl = GURL(url);
- if (!gurl->is_valid()) {
- // URL is not valid.
- return false;
- }
- if (!gurl->SchemeIsHTTPOrHTTPS() && !gurl->SchemeIs("ipp") &&
- !gurl->SchemeIs("ipps")) {
- // URL has unsupported scheme; we support only: http, https, ipp, ipps.
- return false;
- }
- // Replaces ipp/ipps by http/https. IPP standard describes protocol built
- // on top of HTTP, so both types of addresses have the same meaning in the
- // context of IPP interface. Moreover, the URL must have http/https scheme
- // to pass IsStandard() test from GURL library (see "Validation of the URL
- // address" below).
- bool set_ipp_port = false;
- if (gurl->SchemeIs("ipp")) {
- set_ipp_port = (gurl->IntPort() == url::PORT_UNSPECIFIED);
- *gurl = GURL("http" + url.substr(url.find_first_of(':')));
- } else if (gurl->SchemeIs("ipps")) {
- *gurl = GURL("https" + url.substr(url.find_first_of(':')));
- }
- // The default port for ipp is 631. If the schema ipp is replaced by http
- // and the port is not explicitly defined in the url, we have to overwrite
- // the default http port with the default ipp port. For ipps we do nothing
- // because implementers use the same port for ipps and https.
- if (set_ipp_port) {
- GURL::Replacements replacement;
- replacement.SetPortStr("631");
- *gurl = gurl->ReplaceComponents(replacement);
- }
- // Validation of the URL address.
- return gurl->IsStandard();
+GURL GenerateHttpCupsServerUrl(const GURL& server_url) {
+ GURL::Replacements replacement;
+ replacement.SetSchemeStr("http");
+ replacement.SetPortStr("631");
+ return server_url.ReplaceComponents(replacement);
}
} // namespace
@@ -405,6 +376,10 @@ void CupsPrintersHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(
"getEulaUrl", base::BindRepeating(&CupsPrintersHandler::HandleGetEulaUrl,
base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "queryPrintServer",
+ base::BindRepeating(&CupsPrintersHandler::HandleQueryPrintServer,
+ base::Unretained(this)));
}
void CupsPrintersHandler::OnJavascriptAllowed() {
@@ -513,8 +488,8 @@ void CupsPrintersHandler::HandleGetPrinterInfo(const base::ListValue* args) {
if (printer_address.empty()) {
// Run the failure callback.
- OnAutoconfQueried(callback_id, PrinterQueryResult::UNKNOWN_FAILURE, "", "",
- "", {}, false);
+ OnAutoconfQueried(callback_id, PrinterQueryResult::UNKNOWN_FAILURE,
+ printing::PrinterStatus(), "", "", "", {}, false);
return;
}
@@ -541,6 +516,7 @@ void CupsPrintersHandler::OnAutoconfQueriedDiscovered(
const std::string& callback_id,
Printer printer,
PrinterQueryResult result,
+ const printing::PrinterStatus& printer_status,
const std::string& make,
const std::string& model,
const std::string& make_and_model,
@@ -587,6 +563,7 @@ void CupsPrintersHandler::OnAutoconfQueriedDiscovered(
void CupsPrintersHandler::OnAutoconfQueried(
const std::string& callback_id,
PrinterQueryResult result,
+ const printing::PrinterStatus& printer_status,
const std::string& make,
const std::string& model,
const std::string& make_and_model,
@@ -736,7 +713,7 @@ void CupsPrintersHandler::AddOrReconfigurePrinter(const base::ListValue* args,
// Check if the printer already has a valid ppd_reference.
Printer::PpdReference ppd_ref = GetPpdReference(printer_dict);
- if (IsFilledPpdReference(ppd_ref)) {
+ if (ppd_ref.IsFilled()) {
*printer->mutable_ppd_reference() = ppd_ref;
} else if (!printer_ppd_path.empty()) {
GURL tmp = net::FilePathToFileURL(base::FilePath(printer_ppd_path));
@@ -1003,9 +980,8 @@ void CupsPrintersHandler::FileSelected(const base::FilePath& path,
// VerifyPpdContents() in order to determine whether the file appears to be a
// PPD file. The task's priority is USER_BLOCKING because the this task
// updates the UI as a result of a direct user action.
- base::PostTaskAndReplyWithResult(
- FROM_HERE,
- {base::ThreadPool(), base::MayBlock(), base::TaskPriority::USER_BLOCKING},
+ base::ThreadPool::PostTaskAndReplyWithResult(
+ FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_BLOCKING},
base::BindOnce(&ReadFileToStringWithMaxSize, path, kPpdMaxLineLength),
base::BindOnce(&CupsPrintersHandler::VerifyPpdContents,
weak_factory_.GetWeakPtr(), path));
@@ -1239,7 +1215,7 @@ void CupsPrintersHandler::OnGetEulaUrl(const std::string& callback_id,
return;
}
- GURL eula_url(chrome::kChromeUIOSCreditsURL + license);
+ GURL eula_url = PrinterConfigurer::GeneratePrinterEulaUrl(license);
ResolveJavascriptCallback(
base::Value(callback_id),
eula_url.is_valid() ? base::Value(eula_url.spec()) : base::Value());
@@ -1283,27 +1259,45 @@ void CupsPrintersHandler::HandleQueryPrintServer(const base::ListValue* args) {
CHECK(args->GetString(0, &callback_id));
CHECK(args->GetString(1, &server_url));
- GURL server_gurl;
- if (!ConvertToGURL(server_url, &server_gurl)) {
+ base::Optional<GURL> converted_server_url =
+ GenerateServerPrinterUrlWithValidScheme(server_url);
+ if (!converted_server_url) {
RejectJavascriptCallback(
base::Value(callback_id),
base::Value(PrintServerQueryResult::kIncorrectUrl));
return;
}
+ // Use fallback only if HasValidServerPrinterScheme is false.
+ QueryPrintServer(callback_id, converted_server_url.value(),
+ !HasValidServerPrinterScheme(GURL(server_url)));
+}
+
+void CupsPrintersHandler::QueryPrintServer(const std::string& callback_id,
+ const GURL& server_url,
+ bool should_fallback) {
server_printers_fetcher_ = std::make_unique<ServerPrintersFetcher>(
- server_gurl, "(from user)",
+ server_url, "(from user)",
base::BindRepeating(&CupsPrintersHandler::OnQueryPrintServerCompleted,
- weak_factory_.GetWeakPtr(), callback_id));
+ weak_factory_.GetWeakPtr(), callback_id,
+ should_fallback));
}
void CupsPrintersHandler::OnQueryPrintServerCompleted(
const std::string& callback_id,
+ bool should_fallback,
const ServerPrintersFetcher* sender,
const GURL& server_url,
std::vector<PrinterDetector::DetectedPrinter>&& returned_printers) {
const PrintServerQueryResult result = sender->GetLastError();
if (result != PrintServerQueryResult::kNoErrors) {
+ if (should_fallback) {
+ // Apply the fallback query.
+ QueryPrintServer(callback_id, GenerateHttpCupsServerUrl(server_url),
+ /*should_fallback=*/false);
+ return;
+ }
+
RejectJavascriptCallback(base::Value(callback_id), base::Value(result));
return;
}
@@ -1313,9 +1307,10 @@ void CupsPrintersHandler::OnQueryPrintServerCompleted(
printers_manager_->GetPrinters(PrinterClass::kSaved);
std::set<GURL> known_printers;
for (const Printer& printer : saved_printers) {
- GURL gurl;
- if (ConvertToGURL(printer.uri(), &gurl))
- known_printers.insert(gurl);
+ base::Optional<GURL> gurl =
+ GenerateServerPrinterUrlWithValidScheme(printer.uri());
+ if (gurl)
+ known_printers.insert(gurl.value());
}
// Built final list of printers and a list of current names. If "current name"
@@ -1325,11 +1320,10 @@ void CupsPrintersHandler::OnQueryPrintServerCompleted(
printers.reserve(returned_printers.size());
for (PrinterDetector::DetectedPrinter& printer : returned_printers) {
printers.push_back(std::move(printer.printer));
- GURL printer_gurl;
- if (ConvertToGURL(printers.back().uri(), &printer_gurl)) {
- if (known_printers.count(printer_gurl))
- printers.pop_back();
- }
+ base::Optional<GURL> printer_gurl =
+ GenerateServerPrinterUrlWithValidScheme(printers.back().uri());
+ if (printer_gurl && known_printers.count(printer_gurl.value()))
+ printers.pop_back();
}
// Delete fetcher object.
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h
index 6e80a910a18..82de71cf6cc 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h
@@ -18,7 +18,7 @@
#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
#include "chromeos/printing/ppd_provider.h"
#include "chromeos/printing/printer_configuration.h"
-#include "printing/printer_query_result_chromeos.h"
+#include "printing/printer_query_result.h"
#include "ui/shell_dialogs/select_file_dialog.h"
namespace base {
@@ -30,6 +30,10 @@ namespace local_discovery {
class EndpointResolver;
} // namespace local_discovery
+namespace printing {
+struct PrinterStatus;
+} // namespace printing
+
class GURL;
class Profile;
@@ -77,14 +81,17 @@ class CupsPrintersHandler : public ::settings::SettingsPageUIHandler,
void HandleGetPrinterInfo(const base::ListValue* args);
// Handles the callback for HandleGetPrinterInfo. |callback_id| is the
- // identifier to resolve the correct Promise. |success| indicates if the query
- // was successful. |make| is the detected printer manufacturer. |model| is the
+ // identifier to resolve the correct Promise. |result| indicates if the query
+ // was successful. |printer_status| contains the current status of the
+ // printer. |make| is the detected printer manufacturer. |model| is the
// detected model. |make_and_model| is the unparsed printer-make-and-model
// string. |ipp_everywhere| indicates if configuration using the CUPS IPP
- // Everywhere driver should be attempted. If |success| is false, the values of
- // |make|, |model|, |make_and_model|, and |ipp_everywhere| are not specified.
+ // Everywhere driver should be attempted. If |result| is not SUCCESS, the
+ // values of |printer_status|, |make|, |model|, |make_and_model|, and
+ // |ipp_everywhere| are not specified.
void OnAutoconfQueried(const std::string& callback_id,
printing::PrinterQueryResult result,
+ const printing::PrinterStatus& printer_status,
const std::string& make,
const std::string& model,
const std::string& make_and_model,
@@ -96,6 +103,7 @@ class CupsPrintersHandler : public ::settings::SettingsPageUIHandler,
const std::string& callback_id,
Printer printer,
printing::PrinterQueryResult result,
+ const printing::PrinterStatus& printer_status,
const std::string& make,
const std::string& model,
const std::string& make_and_model,
@@ -214,8 +222,14 @@ class CupsPrintersHandler : public ::settings::SettingsPageUIHandler,
const net::IPEndPoint& endpoint);
void HandleQueryPrintServer(const base::ListValue* args);
+
+ void QueryPrintServer(const std::string& callback_id,
+ const GURL& server_url,
+ bool should_fallback);
+
void OnQueryPrintServerCompleted(
const std::string& callback_id,
+ bool should_fallback,
const ServerPrintersFetcher* sender,
const GURL& server_url,
std::vector<PrinterDetector::DetectedPrinter>&& returned_printers);
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/date_time_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/date_time_handler.cc
index 59656e6e848..39ceb89c02a 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/date_time_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/date_time_handler.cc
@@ -168,8 +168,8 @@ void DateTimeHandler::HandleShowParentAccessForTimeZone(
ash::LoginScreen::Get()->ShowParentAccessWidget(
user_manager::UserManager::Get()->GetActiveUser()->GetAccountId(),
- base::BindRepeating(&DateTimeHandler::OnParentAccessValidation,
- weak_ptr_factory_.GetWeakPtr()),
+ base::BindOnce(&DateTimeHandler::OnParentAccessValidation,
+ weak_ptr_factory_.GetWeakPtr()),
ash::ParentAccessRequestReason::kChangeTimezone, false /* extra_dimmer */,
base::Time());
}
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc
index ee16a539c7b..7195f59a799 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc
@@ -6,7 +6,6 @@
#include "ash/public/cpp/keyboard_shortcut_viewer.h"
#include "ash/public/cpp/tablet_mode.h"
-#include "ash/public/mojom/constants.mojom.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/values.h"
@@ -21,25 +20,33 @@ namespace {
struct KeyboardsStateResult {
bool has_internal_keyboard = false;
- bool has_external_non_apple_keyboard = false;
- bool has_apple_keyboard = false;
+ bool has_external_apple_keyboard = false;
+ bool has_external_chromeos_keyboard = false;
+ bool has_external_generic_keyboard = false;
};
KeyboardsStateResult GetKeyboardsState() {
KeyboardsStateResult result;
for (const ui::InputDevice& keyboard :
ui::DeviceDataManager::GetInstance()->GetKeyboardDevices()) {
- result.has_internal_keyboard |=
- (keyboard.type == ui::INPUT_DEVICE_INTERNAL);
-
- const ui::EventRewriterChromeOS::DeviceType type =
- ui::EventRewriterChromeOS::GetDeviceType(keyboard);
- if (type == ui::EventRewriterChromeOS::kDeviceAppleKeyboard) {
- result.has_apple_keyboard = true;
- } else if (type ==
- ui::EventRewriterChromeOS::kDeviceExternalNonAppleKeyboard ||
- type == ui::EventRewriterChromeOS::kDeviceExternalUnknown) {
- result.has_external_non_apple_keyboard = true;
+ switch (ui::EventRewriterChromeOS::GetDeviceType(keyboard)) {
+ case ui::EventRewriterChromeOS::kDeviceInternalKeyboard:
+ result.has_internal_keyboard = true;
+ break;
+ case ui::EventRewriterChromeOS::kDeviceExternalAppleKeyboard:
+ result.has_external_apple_keyboard = true;
+ break;
+ case ui::EventRewriterChromeOS::kDeviceExternalChromeOsKeyboard:
+ result.has_external_chromeos_keyboard = true;
+ break;
+ case ui::EventRewriterChromeOS::kDeviceExternalGenericKeyboard:
+ case ui::EventRewriterChromeOS::kDeviceExternalUnknown:
+ result.has_external_generic_keyboard = true;
+ break;
+ case ui::EventRewriterChromeOS::kDeviceHotrodRemote:
+ case ui::EventRewriterChromeOS::kDeviceVirtualCoreKeyboard:
+ case ui::EventRewriterChromeOS::kDeviceUnknown:
+ break;
}
}
@@ -131,8 +138,8 @@ void KeyboardHandler::UpdateShowKeys() {
// kHasChromeOSKeyboard will be unset on Chromebooks that have standalone Caps
// Lock keys.
const KeyboardsStateResult keyboards_state = GetKeyboardsState();
- const bool has_caps_lock = keyboards_state.has_apple_keyboard ||
- keyboards_state.has_external_non_apple_keyboard ||
+ const bool has_caps_lock = keyboards_state.has_external_apple_keyboard ||
+ keyboards_state.has_external_generic_keyboard ||
!base::CommandLine::ForCurrentProcess()->HasSwitch(
chromeos::switches::kHasChromeOSKeyboard);
@@ -140,9 +147,10 @@ void KeyboardHandler::UpdateShowKeys() {
keyboard_params.SetKey("showCapsLock", base::Value(has_caps_lock));
keyboard_params.SetKey(
"showExternalMetaKey",
- base::Value(keyboards_state.has_external_non_apple_keyboard));
- keyboard_params.SetKey("showAppleCommandKey",
- base::Value(keyboards_state.has_apple_keyboard));
+ base::Value(keyboards_state.has_external_generic_keyboard));
+ keyboard_params.SetKey(
+ "showAppleCommandKey",
+ base::Value(keyboards_state.has_external_apple_keyboard));
keyboard_params.SetKey("hasInternalKeyboard",
base::Value(keyboards_state.has_internal_keyboard));
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler_unittest.cc
index 8f4f6318a50..a558502222a 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler_unittest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler_unittest.cc
@@ -15,6 +15,7 @@
#include "base/observer_list.h"
#include "chromeos/constants/chromeos_switches.h"
#include "content/public/test/test_web_ui.h"
+#include "device/udev_linux/fake_udev_loader.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/devices/device_data_manager_test_api.h"
#include "ui/events/devices/input_device.h"
@@ -192,11 +193,46 @@ TEST_F(KeyboardHandlerTest, NonChromeOSKeyboard) {
}
TEST_F(KeyboardHandlerTest, ExternalKeyboard) {
+ auto fake_udev = std::make_unique<testing::FakeUdevLoader>();
+
+ // Standard internal keyboard on x86 device.
+ const ui::InputDevice internal_kbd(
+ 1, ui::INPUT_DEVICE_INTERNAL, "AT Translated Set 2 keyboard", "",
+ base::FilePath("/devices/platform/i8042/serio0/input/input1"), 1, 1,
+ 0xab41);
+ fake_udev->AddFakeDevice(internal_kbd.name, internal_kbd.sys_path.value(), {},
+ {});
+ // Generic external USB keyboard.
+ const ui::InputDevice external_generic_kbd(
+ 2, ui::INPUT_DEVICE_USB, "Logitech USB Keyboard", "",
+ base::FilePath("/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1:1.0/"
+ "0003:046D:C31C.0007/"
+ "input/input2"),
+ 0x046d, 0xc31c, 0x0111);
+ fake_udev->AddFakeDevice(external_generic_kbd.name,
+ external_generic_kbd.sys_path.value(), {}, {});
+ // Apple keyboard.
+ const ui::InputDevice external_apple_kbd(
+ 3, ui::INPUT_DEVICE_USB, "Apple Inc. Apple Keyboard", "",
+ base::FilePath("/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1:1.1/"
+ "0003:05AC:026C.000A/input/input3"),
+ 0x05ac, 0x026c, 0x0111);
+ fake_udev->AddFakeDevice(external_apple_kbd.name,
+ external_apple_kbd.sys_path.value(), {}, {});
+ // Chrome OS external USB keyboard.
+ const ui::InputDevice external_chromeos_kbd(
+ 4, ui::INPUT_DEVICE_USB, "LG USB Keyboard", "",
+ base::FilePath("/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1:1.0/"
+ "0003:04CA:0082.000B/input/input4"),
+ 0x04ca, 0x0082, 0x0111);
+ fake_udev->AddFakeDevice(external_chromeos_kbd.name,
+ external_chromeos_kbd.sys_path.value(), {},
+ {{"CROS_KEYBOARD_TOP_ROW_LAYOUT", "1"}});
+
// An internal keyboard shouldn't change the defaults.
base::CommandLine::ForCurrentProcess()->AppendSwitch(
chromeos::switches::kHasChromeOSKeyboard);
- device_data_manager_test_api_.SetKeyboardDevices(std::vector<ui::InputDevice>{
- {1, ui::INPUT_DEVICE_INTERNAL, "internal keyboard"}});
+ device_data_manager_test_api_.SetKeyboardDevices({internal_kbd});
handler_test_api_.Initialize();
EXPECT_TRUE(HasInternalSearchKey());
EXPECT_FALSE(HasCapsLock());
@@ -206,20 +242,28 @@ TEST_F(KeyboardHandlerTest, ExternalKeyboard) {
// Simulate an external keyboard being connected. We should assume there's a
// Caps Lock and Meta keys now.
- device_data_manager_test_api_.SetKeyboardDevices(std::vector<ui::InputDevice>{
- {1, ui::INPUT_DEVICE_INTERNAL, "internal keyboard"},
- {2, ui::INPUT_DEVICE_USB, "external keyboard"}});
+ device_data_manager_test_api_.SetKeyboardDevices(
+ std::vector<ui::InputDevice>{internal_kbd, external_generic_kbd});
EXPECT_TRUE(HasInternalSearchKey());
EXPECT_TRUE(HasCapsLock());
EXPECT_TRUE(HasExternalMetaKey());
EXPECT_FALSE(HasAppleCommandKey());
EXPECT_FALSE(HasAssistantKey());
+ // However when connecting external ChromeOS-branded keyboard, we should not
+ // see neither CapsLock not meta keys.
+ device_data_manager_test_api_.SetKeyboardDevices(
+ std::vector<ui::InputDevice>{internal_kbd, external_chromeos_kbd});
+ EXPECT_TRUE(HasInternalSearchKey());
+ EXPECT_FALSE(HasCapsLock());
+ EXPECT_FALSE(HasExternalMetaKey());
+ EXPECT_FALSE(HasAppleCommandKey());
+ EXPECT_FALSE(HasAssistantKey());
+
// Simulate an external Apple keyboard being connected. Now users can remap
// the command key.
- device_data_manager_test_api_.SetKeyboardDevices(std::vector<ui::InputDevice>{
- {1, ui::INPUT_DEVICE_INTERNAL, "internal keyboard"},
- {3, ui::INPUT_DEVICE_USB, "Apple Inc. Apple Keyboard"}});
+ device_data_manager_test_api_.SetKeyboardDevices(
+ std::vector<ui::InputDevice>{internal_kbd, external_apple_kbd});
EXPECT_TRUE(HasInternalSearchKey());
EXPECT_TRUE(HasCapsLock());
EXPECT_FALSE(HasExternalMetaKey());
@@ -228,9 +272,8 @@ TEST_F(KeyboardHandlerTest, ExternalKeyboard) {
// Simulate two external keyboards (Apple and non-Apple) are connected at the
// same time.
- device_data_manager_test_api_.SetKeyboardDevices(std::vector<ui::InputDevice>{
- {2, ui::INPUT_DEVICE_USB, "external keyboard"},
- {3, ui::INPUT_DEVICE_USB, "Apple Inc. Apple Keyboard"}});
+ device_data_manager_test_api_.SetKeyboardDevices(
+ std::vector<ui::InputDevice>{external_generic_kbd, external_apple_kbd});
EXPECT_FALSE(HasInternalSearchKey());
EXPECT_TRUE(HasCapsLock());
EXPECT_TRUE(HasExternalMetaKey());
@@ -242,7 +285,8 @@ TEST_F(KeyboardHandlerTest, ExternalKeyboard) {
// should show the capslock and external meta remapping.
// https://crbug.com/834594.
device_data_manager_test_api_.SetKeyboardDevices(std::vector<ui::InputDevice>{
- {4, ui::INPUT_DEVICE_USB, "Topre Corporation Realforce 87"}});
+ {5, ui::INPUT_DEVICE_USB, "Topre Corporation Realforce 87", "",
+ external_generic_kbd.sys_path, 0x046d, 0xc31c, 0x0111}});
EXPECT_FALSE(HasInternalSearchKey());
EXPECT_TRUE(HasCapsLock());
EXPECT_TRUE(HasExternalMetaKey());
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc
index 1906a330cd5..a5c66d6f18f 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc
@@ -79,11 +79,34 @@ int PowerSourceToDisplayId(
} // namespace
+PowerHandler::IdleBehaviorInfo::IdleBehaviorInfo() = default;
+PowerHandler::IdleBehaviorInfo::~IdleBehaviorInfo() = default;
+
+PowerHandler::IdleBehaviorInfo::IdleBehaviorInfo(
+ const std::set<PowerHandler::IdleBehavior>& possible_behaviors,
+ const PowerHandler::IdleBehavior& current_behavior,
+ const bool is_managed)
+ : possible_behaviors(possible_behaviors),
+ current_behavior(current_behavior),
+ is_managed(is_managed) {}
+
+PowerHandler::IdleBehaviorInfo::IdleBehaviorInfo(const IdleBehaviorInfo& o) =
+ default;
+
const char PowerHandler::kPowerManagementSettingsChangedName[] =
"power-management-settings-changed";
-const char PowerHandler::kIdleBehaviorKey[] = "idleBehavior";
-const char PowerHandler::kIdleControlledKey[] = "idleControlled";
+
+const char PowerHandler::kPossibleAcIdleBehaviorsKey[] =
+ "possibleAcIdleBehaviors";
+const char PowerHandler::kPossibleBatteryIdleBehaviorsKey[] =
+ "possibleBatteryIdleBehaviors";
+const char PowerHandler::kCurrentAcIdleBehaviorKey[] = "currentAcIdleBehavior";
+const char PowerHandler::kCurrentBatteryIdleBehaviorKey[] =
+ "currentBatteryIdleBehavior";
const char PowerHandler::kLidClosedBehaviorKey[] = "lidClosedBehavior";
+const char PowerHandler::kAcIdleManagedKey[] = "acIdleManaged";
+const char PowerHandler::kBatteryIdleManagedKey[] = "batteryIdleManaged";
+
const char PowerHandler::kLidClosedControlledKey[] = "lidClosedControlled";
const char PowerHandler::kHasLidKey[] = "hasLid";
@@ -96,9 +119,11 @@ void PowerHandler::TestAPI::RequestPowerManagementSettings() {
handler_->HandleRequestPowerManagementSettings(&args);
}
-void PowerHandler::TestAPI::SetIdleBehavior(IdleBehavior behavior) {
+void PowerHandler::TestAPI::SetIdleBehavior(IdleBehavior behavior,
+ bool when_on_ac) {
base::ListValue args;
args.AppendInteger(static_cast<int>(behavior));
+ args.AppendBoolean(when_on_ac);
handler_->HandleSetIdleBehavior(&args);
}
@@ -205,49 +230,48 @@ void PowerHandler::HandleSetIdleBehavior(const base::ListValue* args) {
AllowJavascript();
int value = 0;
+ bool when_on_ac = true;
CHECK(args->GetInteger(0, &value));
+ CHECK(args->GetBoolean(1, &when_on_ac));
+
+ const char* idle_pref = when_on_ac ? ash::prefs::kPowerAcIdleAction
+ : ash::prefs::kPowerBatteryIdleAction;
+ const char* screen_dim_delay_pref =
+ when_on_ac ? ash::prefs::kPowerAcScreenDimDelayMs
+ : ash::prefs::kPowerBatteryScreenDimDelayMs;
+ const char* screen_off_delay_pref =
+ when_on_ac ? ash::prefs::kPowerAcScreenOffDelayMs
+ : ash::prefs::kPowerBatteryScreenOffDelayMs;
+ const char* screen_lock_delay_pref =
+ when_on_ac ? ash::prefs::kPowerAcScreenLockDelayMs
+ : ash::prefs::kPowerBatteryScreenLockDelayMs;
+
switch (static_cast<IdleBehavior>(value)) {
case IdleBehavior::DISPLAY_OFF_SLEEP:
- // The default behavior is to turn the display off and sleep. Clear the
- // prefs so we use the default delays.
- prefs_->ClearPref(ash::prefs::kPowerAcIdleAction);
- prefs_->ClearPref(ash::prefs::kPowerAcScreenDimDelayMs);
- prefs_->ClearPref(ash::prefs::kPowerAcScreenOffDelayMs);
- prefs_->ClearPref(ash::prefs::kPowerAcScreenLockDelayMs);
- prefs_->ClearPref(ash::prefs::kPowerBatteryIdleAction);
- prefs_->ClearPref(ash::prefs::kPowerBatteryScreenDimDelayMs);
- prefs_->ClearPref(ash::prefs::kPowerBatteryScreenOffDelayMs);
- prefs_->ClearPref(ash::prefs::kPowerBatteryScreenLockDelayMs);
+ // The default behavior is to turn the display off and sleep.
+ // Clear the prefs so we use the default delays.
+ prefs_->ClearPref(idle_pref);
+ prefs_->ClearPref(screen_dim_delay_pref);
+ prefs_->ClearPref(screen_off_delay_pref);
+ prefs_->ClearPref(screen_lock_delay_pref);
break;
case IdleBehavior::DISPLAY_OFF:
- // Override idle actions to keep the system awake, but use the default
- // screen delays.
- prefs_->SetInteger(ash::prefs::kPowerAcIdleAction,
- PowerPolicyController::ACTION_DO_NOTHING);
- prefs_->ClearPref(ash::prefs::kPowerAcScreenDimDelayMs);
- prefs_->ClearPref(ash::prefs::kPowerAcScreenOffDelayMs);
- prefs_->ClearPref(ash::prefs::kPowerAcScreenLockDelayMs);
- prefs_->SetInteger(ash::prefs::kPowerBatteryIdleAction,
- PowerPolicyController::ACTION_DO_NOTHING);
- prefs_->ClearPref(ash::prefs::kPowerBatteryScreenDimDelayMs);
- prefs_->ClearPref(ash::prefs::kPowerBatteryScreenOffDelayMs);
- prefs_->ClearPref(ash::prefs::kPowerBatteryScreenLockDelayMs);
+ // Override idle actions to keep the system awake, but use the
+ // default screen delays.
+ prefs_->SetInteger(idle_pref, PowerPolicyController::ACTION_DO_NOTHING);
+ prefs_->ClearPref(screen_dim_delay_pref);
+ prefs_->ClearPref(screen_off_delay_pref);
+ prefs_->ClearPref(screen_lock_delay_pref);
break;
case IdleBehavior::DISPLAY_ON:
- // Override idle actions and set screen delays to 0 in order to disable
- // them (i.e. keep the screen on).
- prefs_->SetInteger(ash::prefs::kPowerAcIdleAction,
- PowerPolicyController::ACTION_DO_NOTHING);
- prefs_->SetInteger(ash::prefs::kPowerAcScreenDimDelayMs, 0);
- prefs_->SetInteger(ash::prefs::kPowerAcScreenOffDelayMs, 0);
- prefs_->SetInteger(ash::prefs::kPowerAcScreenLockDelayMs, 0);
- prefs_->SetInteger(ash::prefs::kPowerBatteryIdleAction,
- PowerPolicyController::ACTION_DO_NOTHING);
- prefs_->SetInteger(ash::prefs::kPowerBatteryScreenDimDelayMs, 0);
- prefs_->SetInteger(ash::prefs::kPowerBatteryScreenOffDelayMs, 0);
- prefs_->SetInteger(ash::prefs::kPowerBatteryScreenLockDelayMs, 0);
+ // Override idle actions and set screen delays to 0 in order to
+ // disable them (i.e. keep the screen on).
+ prefs_->SetInteger(idle_pref, PowerPolicyController::ACTION_DO_NOTHING);
+ prefs_->SetInteger(screen_dim_delay_pref, 0);
+ prefs_->SetInteger(screen_off_delay_pref, 0);
+ prefs_->SetInteger(screen_lock_delay_pref, 0);
break;
- default:
+ case IdleBehavior::OTHER:
NOTREACHED() << "Invalid idle behavior " << value;
}
}
@@ -336,32 +360,10 @@ void PowerHandler::SendPowerSources() {
}
void PowerHandler::SendPowerManagementSettings(bool force) {
- // Infer the idle behavior based on the idle action (determining whether we'll
- // sleep eventually or not) and the AC screen-off delay. Policy can request
- // more-nuanced combinations of AC/battery actions and delays, but we wouldn't
- // be able to display something meaningful in the UI in those cases anyway.
- const PowerPolicyController::Action idle_action =
- static_cast<PowerPolicyController::Action>(
- prefs_->GetInteger(ash::prefs::kPowerAcIdleAction));
- IdleBehavior idle_behavior = IdleBehavior::OTHER;
- if (idle_action == PowerPolicyController::ACTION_SUSPEND) {
- idle_behavior = IdleBehavior::DISPLAY_OFF_SLEEP;
- } else if (idle_action == PowerPolicyController::ACTION_DO_NOTHING) {
- idle_behavior =
- (prefs_->GetInteger(ash::prefs::kPowerAcScreenOffDelayMs) > 0
- ? IdleBehavior::DISPLAY_OFF
- : IdleBehavior::DISPLAY_ON);
- }
-
- const bool idle_controlled =
- prefs_->IsManagedPreference(ash::prefs::kPowerAcIdleAction) ||
- prefs_->IsManagedPreference(ash::prefs::kPowerAcScreenDimDelayMs) ||
- prefs_->IsManagedPreference(ash::prefs::kPowerAcScreenOffDelayMs) ||
- prefs_->IsManagedPreference(ash::prefs::kPowerAcScreenLockDelayMs) ||
- prefs_->IsManagedPreference(ash::prefs::kPowerBatteryIdleAction) ||
- prefs_->IsManagedPreference(ash::prefs::kPowerBatteryScreenDimDelayMs) ||
- prefs_->IsManagedPreference(ash::prefs::kPowerBatteryScreenOffDelayMs) ||
- prefs_->IsManagedPreference(ash::prefs::kPowerBatteryScreenLockDelayMs);
+ const PowerHandler::IdleBehaviorInfo ac_idle_info =
+ GetAllowedIdleBehaviors(PowerSource::kAc);
+ const PowerHandler::IdleBehaviorInfo battery_idle_info =
+ GetAllowedIdleBehaviors(PowerSource::kBattery);
const PowerPolicyController::Action lid_closed_behavior =
static_cast<PowerPolicyController::Action>(
@@ -371,23 +373,37 @@ void PowerHandler::SendPowerManagementSettings(bool force) {
const bool has_lid = lid_state_ != PowerManagerClient::LidState::NOT_PRESENT;
// Don't notify the UI if nothing changed.
- if (!force && idle_behavior == last_idle_behavior_ &&
- idle_controlled == last_idle_controlled_ &&
+ if (!force && ac_idle_info == last_ac_idle_info_ &&
+ battery_idle_info == last_battery_idle_info_ &&
lid_closed_behavior == last_lid_closed_behavior_ &&
lid_closed_controlled == last_lid_closed_controlled_ &&
- has_lid == last_has_lid_)
+ has_lid == last_has_lid_) {
return;
+ }
base::DictionaryValue dict;
- dict.SetInteger(kIdleBehaviorKey, static_cast<int>(idle_behavior));
- dict.SetBoolean(kIdleControlledKey, idle_controlled);
+ base::Value* list = dict.SetKey(kPossibleAcIdleBehaviorsKey,
+ base::Value(base::Value::Type::LIST));
+ for (auto idle_behavior : ac_idle_info.possible_behaviors)
+ list->Append(static_cast<int>(idle_behavior));
+
+ list = dict.SetKey(kPossibleBatteryIdleBehaviorsKey,
+ base::Value(base::Value::Type::LIST));
+ for (auto idle_behavior : battery_idle_info.possible_behaviors)
+ list->Append(static_cast<int>(idle_behavior));
+ dict.SetInteger(kCurrentAcIdleBehaviorKey,
+ static_cast<int>(ac_idle_info.current_behavior));
+ dict.SetInteger(kCurrentBatteryIdleBehaviorKey,
+ static_cast<int>(battery_idle_info.current_behavior));
dict.SetInteger(kLidClosedBehaviorKey, lid_closed_behavior);
+ dict.SetBoolean(kAcIdleManagedKey, ac_idle_info.is_managed);
+ dict.SetBoolean(kBatteryIdleManagedKey, battery_idle_info.is_managed);
dict.SetBoolean(kLidClosedControlledKey, lid_closed_controlled);
dict.SetBoolean(kHasLidKey, has_lid);
FireWebUIListener(kPowerManagementSettingsChangedName, dict);
- last_idle_behavior_ = idle_behavior;
- last_idle_controlled_ = idle_controlled;
+ last_ac_idle_info_ = ac_idle_info;
+ last_battery_idle_info_ = battery_idle_info;
last_lid_closed_behavior_ = lid_closed_behavior;
last_lid_closed_controlled_ = lid_closed_controlled;
last_has_lid_ = has_lid;
@@ -401,5 +417,159 @@ void PowerHandler::OnGotSwitchStates(
SendPowerManagementSettings(false /* force */);
}
+PowerHandler::IdleBehaviorInfo PowerHandler::GetAllowedIdleBehaviors(
+ PowerSource power_source) {
+ const char* idle_pref = power_source == PowerSource::kAc
+ ? ash::prefs::kPowerAcIdleAction
+ : ash::prefs::kPowerBatteryIdleAction;
+ const char* screen_off_delay_pref =
+ power_source == PowerSource::kAc
+ ? ash::prefs::kPowerAcScreenOffDelayMs
+ : ash::prefs::kPowerBatteryScreenOffDelayMs;
+
+ std::set<IdleBehavior> possible_behaviors;
+ IdleBehavior current_idle_behavior;
+
+ // If idle action is managed and set to suspend, only possible idle
+ // behaviour is sleep with display off.
+ if (prefs_->IsManagedPreference(idle_pref) &&
+ prefs_->GetInteger(idle_pref) == PowerPolicyController::ACTION_SUSPEND) {
+ current_idle_behavior = IdleBehavior::DISPLAY_OFF_SLEEP;
+ possible_behaviors.insert(IdleBehavior::DISPLAY_OFF_SLEEP);
+ return IdleBehaviorInfo(possible_behaviors, current_idle_behavior,
+ IsIdleManaged(power_source));
+ }
+
+ // If idle action is managed and set to SHUT_DOWN/STOP_SESSION, only
+ // possible idle behaviour is other.
+ if (prefs_->IsManagedPreference(idle_pref) &&
+ (prefs_->GetInteger(idle_pref) ==
+ PowerPolicyController::ACTION_STOP_SESSION ||
+ prefs_->GetInteger(idle_pref) ==
+ PowerPolicyController::ACTION_SHUT_DOWN)) {
+ current_idle_behavior = IdleBehavior::OTHER;
+ possible_behaviors.insert(IdleBehavior::OTHER);
+ return IdleBehaviorInfo(possible_behaviors, current_idle_behavior,
+ IsIdleManaged(power_source));
+ }
+
+ // Note that after this point |idle_pref| should either be:
+ // 1. Not managed.
+ // 2. Or managed and set to
+ // PowerPolicyController::ACTION_DO_NOTHING.
+ DCHECK(!prefs_->IsManagedPreference(idle_pref) ||
+ (prefs_->GetInteger(idle_pref) ==
+ PowerPolicyController::ACTION_DO_NOTHING));
+
+ // If screen off delay is managed and set to a value greater than 0
+ // and
+ // 1. If idle action is managed and set to DO_NOTHING, only
+ // possible idle behavior is DISPLAY_OFF.
+ // 2. If idle action is not managed then possible idle options
+ // are DiSPLAY_OFF and DISPLAY_OFF_SLEEP
+ if (prefs_->IsManagedPreference(screen_off_delay_pref) &&
+ prefs_->GetInteger(screen_off_delay_pref) > 0) {
+ if (prefs_->IsManagedPreference(idle_pref) &&
+ prefs_->GetInteger(idle_pref) ==
+ PowerPolicyController::ACTION_DO_NOTHING) {
+ current_idle_behavior = IdleBehavior::DISPLAY_OFF;
+ possible_behaviors.insert(IdleBehavior::DISPLAY_OFF);
+ return IdleBehaviorInfo(possible_behaviors, current_idle_behavior,
+ IsIdleManaged(power_source));
+ }
+
+ possible_behaviors.insert(IdleBehavior::DISPLAY_OFF);
+ possible_behaviors.insert(IdleBehavior::DISPLAY_OFF_SLEEP);
+ // Set the current default option based on the current idle action.
+ const PowerPolicyController::Action idle_action =
+ static_cast<PowerPolicyController::Action>(
+ prefs_->GetInteger(idle_pref));
+
+ if (idle_action == PowerPolicyController::ACTION_SUSPEND)
+ current_idle_behavior = IdleBehavior::DISPLAY_OFF_SLEEP;
+ else
+ current_idle_behavior = IdleBehavior::DISPLAY_OFF;
+ return IdleBehaviorInfo(possible_behaviors, current_idle_behavior,
+ IsIdleManaged(power_source));
+ }
+
+ // If idle action is managed and set to DO_NOTHING, and
+ // 1. If screen off delay is also managed (and set to 0), only
+ // possible idle
+ // action is DISPLAY_ON.
+ // 2. If AC screen off delay is not managed, possible idle actions
+ // are DISPLAY_ON && DISPLAY_OFF.
+ if (prefs_->IsManagedPreference(idle_pref) &&
+ prefs_->GetInteger(idle_pref) ==
+ PowerPolicyController::ACTION_DO_NOTHING) {
+ if (prefs_->IsManagedPreference(screen_off_delay_pref)) {
+ // Note that we reach here only when screen off delays are
+ // set by enterprise policy to 0 to prevent display from turning
+ // off.
+ DCHECK(prefs_->GetInteger(screen_off_delay_pref) == 0);
+ current_idle_behavior = IdleBehavior::DISPLAY_ON;
+ possible_behaviors.insert(IdleBehavior::DISPLAY_ON);
+ return IdleBehaviorInfo(possible_behaviors, current_idle_behavior,
+ IsIdleManaged(power_source));
+ }
+ possible_behaviors.insert(IdleBehavior::DISPLAY_ON);
+ possible_behaviors.insert(IdleBehavior::DISPLAY_OFF);
+ // Set the current default option based on the current screen off
+ // delay.
+ current_idle_behavior = prefs_->GetInteger(screen_off_delay_pref) > 0
+ ? IdleBehavior::DISPLAY_OFF
+ : IdleBehavior::DISPLAY_ON;
+ return IdleBehaviorInfo(possible_behaviors, current_idle_behavior,
+ IsIdleManaged(power_source));
+ }
+
+ // Looks like we did not find enterprise policy restricitng the idle
+ // options. So add all three idle options to what user can select
+ // from.
+ possible_behaviors.insert(IdleBehavior::DISPLAY_ON);
+ possible_behaviors.insert(IdleBehavior::DISPLAY_OFF);
+ possible_behaviors.insert(IdleBehavior::DISPLAY_OFF_SLEEP);
+
+ // Infer the idle behavior based on the current idle action
+ // (determining whether we'll sleep eventually or not) and the AC
+ // screen-off delay.
+ const PowerPolicyController::Action idle_action =
+ static_cast<PowerPolicyController::Action>(prefs_->GetInteger(idle_pref));
+
+ if (idle_action == PowerPolicyController::ACTION_SUSPEND) {
+ current_idle_behavior = IdleBehavior::DISPLAY_OFF_SLEEP;
+ } else if (idle_action == PowerPolicyController::ACTION_DO_NOTHING) {
+ current_idle_behavior = (prefs_->GetInteger(screen_off_delay_pref) > 0
+ ? IdleBehavior::DISPLAY_OFF
+ : IdleBehavior::DISPLAY_ON);
+ } else {
+ current_idle_behavior = IdleBehavior::OTHER;
+ possible_behaviors.insert(IdleBehavior::OTHER);
+ }
+
+ return IdleBehaviorInfo(possible_behaviors, current_idle_behavior,
+ IsIdleManaged(power_source));
+}
+
+bool PowerHandler::IsIdleManaged(PowerSource power_source) {
+ switch (power_source) {
+ case PowerSource::kAc:
+ return prefs_->IsManagedPreference(ash::prefs::kPowerAcIdleAction) ||
+ prefs_->IsManagedPreference(
+ ash::prefs::kPowerAcScreenDimDelayMs) ||
+ prefs_->IsManagedPreference(
+ ash::prefs::kPowerAcScreenOffDelayMs) ||
+ prefs_->IsManagedPreference(ash::prefs::kPowerAcScreenLockDelayMs);
+ case PowerSource::kBattery:
+ return prefs_->IsManagedPreference(ash::prefs::kPowerBatteryIdleAction) ||
+ prefs_->IsManagedPreference(
+ ash::prefs::kPowerBatteryScreenDimDelayMs) ||
+ prefs_->IsManagedPreference(
+ ash::prefs::kPowerBatteryScreenOffDelayMs) ||
+ prefs_->IsManagedPreference(
+ ash::prefs::kPowerBatteryScreenLockDelayMs);
+ }
+}
+
} // namespace settings
} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.h
index d55a3944bd5..1d125b0295a 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.h
@@ -6,6 +6,7 @@
#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_POWER_HANDLER_H_
#include <memory>
+#include <set>
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
@@ -22,7 +23,7 @@ class PrefService;
namespace base {
class ListValue;
class TimeTicks;
-}
+} // namespace base
namespace chromeos {
namespace settings {
@@ -43,8 +44,12 @@ class PowerHandler : public ::settings::SettingsPageUIHandler,
// WebUI message name and dictionary keys. Shared with tests.
static const char kPowerManagementSettingsChangedName[];
- static const char kIdleBehaviorKey[];
- static const char kIdleControlledKey[];
+ static const char kPossibleAcIdleBehaviorsKey[];
+ static const char kPossibleBatteryIdleBehaviorsKey[];
+ static const char kAcIdleManagedKey[];
+ static const char kBatteryIdleManagedKey[];
+ static const char kCurrentAcIdleBehaviorKey[];
+ static const char kCurrentBatteryIdleBehaviorKey[];
static const char kLidClosedBehaviorKey[];
static const char kLidClosedControlledKey[];
static const char kHasLidKey[];
@@ -56,7 +61,9 @@ class PowerHandler : public ::settings::SettingsPageUIHandler,
~TestAPI();
void RequestPowerManagementSettings();
- void SetIdleBehavior(IdleBehavior behavior);
+ // Sets AC idle behavior to |behavior| if |when_on_ac| is true. Otherwise
+ // sets battery idle behavior to |behavior|.
+ void SetIdleBehavior(IdleBehavior behavior, bool when_on_ac);
void SetLidClosedBehavior(PowerPolicyController::Action behavior);
private:
@@ -80,6 +87,33 @@ class PowerHandler : public ::settings::SettingsPageUIHandler,
const base::TimeTicks& timestamp) override;
private:
+ enum class PowerSource { kAc, kBattery };
+
+ // Struct holding possible idle behaviors and the current behavior while
+ // charging/when on battery.
+ struct IdleBehaviorInfo {
+ IdleBehaviorInfo();
+ IdleBehaviorInfo(const std::set<IdleBehavior>& possible_behaviors,
+ const IdleBehavior& current_behavior,
+ const bool is_managed);
+
+ IdleBehaviorInfo(const IdleBehaviorInfo& o);
+ ~IdleBehaviorInfo();
+
+ bool operator==(const IdleBehaviorInfo& o) const {
+ return (possible_behaviors == o.possible_behaviors &&
+ current_behavior == o.current_behavior &&
+ is_managed == o.is_managed);
+ }
+
+ // All possible idle behaviors.
+ std::set<IdleBehavior> possible_behaviors;
+ // Current idle behavior.
+ IdleBehavior current_behavior = IdleBehavior::DISPLAY_OFF_SLEEP;
+ // Whether enterpise policy manages idle behavior.
+ bool is_managed = false;
+ };
+
// Handler to request updating the power status.
void HandleUpdatePowerStatus(const base::ListValue* args);
@@ -109,7 +143,16 @@ class PowerHandler : public ::settings::SettingsPageUIHandler,
void OnGotSwitchStates(
base::Optional<PowerManagerClient::SwitchStates> result);
- PrefService* prefs_; // Not owned.
+ // Returns all possible idle behaviors (that a user can choose from) and
+ // current idle behavior based on enterprise policy and other factors when on
+ // |power_source|.
+ IdleBehaviorInfo GetAllowedIdleBehaviors(PowerSource power_source);
+
+ // Returns true if the enterprise policy enforces any settings that can impact
+ // the idle behavior of the device when on |power_source|.
+ bool IsIdleManaged(PowerSource power_source);
+
+ PrefService* const prefs_;
// Used to watch power management prefs for changes so the UI can be notified.
std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;
@@ -123,10 +166,10 @@ class PowerHandler : public ::settings::SettingsPageUIHandler,
// Last values sent by SendPowerManagementSettings(), cached here so
// SendPowerManagementSettings() can avoid spamming the UI after this class
// changes multiple prefs at once.
- IdleBehavior last_idle_behavior_ = IdleBehavior::DISPLAY_OFF_SLEEP;
+ IdleBehaviorInfo last_ac_idle_info_;
+ IdleBehaviorInfo last_battery_idle_info_;
PowerPolicyController::Action last_lid_closed_behavior_ =
PowerPolicyController::ACTION_SUSPEND;
- bool last_idle_controlled_ = false;
bool last_lid_closed_controlled_ = false;
bool last_has_lid_ = true;
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler_browsertest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler_browsertest.cc
index c27e55cb6d4..c928ccd2d75 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler_browsertest.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler_browsertest.cc
@@ -2,9 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/ui/webui/settings/chromeos/device_power_handler.h"
-
#include <memory>
+#include <set>
#include <utility>
#include "ash/public/cpp/ash_pref_names.h"
@@ -13,6 +12,7 @@
#include "base/run_loop.h"
#include "base/values.h"
#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/ui/webui/settings/chromeos/device_power_handler.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chromeos/dbus/power/fake_power_manager_client.h"
#include "chromeos/dbus/power/power_policy_controller.h"
@@ -24,8 +24,8 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-using testing::Return;
using testing::_;
+using testing::Return;
namespace chromeos {
namespace settings {
@@ -48,6 +48,34 @@ class TestPowerHandler : public PowerHandler {
class PowerHandlerTest : public InProcessBrowserTest {
protected:
+ struct DevicePowerSettings {
+ // Initialize with initial settings.
+ DevicePowerSettings() {
+ possible_ac_behaviors.insert(
+ PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP);
+ possible_ac_behaviors.insert(PowerHandler::IdleBehavior::DISPLAY_OFF);
+ possible_ac_behaviors.insert(PowerHandler::IdleBehavior::DISPLAY_ON);
+ possible_battery_behaviors.insert(
+ PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP);
+ possible_battery_behaviors.insert(
+ PowerHandler::IdleBehavior::DISPLAY_OFF);
+ possible_battery_behaviors.insert(PowerHandler::IdleBehavior::DISPLAY_ON);
+ }
+
+ std::set<PowerHandler::IdleBehavior> possible_ac_behaviors;
+ std::set<PowerHandler::IdleBehavior> possible_battery_behaviors;
+ PowerHandler::IdleBehavior current_ac_behavior =
+ PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP;
+ PowerHandler::IdleBehavior current_battery_behavior =
+ PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP;
+ bool ac_idle_managed = false;
+ bool battery_idle_managed = false;
+ PowerPolicyController::Action lid_closed_behavior =
+ PowerPolicyController::ACTION_SUSPEND;
+ bool lid_closed_controlled = false;
+ bool has_lid = true;
+ };
+
PowerHandlerTest() = default;
~PowerHandlerTest() override = default;
@@ -99,23 +127,32 @@ class PowerHandlerTest : public InProcessBrowserTest {
return std::string();
}
- // Returns a string for the given settings that can be compared against the
- // output of GetLastSettingsChangedMessage().
- std::string CreateSettingsChangedString(
- PowerHandler::IdleBehavior idle_behavior,
- bool idle_controlled,
- PowerPolicyController::Action lid_closed_behavior,
- bool lid_closed_controlled,
- bool has_lid) {
+ // Returns a string for the given |settings|. Used to verify expected
+ // settings are sent to the UI.
+ std::string ToString(const DevicePowerSettings& settings) {
base::DictionaryValue dict;
- dict.SetInteger(PowerHandler::kIdleBehaviorKey,
- static_cast<int>(idle_behavior));
- dict.SetBoolean(PowerHandler::kIdleControlledKey, idle_controlled);
- dict.SetInteger(PowerHandler::kLidClosedBehaviorKey, lid_closed_behavior);
+ base::Value* list = dict.SetKey(PowerHandler::kPossibleAcIdleBehaviorsKey,
+ base::Value(base::Value::Type::LIST));
+ for (auto idle_behavior : settings.possible_ac_behaviors)
+ list->Append(static_cast<int>(idle_behavior));
+
+ list = dict.SetKey(PowerHandler::kPossibleBatteryIdleBehaviorsKey,
+ base::Value(base::Value::Type::LIST));
+ for (auto idle_behavior : settings.possible_battery_behaviors)
+ list->Append(static_cast<int>(idle_behavior));
+
+ dict.SetInteger(PowerHandler::kCurrentAcIdleBehaviorKey,
+ static_cast<int>(settings.current_ac_behavior));
+ dict.SetInteger(PowerHandler::kCurrentBatteryIdleBehaviorKey,
+ static_cast<int>(settings.current_battery_behavior));
+ dict.SetBoolean(PowerHandler::kAcIdleManagedKey, settings.ac_idle_managed);
+ dict.SetBoolean(PowerHandler::kBatteryIdleManagedKey,
+ settings.battery_idle_managed);
+ dict.SetInteger(PowerHandler::kLidClosedBehaviorKey,
+ settings.lid_closed_behavior);
dict.SetBoolean(PowerHandler::kLidClosedControlledKey,
- lid_closed_controlled);
- dict.SetBoolean(PowerHandler::kHasLidKey, has_lid);
-
+ settings.lid_closed_controlled);
+ dict.SetBoolean(PowerHandler::kHasLidKey, settings.has_lid);
std::string out;
EXPECT_TRUE(base::JSONWriter::Write(dict, &out));
return out;
@@ -129,6 +166,12 @@ class PowerHandlerTest : public InProcessBrowserTest {
return GetPrefs()->GetInteger(name);
}
+ // Trigger power pref managed change.
+ void UpdateChromePolicy(policy::PolicyMap* policy_map) {
+ provider_.UpdateChromePolicy(*policy_map);
+ base::RunLoop().RunUntilIdle();
+ }
+
// Sets a policy update which will cause power pref managed change.
void SetPolicyForPolicyKey(policy::PolicyMap* policy_map,
const std::string& policy_key,
@@ -136,8 +179,7 @@ class PowerHandlerTest : public InProcessBrowserTest {
policy_map->Set(policy_key, policy::POLICY_LEVEL_MANDATORY,
policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
std::move(value), nullptr);
- provider_.UpdateChromePolicy(*policy_map);
- base::RunLoop().RunUntilIdle();
+ UpdateChromePolicy(policy_map);
}
std::unique_ptr<TestPowerHandler> handler_;
@@ -154,155 +196,215 @@ class PowerHandlerTest : public InProcessBrowserTest {
// Verifies that settings are sent to WebUI when requested.
IN_PROC_BROWSER_TEST_F(PowerHandlerTest, SendInitialSettings) {
test_api_->RequestPowerManagementSettings();
- EXPECT_EQ(
- CreateSettingsChangedString(
- PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP,
- false /* idle_controlled */, PowerPolicyController::ACTION_SUSPEND,
- false /* lid_closed_controlled */, true /* has_lid */),
- GetLastSettingsChangedMessage());
+ // Initialized to initial settings.
+ DevicePowerSettings settings;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
}
// Verifies that WebUI receives updated settings when the lid state changes.
IN_PROC_BROWSER_TEST_F(PowerHandlerTest, SendSettingsForLidStateChanges) {
chromeos::FakePowerManagerClient::Get()->SetLidState(
PowerManagerClient::LidState::NOT_PRESENT, base::TimeTicks());
- EXPECT_EQ(
- CreateSettingsChangedString(
- PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP,
- false /* idle_controlled */, PowerPolicyController::ACTION_SUSPEND,
- false /* lid_closed_controlled */, false /* has_lid */),
- GetLastSettingsChangedMessage());
+
+ DevicePowerSettings settings;
+ settings.has_lid = false;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
chromeos::FakePowerManagerClient::Get()->SetLidState(
PowerManagerClient::LidState::OPEN, base::TimeTicks());
- EXPECT_EQ(
- CreateSettingsChangedString(
- PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP,
- false /* idle_controlled */, PowerPolicyController::ACTION_SUSPEND,
- false /* lid_closed_controlled */, true /* has_lid */),
- GetLastSettingsChangedMessage());
+ settings.has_lid = true;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
}
-// Verifies that when various prefs are controlled, the corresponding settings
-// are reported as controlled to WebUI.
+// Verifies that when various prefs are controlled, the corresponding
+// settings are reported as controlled/managed to WebUI.
IN_PROC_BROWSER_TEST_F(PowerHandlerTest, SendSettingsForControlledPrefs) {
policy::PolicyMap policy_map;
- // Making an arbitrary delay pref managed should result in the idle setting
- // being reported as controlled.
+ // Making an arbitrary AC delay pref managed should result in the AC idle
+ // setting being reported as managed.
SetPolicyForPolicyKey(&policy_map, policy::key::kScreenDimDelayAC,
std::make_unique<base::Value>(10000));
- EXPECT_EQ(
- CreateSettingsChangedString(
- PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP,
- true /* idle_controlled */, PowerPolicyController::ACTION_SUSPEND,
- false /* lid_closed_controlled */, true /* has_lid */),
- GetLastSettingsChangedMessage());
+ DevicePowerSettings settings;
+ settings.ac_idle_managed = true;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
+
+ // Ditto for battery delay pref managed.
+ SetPolicyForPolicyKey(&policy_map, policy::key::kScreenDimDelayBattery,
+ std::make_unique<base::Value>(10000));
+ settings.battery_idle_managed = true;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
// Ditto for making the lid action pref managed.
SetPolicyForPolicyKey(
&policy_map, policy::key::kLidCloseAction,
std::make_unique<base::Value>(PowerPolicyController::ACTION_SUSPEND));
- EXPECT_EQ(
- CreateSettingsChangedString(
- PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP,
- true /* idle_controlled */, PowerPolicyController::ACTION_SUSPEND,
- true /* lid_closed_controlled */, true /* has_lid */),
- GetLastSettingsChangedMessage());
+ settings.lid_closed_controlled = true;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
}
-// Verifies that idle-related prefs are distilled into the proper WebUI
-// settings.
+// Verifies that idle-related prefs (when not managed by enterpise policy)
+// are distilled into the proper WebUI settings.
IN_PROC_BROWSER_TEST_F(PowerHandlerTest, SendIdleSettingForPrefChanges) {
- // Set a do-nothing idle action and a nonzero screen-off delay.
+ // Initial power settings.
+ DevicePowerSettings settings;
+ // Set a AC do-nothing idle action and a AC nonzero screen-off delay. User
+ // should see all three options (DISPLAY_ON, DISPLAY_OFF and
+ // DISPLAY_OFF_SLEEP) and the selected setting when on AC should be set to
+ // DISPLAY_OFF.
GetPrefs()->Set(ash::prefs::kPowerAcIdleAction,
base::Value(PowerPolicyController::ACTION_DO_NOTHING));
GetPrefs()->Set(ash::prefs::kPowerAcScreenOffDelayMs, base::Value(10000));
- EXPECT_EQ(CreateSettingsChangedString(PowerHandler::IdleBehavior::DISPLAY_OFF,
- false /* idle_controlled */,
- PowerPolicyController::ACTION_SUSPEND,
- false /* lid_closed_controlled */,
- true /* has_lid */),
- GetLastSettingsChangedMessage());
-
- // Now set the delay to zero and check that the setting goes to "display on".
- GetPrefs()->Set(ash::prefs::kPowerAcScreenOffDelayMs, base::Value(0));
- EXPECT_EQ(CreateSettingsChangedString(PowerHandler::IdleBehavior::DISPLAY_ON,
- false /* idle_controlled */,
- PowerPolicyController::ACTION_SUSPEND,
- false /* lid_closed_controlled */,
- true /* has_lid */),
- GetLastSettingsChangedMessage());
+
+ // Current AC idle behavior should be DISPLAY_OFF.
+ settings.current_ac_behavior = PowerHandler::IdleBehavior::DISPLAY_OFF;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
+
+ // Now set the battery screen off delay to zero along with battery do-nothing
+ // idle action and check that the selected setting goes to "display on" when
+ // on battery.
+ GetPrefs()->Set(ash::prefs::kPowerBatteryIdleAction,
+ base::Value(PowerPolicyController::ACTION_DO_NOTHING));
+ GetPrefs()->Set(ash::prefs::kPowerBatteryScreenOffDelayMs, base::Value(0));
+
+ // Current battery idle behavior should be DISPLAY_ON.
+ settings.current_battery_behavior = PowerHandler::IdleBehavior::DISPLAY_ON;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
// Other idle actions should result in an "other" setting.
GetPrefs()->Set(ash::prefs::kPowerAcIdleAction,
base::Value(PowerPolicyController::ACTION_STOP_SESSION));
- EXPECT_EQ(CreateSettingsChangedString(
- PowerHandler::IdleBehavior::OTHER, false /* idle_controlled */,
- PowerPolicyController::ACTION_SUSPEND,
- false /* lid_closed_controlled */, true /* has_lid */),
- GetLastSettingsChangedMessage());
+ // Current AC idle behavior should be OTHER.
+ settings.current_ac_behavior = PowerHandler::IdleBehavior::OTHER;
+ // Possible AC idle behaviors should include OTHER too.
+ settings.possible_ac_behaviors.insert(PowerHandler::IdleBehavior::OTHER);
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
+}
+
+// Verifies that idle-related prefs when managed by enterpise policy are
+// distilled into the proper WebUI settings.
+IN_PROC_BROWSER_TEST_F(PowerHandlerTest, SendManagedIdleSettingForPrefChanges) {
+ policy::PolicyMap policy_map;
+ // Set Enterpise policy that forces AC idle action to suspend. Only possible
+ // AC idle option visible to the user should be DISPLAY_OFF_SLEEP and the
+ // current should also be set to same.
+ SetPolicyForPolicyKey(&policy_map, policy::key::kIdleActionAC,
+ std::make_unique<base::Value>(
+ chromeos::PowerPolicyController::ACTION_SUSPEND));
+ DevicePowerSettings settings;
+ std::set<PowerHandler::IdleBehavior> behaviors;
+ behaviors.insert(PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP);
+ settings.possible_ac_behaviors = behaviors;
+ settings.ac_idle_managed = true;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
+
+ // Set Enterpise policy that forces battery idle action to Shutdown. Only
+ // possible battery idle option visible to the user then should be OTHER and
+ // the default should also be set to same.
+ SetPolicyForPolicyKey(&policy_map, policy::key::kIdleActionBattery,
+ std::make_unique<base::Value>(
+ chromeos::PowerPolicyController::ACTION_SHUT_DOWN));
+ behaviors.clear();
+ behaviors.insert(PowerHandler::IdleBehavior::OTHER);
+ settings.possible_battery_behaviors = behaviors;
+ settings.current_battery_behavior = PowerHandler::IdleBehavior::OTHER;
+ settings.battery_idle_managed = true;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
+ // Erase battery idle action.
+ policy_map.Erase(policy::key::kIdleActionBattery);
+
+ // Set battery idle action to DO_NOTHING in Enterpise policy. The user then
+ // should not see DISPLAY_OFF_SLEEP in available options.
+ SetPolicyForPolicyKey(
+ &policy_map, policy::key::kIdleActionBattery,
+ std::make_unique<base::Value>(
+ chromeos::PowerPolicyController::ACTION_DO_NOTHING));
+ behaviors.clear();
+ behaviors.insert(PowerHandler::IdleBehavior::DISPLAY_OFF);
+ behaviors.insert(PowerHandler::IdleBehavior::DISPLAY_ON);
+ settings.possible_battery_behaviors = behaviors;
+ settings.current_battery_behavior = PowerHandler::IdleBehavior::DISPLAY_OFF;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
+
+ // Set battery screen delay in Enterprise policy on top of DO_NOTHING idle
+ // action. The user should see only see DISPLAY_OFF as the possible battery
+ // idle action.
+ SetPolicyForPolicyKey(&policy_map, policy::key::kScreenOffDelayBattery,
+ std::make_unique<base::Value>(10000));
+ behaviors.clear();
+ behaviors.insert(PowerHandler::IdleBehavior::DISPLAY_OFF);
+ settings.possible_battery_behaviors = behaviors;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
+
+ // Now stop enforcing battery idle action (to DO_NOTHING) in enterprise
+ // policy. The user should see DISPLAY_OFF and DISPLAY_OFF_SLEEP as
+ // the possible battery idle actions.
+ policy_map.Erase(policy::key::kIdleActionBattery);
+ UpdateChromePolicy(&policy_map);
+ settings.possible_battery_behaviors.insert(
+ PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP);
+ settings.current_battery_behavior =
+ PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
}
// Verifies that the lid-closed pref's value is sent directly to WebUI.
IN_PROC_BROWSER_TEST_F(PowerHandlerTest, SendLidSettingForPrefChanges) {
GetPrefs()->Set(ash::prefs::kPowerLidClosedAction,
base::Value(PowerPolicyController::ACTION_SHUT_DOWN));
- EXPECT_EQ(
- CreateSettingsChangedString(
- PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP,
- false /* idle_controlled */, PowerPolicyController::ACTION_SHUT_DOWN,
- false /* lid_closed_controlled */, true /* has_lid */),
- GetLastSettingsChangedMessage());
+ DevicePowerSettings settings;
+ settings.lid_closed_behavior = PowerPolicyController::ACTION_SHUT_DOWN;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
GetPrefs()->Set(ash::prefs::kPowerLidClosedAction,
base::Value(PowerPolicyController::ACTION_STOP_SESSION));
- EXPECT_EQ(CreateSettingsChangedString(
- PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP,
- false /* idle_controlled */,
- PowerPolicyController::ACTION_STOP_SESSION,
- false /* lid_closed_controlled */, true /* has_lid */),
- GetLastSettingsChangedMessage());
+ settings.lid_closed_behavior = PowerPolicyController::ACTION_STOP_SESSION;
+ EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage());
}
// Verifies that requests from WebUI to update the idle behavior update prefs
// appropriately.
IN_PROC_BROWSER_TEST_F(PowerHandlerTest, SetIdleBehavior) {
- // Request the "Keep display on" setting and check that prefs are set
+ // Request the "Keep display on" AC setting and check that prefs are set
// appropriately.
- test_api_->SetIdleBehavior(PowerHandler::IdleBehavior::DISPLAY_ON);
+ test_api_->SetIdleBehavior(PowerHandler::IdleBehavior::DISPLAY_ON,
+ true /* is_ac */);
EXPECT_EQ(PowerPolicyController::ACTION_DO_NOTHING,
GetIntPref(ash::prefs::kPowerAcIdleAction));
EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerAcScreenDimDelayMs));
EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerAcScreenOffDelayMs));
EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerAcScreenLockDelayMs));
- EXPECT_EQ(PowerPolicyController::ACTION_DO_NOTHING,
- GetIntPref(ash::prefs::kPowerBatteryIdleAction));
- EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerBatteryScreenDimDelayMs));
- EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerBatteryScreenOffDelayMs));
- EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerBatteryScreenLockDelayMs));
+ EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerBatteryIdleAction));
+ EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerBatteryScreenDimDelayMs));
+ EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerBatteryScreenOffDelayMs));
+ EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerBatteryScreenLockDelayMs));
- // "Turn off display" should set the idle prefs but clear the screen
- // delays.
- test_api_->SetIdleBehavior(PowerHandler::IdleBehavior::DISPLAY_OFF);
+ // "Turn off display" battery setting should set the battery idle pref but
+ // clear the battery screen delays.
+ test_api_->SetIdleBehavior(PowerHandler::IdleBehavior::DISPLAY_OFF,
+ false /* is_battery */);
EXPECT_EQ(PowerPolicyController::ACTION_DO_NOTHING,
GetIntPref(ash::prefs::kPowerAcIdleAction));
- EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerAcScreenDimDelayMs));
- EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerAcScreenOffDelayMs));
- EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerAcScreenLockDelayMs));
+ EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerAcScreenDimDelayMs));
+ EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerAcScreenOffDelayMs));
+ EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerAcScreenLockDelayMs));
EXPECT_EQ(PowerPolicyController::ACTION_DO_NOTHING,
GetIntPref(ash::prefs::kPowerBatteryIdleAction));
EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerBatteryScreenDimDelayMs));
EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerBatteryScreenOffDelayMs));
EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerBatteryScreenLockDelayMs));
- // Now switch to the "Keep display on" setting (to set the prefs again) and
- // check that the "Turn off display and sleep" setting clears all the prefs.
- test_api_->SetIdleBehavior(PowerHandler::IdleBehavior::DISPLAY_ON);
- test_api_->SetIdleBehavior(PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP);
- EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerAcIdleAction));
- EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerAcScreenDimDelayMs));
- EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerAcScreenOffDelayMs));
- EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerAcScreenLockDelayMs));
+ // Now switch to the "Keep display on" battery setting (to set the prefs
+ // again) and check that the "Turn off display and sleep" battery setting
+ // clears all the battery prefs.
+ test_api_->SetIdleBehavior(PowerHandler::IdleBehavior::DISPLAY_ON,
+ false /* is_battery */);
+ test_api_->SetIdleBehavior(PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP,
+ false /* is_battery */);
+ EXPECT_EQ(PowerPolicyController::ACTION_DO_NOTHING,
+ GetIntPref(ash::prefs::kPowerAcIdleAction));
+ EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerAcScreenDimDelayMs));
+ EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerAcScreenOffDelayMs));
+ EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerAcScreenLockDelayMs));
EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerBatteryIdleAction));
EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerBatteryScreenDimDelayMs));
EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerBatteryScreenOffDelayMs));
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc
index 0eebb3c1814..128d85cb80b 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc
@@ -6,46 +6,16 @@
#include <algorithm>
#include <limits>
-#include <numeric>
+#include <memory>
#include <string>
+#include <utility>
-#include "base/bind.h"
-#include "base/feature_list.h"
-#include "base/files/file_util.h"
-#include "base/system/sys_info.h"
-#include "base/task/post_task.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/browsing_data/browsing_data_appcache_helper.h"
-#include "chrome/browser/browsing_data/browsing_data_cache_storage_helper.h"
-#include "chrome/browser/browsing_data/browsing_data_cookie_helper.h"
-#include "chrome/browser/browsing_data/browsing_data_database_helper.h"
-#include "chrome/browser/browsing_data/browsing_data_file_system_helper.h"
-#include "chrome/browser/browsing_data/browsing_data_flash_lso_helper.h"
-#include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h"
-#include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h"
-#include "chrome/browser/browsing_data/browsing_data_service_worker_helper.h"
#include "chrome/browser/chromeos/arc/arc_util.h"
-#include "chrome/browser/chromeos/crostini/crostini_features.h"
-#include "chrome/browser/chromeos/crostini/crostini_manager.h"
-#include "chrome/browser/chromeos/crostini/crostini_util.h"
-#include "chrome/browser/chromeos/drive/file_system_util.h"
#include "chrome/browser/chromeos/file_manager/path_util.h"
#include "chrome/browser/platform_util.h"
-#include "chrome/browser/profiles/profile.h"
#include "chrome/grit/generated_resources.h"
-#include "chromeos/cryptohome/cryptohome_util.h"
-#include "chromeos/dbus/cryptohome/cryptohome_client.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/disks/disk.h"
#include "components/arc/arc_features.h"
-#include "components/arc/arc_prefs.h"
-#include "components/arc/arc_service_manager.h"
-#include "components/arc/arc_util.h"
-#include "components/arc/session/arc_bridge_service.h"
-#include "components/browsing_data/content/conditional_cache_counting_helper.h"
-#include "components/user_manager/user_manager.h"
-#include "content/public/browser/browser_context.h"
-#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_ui_data_source.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/text/bytes_formatting.h"
@@ -55,41 +25,43 @@ using chromeos::disks::DiskMountManager;
namespace chromeos {
namespace settings {
-namespace {
-
-void GetSizeStatBlocking(const base::FilePath& mount_path,
- int64_t* total_size,
- int64_t* available_size) {
- int64_t size = base::SysInfo::AmountOfTotalDiskSpace(mount_path);
- if (size >= 0)
- *total_size = size;
- size = base::SysInfo::AmountOfFreeDiskSpace(mount_path);
- if (size >= 0)
- *available_size = size;
-}
-
-// Threshold to show a message indicating space is critically low (512 MB).
-const int64_t kSpaceCriticallyLowBytes = 512 * 1024 * 1024;
-// Threshold to show a message indicating space is low (1 GB).
-const int64_t kSpaceLowBytes = 1 * 1024 * 1024 * 1024;
+namespace {
constexpr char kAndroidEnabled[] = "androidEnabled";
+const char* CalculationTypeToEventName(
+ calculator::SizeCalculator::CalculationType x) {
+ switch (x) {
+ case calculator::SizeCalculator::CalculationType::kSystem:
+ return "storage-system-size-changed";
+ case calculator::SizeCalculator::CalculationType::kInUse:
+ return "storage-size-stat-changed";
+ case calculator::SizeCalculator::CalculationType::kMyFiles:
+ return "storage-my-files-size-changed";
+ case calculator::SizeCalculator::CalculationType::kBrowsingData:
+ return "storage-browsing-data-size-changed";
+ case calculator::SizeCalculator::CalculationType::kAppsExtensions:
+ return "storage-apps-size-changed";
+ case calculator::SizeCalculator::CalculationType::kCrostini:
+ return "storage-crostini-size-changed";
+ case calculator::SizeCalculator::CalculationType::kOtherUsers:
+ return "storage-other-users-size-changed";
+ }
+ NOTREACHED();
+ return "";
+}
+
} // namespace
StorageHandler::StorageHandler(Profile* profile,
content::WebUIDataSource* html_source)
- : browser_cache_size_(-1),
- has_browser_cache_size_(false),
- browser_site_data_size_(-1),
- has_browser_site_data_size_(false),
- updating_downloads_size_(false),
- updating_browsing_data_size_(false),
- updating_android_size_(false),
- updating_crostini_size_(false),
- updating_other_users_size_(false),
- is_android_running_(false),
+ : size_stat_calculator_(profile),
+ my_files_size_calculator_(profile),
+ browsing_data_size_calculator_(profile),
+ apps_size_calculator_(profile),
+ crostini_size_calculator_(profile),
+ other_users_size_calculator_(),
profile_(profile),
source_name_(html_source->GetSource()),
arc_observer_(this),
@@ -101,11 +73,7 @@ StorageHandler::StorageHandler(Profile* profile,
}
StorageHandler::~StorageHandler() {
- DiskMountManager::GetInstance()->RemoveObserver(this);
- arc::ArcServiceManager::Get()
- ->arc_bridge_service()
- ->storage_manager()
- ->RemoveObserver(this);
+ StopObservingEvents();
}
void StorageHandler::RegisterMessages() {
@@ -120,8 +88,8 @@ void StorageHandler::RegisterMessages() {
base::BindRepeating(&StorageHandler::HandleUpdateStorageInfo,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
- "openDownloads", base::BindRepeating(&StorageHandler::HandleOpenDownloads,
- base::Unretained(this)));
+ "openMyFiles", base::BindRepeating(&StorageHandler::HandleOpenMyFiles,
+ base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"openArcStorage",
base::BindRepeating(&StorageHandler::HandleOpenArcStorage,
@@ -136,35 +104,48 @@ void StorageHandler::OnJavascriptAllowed() {
if (base::FeatureList::IsEnabled(arc::kUsbStorageUIFeature))
arc_observer_.Add(arc::ArcSessionManager::Get());
- // Start observing the mojo connection UpdateAndroidSize() relies on. Note
- // that OnConnectionReady() will be called immediately if the connection has
- // already been established.
- arc::ArcServiceManager::Get()
- ->arc_bridge_service()
- ->storage_manager()
- ->AddObserver(this);
-
// Start observing mount/unmount events to update the connected device list.
DiskMountManager::GetInstance()->AddObserver(this);
+
+ // Start observing calculators.
+ size_stat_calculator_.AddObserver(this);
+ my_files_size_calculator_.AddObserver(this);
+ browsing_data_size_calculator_.AddObserver(this);
+ apps_size_calculator_.AddObserver(this);
+ crostini_size_calculator_.AddObserver(this);
+ other_users_size_calculator_.AddObserver(this);
}
void StorageHandler::OnJavascriptDisallowed() {
// Ensure that pending callbacks do not complete and cause JS to be evaluated.
weak_ptr_factory_.InvalidateWeakPtrs();
- // Stop observing mount/unmount events to update the connected device list.
- DiskMountManager::GetInstance()->RemoveObserver(this);
-
- // Stop observing the mojo connection so that OnConnectionReady() and
- // OnConnectionClosed() that use FireWebUIListener() won't be called while JS
- // is disabled.
- arc::ArcServiceManager::Get()
- ->arc_bridge_service()
- ->storage_manager()
- ->RemoveObserver(this);
-
if (base::FeatureList::IsEnabled(arc::kUsbStorageUIFeature))
arc_observer_.Remove(arc::ArcSessionManager::Get());
+
+ StopObservingEvents();
+}
+
+int64_t StorageHandler::RoundByteSize(int64_t bytes) {
+ if (bytes < 0) {
+ NOTREACHED() << "Negative bytes value";
+ return -1;
+ }
+
+ // Subtract one to the original number of bytes.
+ bytes--;
+ // Set all the lower bits to 1.
+ bytes |= bytes >> 1;
+ bytes |= bytes >> 2;
+ bytes |= bytes >> 4;
+ bytes |= bytes >> 8;
+ bytes |= bytes >> 16;
+ bytes |= bytes >> 32;
+ // Add one. The one bit beyond the highest set bit is set to 1. All the lower
+ // bits are set to 0.
+ bytes++;
+
+ return bytes;
}
void StorageHandler::HandleUpdateAndroidEnabled(
@@ -176,20 +157,18 @@ void StorageHandler::HandleUpdateAndroidEnabled(
void StorageHandler::HandleUpdateStorageInfo(const base::ListValue* args) {
AllowJavascript();
- UpdateSizeStat();
- UpdateDownloadsSize();
- UpdateBrowsingDataSize();
- UpdateAndroidRunning();
- UpdateAndroidSize();
- UpdateCrostiniSize();
- UpdateOtherUsersSize();
+ size_stat_calculator_.StartCalculation();
+ my_files_size_calculator_.StartCalculation();
+ browsing_data_size_calculator_.StartCalculation();
+ apps_size_calculator_.StartCalculation();
+ crostini_size_calculator_.StartCalculation();
+ other_users_size_calculator_.StartCalculation();
}
-void StorageHandler::HandleOpenDownloads(
- const base::ListValue* unused_args) {
- const base::FilePath downloads_path =
- file_manager::util::GetDownloadsFolderForProfile(profile_);
- platform_util::OpenItem(profile_, downloads_path, platform_util::OPEN_FOLDER,
+void StorageHandler::HandleOpenMyFiles(const base::ListValue* unused_args) {
+ const base::FilePath my_files_path =
+ file_manager::util::GetMyFilesFolderForProfile(profile_);
+ platform_util::OpenItem(profile_, my_files_path, platform_util::OPEN_FOLDER,
platform_util::OpenOperationCallback());
}
@@ -206,233 +185,6 @@ void StorageHandler::HandleUpdateExternalStorages(
UpdateExternalStorages();
}
-void StorageHandler::UpdateSizeStat() {
- const base::FilePath downloads_path =
- file_manager::util::GetDownloadsFolderForProfile(profile_);
-
- int64_t* total_size = new int64_t(0);
- int64_t* available_size = new int64_t(0);
- base::PostTaskAndReply(
- FROM_HERE,
- {base::ThreadPool(), base::MayBlock(), base::TaskPriority::USER_VISIBLE},
- base::Bind(&GetSizeStatBlocking, downloads_path, total_size,
- available_size),
- base::Bind(&StorageHandler::OnGetSizeStat, weak_ptr_factory_.GetWeakPtr(),
- base::Owned(total_size), base::Owned(available_size)));
-}
-
-void StorageHandler::OnGetSizeStat(int64_t* total_size,
- int64_t* available_size) {
- int64_t used_size = *total_size - *available_size;
- base::DictionaryValue size_stat;
- size_stat.SetString("totalSize", ui::FormatBytes(*total_size));
- size_stat.SetString("availableSize", ui::FormatBytes(*available_size));
- size_stat.SetString("usedSize", ui::FormatBytes(used_size));
- size_stat.SetDouble("usedRatio",
- static_cast<double>(used_size) / *total_size);
- int storage_space_state = STORAGE_SPACE_NORMAL;
- if (*available_size < kSpaceCriticallyLowBytes)
- storage_space_state = STORAGE_SPACE_CRITICALLY_LOW;
- else if (*available_size < kSpaceLowBytes)
- storage_space_state = STORAGE_SPACE_LOW;
- size_stat.SetInteger("spaceState", storage_space_state);
-
- FireWebUIListener("storage-size-stat-changed", size_stat);
-}
-
-void StorageHandler::UpdateDownloadsSize() {
- if (updating_downloads_size_)
- return;
- updating_downloads_size_ = true;
-
- const base::FilePath downloads_path =
- file_manager::util::GetDownloadsFolderForProfile(profile_);
-
- base::PostTaskAndReplyWithResult(
- FROM_HERE,
- {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT},
- base::Bind(&base::ComputeDirectorySize, downloads_path),
- base::Bind(&StorageHandler::OnGetDownloadsSize,
- weak_ptr_factory_.GetWeakPtr()));
-}
-
-void StorageHandler::OnGetDownloadsSize(int64_t size) {
- updating_downloads_size_ = false;
- FireWebUIListener("storage-downloads-size-changed",
- base::Value(ui::FormatBytes(size)));
-}
-
-void StorageHandler::UpdateBrowsingDataSize() {
- if (updating_browsing_data_size_)
- return;
- updating_browsing_data_size_ = true;
-
- has_browser_cache_size_ = false;
- has_browser_site_data_size_ = false;
- // Fetch the size of http cache in browsing data.
- browsing_data::ConditionalCacheCountingHelper::Count(
- content::BrowserContext::GetDefaultStoragePartition(profile_),
- base::Time(), base::Time::Max(),
- base::BindOnce(&StorageHandler::OnGetCacheSize,
- weak_ptr_factory_.GetWeakPtr()));
-
- // Fetch the size of site data in browsing data.
- if (!site_data_size_collector_.get()) {
- content::StoragePartition* storage_partition =
- content::BrowserContext::GetDefaultStoragePartition(profile_);
- site_data_size_collector_ = std::make_unique<SiteDataSizeCollector>(
- storage_partition->GetPath(),
- new BrowsingDataCookieHelper(storage_partition),
- new BrowsingDataDatabaseHelper(profile_),
- new BrowsingDataLocalStorageHelper(profile_),
- new BrowsingDataAppCacheHelper(storage_partition->GetAppCacheService()),
- new BrowsingDataIndexedDBHelper(
- storage_partition->GetIndexedDBContext()),
- BrowsingDataFileSystemHelper::Create(
- storage_partition->GetFileSystemContext()),
- new BrowsingDataServiceWorkerHelper(
- storage_partition->GetServiceWorkerContext()),
- new BrowsingDataCacheStorageHelper(
- storage_partition->GetCacheStorageContext()),
- BrowsingDataFlashLSOHelper::Create(profile_));
- }
- site_data_size_collector_->Fetch(
- base::Bind(&StorageHandler::OnGetBrowsingDataSize,
- weak_ptr_factory_.GetWeakPtr(), true));
-}
-
-void StorageHandler::OnGetCacheSize(bool is_upper_limit, int64_t size) {
- DCHECK(!is_upper_limit);
- OnGetBrowsingDataSize(false, size);
-}
-
-void StorageHandler::OnGetBrowsingDataSize(bool is_site_data, int64_t size) {
- if (is_site_data) {
- has_browser_site_data_size_ = true;
- browser_site_data_size_ = size;
- } else {
- has_browser_cache_size_ = true;
- browser_cache_size_ = size;
- }
- if (has_browser_cache_size_ && has_browser_site_data_size_) {
- base::string16 size_string;
- if (browser_cache_size_ >= 0 && browser_site_data_size_ >= 0) {
- size_string = ui::FormatBytes(
- browser_site_data_size_ + browser_cache_size_);
- } else {
- size_string =
- l10n_util::GetStringUTF16(IDS_SETTINGS_STORAGE_SIZE_UNKNOWN);
- }
- updating_browsing_data_size_ = false;
- FireWebUIListener("storage-browsing-data-size-changed",
- base::Value(size_string));
- }
-}
-
-void StorageHandler::UpdateAndroidRunning() {
- FireWebUIListener("storage-android-running-changed",
- base::Value(is_android_running_));
-}
-
-void StorageHandler::UpdateAndroidSize() {
- if (!is_android_running_)
- return;
-
- if (updating_android_size_)
- return;
- updating_android_size_ = true;
-
- bool success = false;
- auto* arc_storage_manager =
- arc::ArcStorageManager::GetForBrowserContext(profile_);
- if (arc_storage_manager) {
- success = arc_storage_manager->GetApplicationsSize(base::BindOnce(
- &StorageHandler::OnGetAndroidSize, weak_ptr_factory_.GetWeakPtr()));
- }
- if (!success)
- updating_android_size_ = false;
-}
-
-void StorageHandler::OnGetAndroidSize(bool succeeded,
- arc::mojom::ApplicationsSizePtr size) {
- base::string16 size_string;
- if (succeeded) {
- uint64_t total_bytes = size->total_code_bytes + size->total_data_bytes +
- size->total_cache_bytes;
- size_string = ui::FormatBytes(total_bytes);
- } else {
- size_string = l10n_util::GetStringUTF16(IDS_SETTINGS_STORAGE_SIZE_UNKNOWN);
- }
- updating_android_size_ = false;
- FireWebUIListener("storage-android-size-changed", base::Value(size_string));
-}
-
-void StorageHandler::UpdateCrostiniSize() {
- if (!crostini::CrostiniFeatures::Get()->IsEnabled(profile_)) {
- return;
- }
-
- if (updating_crostini_size_)
- return;
- updating_crostini_size_ = true;
-
- crostini::CrostiniManager::GetForProfile(profile_)->ListVmDisks(
- base::BindOnce(&StorageHandler::OnGetCrostiniSize,
- weak_ptr_factory_.GetWeakPtr()));
-}
-
-void StorageHandler::OnGetCrostiniSize(crostini::CrostiniResult result,
- int64_t size) {
- updating_crostini_size_ = false;
- FireWebUIListener("storage-crostini-size-changed",
- base::Value(ui::FormatBytes(size)));
-}
-
-void StorageHandler::UpdateOtherUsersSize() {
- if (updating_other_users_size_)
- return;
- updating_other_users_size_ = true;
-
- other_users_.clear();
- user_sizes_.clear();
- const user_manager::UserList& users =
- user_manager::UserManager::Get()->GetUsers();
- for (auto* user : users) {
- if (user->is_active())
- continue;
- other_users_.push_back(user);
- CryptohomeClient::Get()->GetAccountDiskUsage(
- cryptohome::CreateAccountIdentifierFromAccountId(user->GetAccountId()),
- base::BindOnce(&StorageHandler::OnGetOtherUserSize,
- weak_ptr_factory_.GetWeakPtr()));
- }
- // We should show "0 B" if there is no other user.
- if (other_users_.empty()) {
- updating_other_users_size_ = false;
- FireWebUIListener("storage-other-users-size-changed",
- base::Value(ui::FormatBytes(0)));
- }
-}
-
-void StorageHandler::OnGetOtherUserSize(
- base::Optional<cryptohome::BaseReply> reply) {
- user_sizes_.push_back(cryptohome::AccountDiskUsageReplyToUsageSize(reply));
- if (user_sizes_.size() == other_users_.size()) {
- base::string16 size_string;
- // If all the requests succeed, shows the total bytes in the UI.
- if (std::count(user_sizes_.begin(), user_sizes_.end(), -1) == 0) {
- size_string = ui::FormatBytes(
- std::accumulate(user_sizes_.begin(), user_sizes_.end(), 0LL));
- } else {
- size_string =
- l10n_util::GetStringUTF16(IDS_SETTINGS_STORAGE_SIZE_UNKNOWN);
- }
- updating_other_users_size_ = false;
- FireWebUIListener("storage-other-users-size-changed",
- base::Value(size_string));
- }
-}
-
void StorageHandler::UpdateExternalStorages() {
base::Value devices(base::Value::Type::LIST);
for (const auto& itr : DiskMountManager::GetInstance()->mount_points()) {
@@ -463,19 +215,7 @@ void StorageHandler::UpdateExternalStorages() {
FireWebUIListener("onExternalStoragesUpdated", devices);
}
-void StorageHandler::OnConnectionReady() {
- is_android_running_ = true;
- UpdateAndroidRunning();
- UpdateAndroidSize();
-}
-
-void StorageHandler::OnConnectionClosed() {
- is_android_running_ = false;
- UpdateAndroidRunning();
-}
-
void StorageHandler::OnArcPlayStoreEnabledChanged(bool enabled) {
- FireWebUIListener("storage-android-enabled-changed", base::Value(enabled));
auto update = std::make_unique<base::DictionaryValue>();
update->SetKey(kAndroidEnabled, base::Value(enabled));
content::WebUIDataSource::Update(profile_, source_name_, std::move(update));
@@ -494,6 +234,114 @@ void StorageHandler::OnMountEvent(
UpdateExternalStorages();
}
+void StorageHandler::OnSizeCalculated(
+ const calculator::SizeCalculator::CalculationType& calculation_type,
+ int64_t total_bytes,
+ const base::Optional<int64_t>& available_bytes) {
+ if (available_bytes) {
+ UpdateSizeStat(calculation_type, total_bytes, available_bytes.value());
+ } else {
+ UpdateStorageItem(calculation_type, total_bytes);
+ }
+}
+
+void StorageHandler::StopObservingEvents() {
+ // Stop observing mount/unmount events to update the connected device list.
+ DiskMountManager::GetInstance()->RemoveObserver(this);
+
+ // Stop observing calculators.
+ size_stat_calculator_.RemoveObserver(this);
+ my_files_size_calculator_.RemoveObserver(this);
+ browsing_data_size_calculator_.RemoveObserver(this);
+ apps_size_calculator_.RemoveObserver(this);
+ crostini_size_calculator_.RemoveObserver(this);
+ other_users_size_calculator_.RemoveObserver(this);
+}
+
+void StorageHandler::UpdateStorageItem(
+ const calculator::SizeCalculator::CalculationType& calculation_type,
+ int64_t total_bytes) {
+ // When the system size has been calculated, UpdateSystemSize calls this
+ // method with the calculation type kSystem. This check prevents an infinite
+ // loop.
+ if (calculation_type != calculator::SizeCalculator::CalculationType::kSystem)
+ UpdateSystemSize(calculation_type, total_bytes);
+
+ base::string16 message;
+ if (total_bytes < 0) {
+ message = l10n_util::GetStringUTF16(IDS_SETTINGS_STORAGE_SIZE_UNKNOWN);
+ } else {
+ message = ui::FormatBytes(total_bytes);
+ }
+
+ if (calculation_type ==
+ calculator::SizeCalculator::CalculationType::kOtherUsers) {
+ bool no_other_users = (total_bytes == 0);
+ FireWebUIListener(CalculationTypeToEventName(calculation_type),
+ base::Value(message), base::Value(no_other_users));
+ } else {
+ FireWebUIListener(CalculationTypeToEventName(calculation_type),
+ base::Value(message));
+ }
+}
+
+void StorageHandler::UpdateSizeStat(
+ const calculator::SizeCalculator::CalculationType& calculation_type,
+ int64_t total_bytes,
+ int64_t available_bytes) {
+ int64_t rounded_total_bytes = RoundByteSize(total_bytes);
+ int64_t in_use_total_bytes_ = rounded_total_bytes - available_bytes;
+
+ UpdateSystemSize(calculation_type, in_use_total_bytes_);
+
+ base::DictionaryValue size_stat;
+ size_stat.SetString("availableSize", ui::FormatBytes(available_bytes));
+ size_stat.SetString("usedSize", ui::FormatBytes(in_use_total_bytes_));
+ size_stat.SetDouble("usedRatio", static_cast<double>(in_use_total_bytes_) /
+ rounded_total_bytes);
+ int storage_space_state =
+ static_cast<int>(StorageSpaceState::kStorageSpaceNormal);
+ if (available_bytes < kSpaceCriticallyLowBytes)
+ storage_space_state =
+ static_cast<int>(StorageSpaceState::kStorageSpaceCriticallyLow);
+ else if (available_bytes < kSpaceLowBytes)
+ storage_space_state = static_cast<int>(StorageSpaceState::kStorageSpaceLow);
+ size_stat.SetInteger("spaceState", storage_space_state);
+
+ FireWebUIListener(CalculationTypeToEventName(calculation_type), size_stat);
+}
+
+void StorageHandler::UpdateSystemSize(
+ const calculator::SizeCalculator::CalculationType& calculation_type,
+ int64_t total_bytes) {
+ const int item_index = static_cast<int>(calculation_type);
+ storage_items_total_bytes_[item_index] = total_bytes > 0 ? total_bytes : 0;
+ calculation_state_.set(item_index);
+
+ // Update system size. We only display the total system size when the size of
+ // all categories has been updated. If some size calculations are pending,
+ // return early and wait for all calculations to complete.
+ if (!calculation_state_.all())
+ return;
+
+ int64_t system_bytes = 0;
+ for (int i = 0; i < calculator::SizeCalculator::kCalculationTypeCount; ++i) {
+ int64_t total_bytes_for_current_item = storage_items_total_bytes_[i];
+ // If the storage is in use, add to the system's total storage.
+ if (i ==
+ static_cast<int>(calculator::SizeCalculator::CalculationType::kInUse)) {
+ system_bytes += total_bytes_for_current_item;
+ continue;
+ }
+ // Otherwise, this storage amount counts against the total storage
+ // amount.
+ system_bytes -= total_bytes_for_current_item;
+ }
+
+ OnSizeCalculated(calculator::SizeCalculator::CalculationType::kSystem,
+ system_bytes);
+}
+
bool StorageHandler::IsEligibleForAndroidStorage(std::string source_path) {
// Android's StorageManager volume concept relies on assumption that it is
// local filesystem. Hence, special volumes like DriveFS should not be
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h
index 4c901c9913a..cdd352797a6 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h
@@ -5,25 +5,12 @@
#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_STORAGE_HANDLER_H_
#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_STORAGE_HANDLER_H_
-#include <stdint.h>
-
-#include <memory>
#include <string>
-#include <vector>
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
-#include "base/scoped_observer.h"
-#include "chrome/browser/browsing_data/site_data_size_collector.h"
#include "chrome/browser/chromeos/arc/session/arc_session_manager.h"
+#include "chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.h"
#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
-#include "chromeos/dbus/cryptohome/rpc.pb.h"
#include "chromeos/disks/disk_mount_manager.h"
-#include "components/arc/mojom/storage_manager.mojom.h"
-#include "components/arc/session/connection_observer.h"
-#include "components/arc/storage_manager/arc_storage_manager.h"
-#include "components/user_manager/user.h"
#include "third_party/re2/src/re2/re2.h"
class Profile;
@@ -39,20 +26,25 @@ enum class CrostiniResult;
namespace chromeos {
namespace settings {
-class StorageHandler
- : public ::settings::SettingsPageUIHandler,
- public arc::ConnectionObserver<arc::mojom::StorageManagerInstance>,
- public arc::ArcSessionManager::Observer,
- public chromeos::disks::DiskMountManager::Observer {
- public:
- // Enumeration for device state about remaining space. These values must be
- // kept in sync with settings.StorageSpaceState in JS code.
- enum StorageSpaceState {
- STORAGE_SPACE_NORMAL = 0,
- STORAGE_SPACE_LOW = 1,
- STORAGE_SPACE_CRITICALLY_LOW = 2,
- };
+// Enumeration for device state about remaining space. These values must be
+// kept in sync with settings.StorageSpaceState in JS code.
+enum class StorageSpaceState {
+ kStorageSpaceNormal = 0,
+ kStorageSpaceLow = 1,
+ kStorageSpaceCriticallyLow = 2,
+};
+
+// Threshold to show a message indicating space is critically low (512 MB).
+const int64_t kSpaceCriticallyLowBytes = 512 * 1024 * 1024;
+// Threshold to show a message indicating space is low (1 GB).
+const int64_t kSpaceLowBytes = 1 * 1024 * 1024 * 1024;
+
+class StorageHandler : public ::settings::SettingsPageUIHandler,
+ public arc::ArcSessionManager::Observer,
+ public chromeos::disks::DiskMountManager::Observer,
+ public calculator::SizeCalculator::Observer {
+ public:
StorageHandler(Profile* profile, content::WebUIDataSource* html_source);
~StorageHandler() override;
@@ -61,10 +53,6 @@ class StorageHandler
void OnJavascriptAllowed() override;
void OnJavascriptDisallowed() override;
- // arc::ConnectionObserver<arc::mojom::StorageManagerInstance>:
- void OnConnectionReady() override;
- void OnConnectionClosed() override;
-
// arc::ArcSessionManager::Observer:
void OnArcPlayStoreEnabledChanged(bool enabled) override;
@@ -74,56 +62,42 @@ class StorageHandler
const chromeos::disks::DiskMountManager::MountPointInfo&
mount_info) override;
+ // chromeos::settings::calculator::SizeCalculator::Observer:
+ void OnSizeCalculated(
+ const calculator::SizeCalculator::CalculationType& calculation_type,
+ int64_t total_bytes,
+ const base::Optional<int64_t>& available_bytes = base::nullopt) override;
+
+ // Remove the handler from the list of observers of every observed instances.
+ void StopObservingEvents();
+
+ protected:
+ // Round a given number of bytes up to the next power of 2.
+ // Ex: 14 => 16, 150 => 256.
+ int64_t RoundByteSize(int64_t bytes);
+
private:
// Handlers of JS messages.
void HandleUpdateAndroidEnabled(const base::ListValue* unused_args);
void HandleUpdateStorageInfo(const base::ListValue* unused_args);
- void HandleOpenDownloads(const base::ListValue* unused_args);
+ void HandleOpenMyFiles(const base::ListValue* unused_args);
void HandleOpenArcStorage(const base::ListValue* unused_args);
void HandleUpdateExternalStorages(const base::ListValue* unused_args);
- // Requests updating disk space information.
- void UpdateSizeStat();
-
- // Callback to update the UI about disk space information.
- void OnGetSizeStat(int64_t* total_size, int64_t* available_size);
-
- // Requests updating the size of Downloads directory.
- void UpdateDownloadsSize();
-
- // Callback to update the UI about the size of Downloads directory.
- void OnGetDownloadsSize(int64_t size);
-
- // Requests updating the size of browsing data.
- void UpdateBrowsingDataSize();
-
- // Callback to receive the cache size.
- void OnGetCacheSize(bool is_upper_limit, int64_t size);
-
- // Callback to update the UI about the size of browsing data.
- void OnGetBrowsingDataSize(bool is_site_data, int64_t size);
-
- // Requests updating the flag that hides the Android size UI.
- void UpdateAndroidRunning();
-
- // Requests updating the space size used by Android apps and cache.
- void UpdateAndroidSize();
-
- // Callback to update the UI about Android apps and cache.
- void OnGetAndroidSize(bool succeeded, arc::mojom::ApplicationsSizePtr size);
-
- // Requests updating the space size used by Crostini VMs and their apps and
- // cache.
- void UpdateCrostiniSize();
-
- // Callback to update the UI about Crostini VMs and their apps and cache.
- void OnGetCrostiniSize(crostini::CrostiniResult result, int64_t size);
-
- // Requests updating the total size of other users' data.
- void UpdateOtherUsersSize();
-
- // Callback to save the fetched user sizes and update the UI.
- void OnGetOtherUserSize(base::Optional<cryptohome::BaseReply> reply);
+ // Update storage sizes on the UI.
+ void UpdateStorageItem(
+ const calculator::SizeCalculator::CalculationType& calculation_type,
+ int64_t total_bytes);
+ void UpdateSizeStat(
+ const calculator::SizeCalculator::CalculationType& calculation_type,
+ int64_t total_bytes,
+ int64_t available_bytes);
+
+ // Marks the size of |item| as calculated. When all storage items have been
+ // calculated, then "System" size can be calculated.
+ void UpdateSystemSize(
+ const calculator::SizeCalculator::CalculationType& calculation_type,
+ int64_t total_bytes);
// Updates list of external storages.
void UpdateExternalStorages();
@@ -132,38 +106,21 @@ class StorageHandler
// storage.
bool IsEligibleForAndroidStorage(std::string source_path);
- // Total size of cache data in browsing data.
- int64_t browser_cache_size_;
-
- // True if we have already received the size of http cache.
- bool has_browser_cache_size_;
-
- // Total size of site data in browsing data.
- int64_t browser_site_data_size_;
-
- // True if we have already received the size of site data.
- bool has_browser_site_data_size_;
-
- // Helper to compute the total size of all types of site date.
- std::unique_ptr<SiteDataSizeCollector> site_data_size_collector_;
-
- // The list of other users whose directory sizes will be accumulated as the
- // size of "Other users".
- user_manager::UserList other_users_;
-
- // Fetched sizes of user directories.
- std::vector<int64_t> user_sizes_;
-
- // Flags indicating fetch operations for storage sizes are ongoing.
- bool updating_downloads_size_;
- bool updating_browsing_data_size_;
- bool updating_android_size_;
- bool updating_crostini_size_;
- bool updating_other_users_size_;
-
- // A flag for keeping track of the mojo connection status to the ARC
- // container.
- bool is_android_running_;
+ // Instances calculating the size of each storage items.
+ calculator::SizeStatCalculator size_stat_calculator_;
+ calculator::MyFilesSizeCalculator my_files_size_calculator_;
+ calculator::BrowsingDataSizeCalculator browsing_data_size_calculator_;
+ calculator::AppsSizeCalculator apps_size_calculator_;
+ calculator::CrostiniSizeCalculator crostini_size_calculator_;
+ calculator::OtherUsersSizeCalculator other_users_size_calculator_;
+
+ // Controls if the size of each storage item has been calculated.
+ std::bitset<calculator::SizeCalculator::kCalculationTypeCount>
+ calculation_state_;
+
+ // Keeps track of the size of each storage item.
+ int64_t storage_items_total_bytes_
+ [calculator::SizeCalculator::kCalculationTypeCount] = {0};
Profile* const profile_;
const std::string source_name_;
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler_unittest.cc
new file mode 100644
index 00000000000..57c1ab89f3c
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler_unittest.cc
@@ -0,0 +1,516 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/files/file.h"
+#include "base/files/file_util.h"
+#include "base/path_service.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/system/sys_info.h"
+#include "chrome/browser/chromeos/arc/session/arc_session_manager.h"
+#include "chrome/browser/chromeos/arc/test/test_arc_session_manager.h"
+#include "chrome/browser/chromeos/file_manager/fake_disk_mount_manager.h"
+#include "chrome/browser/chromeos/file_manager/path_util.h"
+#include "chrome/browser/chromeos/scoped_set_running_on_chromeos_for_testing.h"
+#include "chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator_test_api.h"
+#include "chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/webui_url_constants.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "chrome/test/base/testing_profile_manager.h"
+#include "components/arc/arc_service_manager.h"
+#include "components/arc/test/fake_arc_session.h"
+#include "content/public/browser/web_ui_data_source.h"
+#include "content/public/test/browser_task_environment.h"
+#include "content/public/test/test_web_ui.h"
+#include "storage/browser/file_system/external_mount_points.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/text/bytes_formatting.h"
+
+namespace chromeos {
+namespace settings {
+
+namespace {
+
+const char kLsbRelease[] =
+ "CHROMEOS_RELEASE_NAME=Chrome OS\n"
+ "CHROMEOS_RELEASE_VERSION=1.2.3.4\n";
+
+class TestStorageHandler : public StorageHandler {
+ public:
+ explicit TestStorageHandler(Profile* profile,
+ content::WebUIDataSource* html_source)
+ : StorageHandler(profile, html_source) {}
+
+ // Pull WebUIMessageHandler::set_web_ui() into public so tests can call it.
+ using StorageHandler::RoundByteSize;
+ using StorageHandler::set_web_ui;
+};
+
+class StorageHandlerTest : public testing::Test {
+ public:
+ StorageHandlerTest() = default;
+ ~StorageHandlerTest() override = default;
+
+ void SetUp() override {
+ // The storage handler requires an instance of DiskMountManager,
+ // ArcServiceManager and ArcSessionManager.
+ chromeos::disks::DiskMountManager::InitializeForTesting(
+ new file_manager::FakeDiskMountManager);
+ arc_service_manager_ = std::make_unique<arc::ArcServiceManager>();
+ arc_session_manager_ = arc::CreateTestArcSessionManager(
+ std::make_unique<arc::ArcSessionRunner>(
+ base::BindRepeating(arc::FakeArcSession::Create)));
+
+ // Initialize profile.
+ profile_manager_ = std::make_unique<TestingProfileManager>(
+ TestingBrowserProcess::GetGlobal());
+ ASSERT_TRUE(profile_manager_->SetUp());
+ profile_ = profile_manager_->CreateTestingProfile("p1");
+
+ // Initialize storage handler.
+ content::WebUIDataSource* html_source =
+ content::WebUIDataSource::Create(chrome::kChromeUIOSSettingsHost);
+ handler_ = std::make_unique<TestStorageHandler>(profile_, html_source);
+ handler_->set_web_ui(&web_ui_);
+ handler_->AllowJavascriptForTesting();
+
+ // Initialize tests APIs.
+ size_stat_test_api_ = std::make_unique<calculator::SizeStatTestAPI>(
+ handler_.get(), new calculator::SizeStatCalculator(profile_));
+ my_files_size_test_api_ = std::make_unique<calculator::MyFilesSizeTestAPI>(
+ handler_.get(), new calculator::MyFilesSizeCalculator(profile_));
+ browsing_data_size_test_api_ =
+ std::make_unique<calculator::BrowsingDataSizeTestAPI>(
+ handler_.get(),
+ new calculator::BrowsingDataSizeCalculator(profile_));
+ apps_size_test_api_ = std::make_unique<calculator::AppsSizeTestAPI>(
+ handler_.get(), new calculator::AppsSizeCalculator(profile_));
+ crostini_size_test_api_ = std::make_unique<calculator::CrostiniSizeTestAPI>(
+ handler_.get(), new calculator::CrostiniSizeCalculator(profile_));
+ other_users_size_test_api_ =
+ std::make_unique<calculator::OtherUsersSizeTestAPI>(
+ handler_.get(), new calculator::OtherUsersSizeCalculator());
+
+ // Create and register My files directory.
+ // By emulating chromeos running, GetMyFilesFolderForProfile will return the
+ // profile's temporary location instead of $HOME/Downloads.
+ chromeos::ScopedSetRunningOnChromeOSForTesting fake_release(kLsbRelease,
+ base::Time());
+ const base::FilePath my_files_path =
+ file_manager::util::GetMyFilesFolderForProfile(profile_);
+ CHECK(base::CreateDirectory(my_files_path));
+ CHECK(storage::ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
+ file_manager::util::GetDownloadsMountPointName(profile_),
+ storage::kFileSystemTypeNativeLocal, storage::FileSystemMountOption(),
+ my_files_path));
+ }
+
+ void TearDown() override {
+ handler_.reset();
+ size_stat_test_api_.reset();
+ my_files_size_test_api_.reset();
+ browsing_data_size_test_api_.reset();
+ apps_size_test_api_.reset();
+ crostini_size_test_api_.reset();
+ other_users_size_test_api_.reset();
+ chromeos::disks::DiskMountManager::Shutdown();
+ storage::ExternalMountPoints::GetSystemInstance()->RevokeAllFileSystems();
+ }
+
+ protected:
+ // From a given amount of total size and available size as input, returns the
+ // space state determined by the OnGetSizeState function.
+ int GetSpaceState(int64_t* total_size, int64_t* available_size) {
+ size_stat_test_api_->SimulateOnGetSizeStat(total_size, available_size);
+ task_environment_.RunUntilIdle();
+ const base::Value* dictionary =
+ GetWebUICallbackMessage("storage-size-stat-changed");
+ EXPECT_TRUE(dictionary) << "No 'storage-size-stat-changed' callback";
+ int space_state = dictionary->FindKey("spaceState")->GetInt();
+ return space_state;
+ }
+
+ // Expects a callback message with a given |event_name|. A non null
+ // base::Value is returned if the callback message is found and has associated
+ // data.
+ const base::Value* GetWebUICallbackMessage(const std::string& event_name) {
+ for (auto it = web_ui_.call_data().rbegin();
+ it != web_ui_.call_data().rend(); ++it) {
+ const content::TestWebUI::CallData* data = it->get();
+ std::string name;
+ if (data->function_name() != "cr.webUIListenerCallback" ||
+ !data->arg1()->GetAsString(&name)) {
+ continue;
+ }
+ if (name == event_name)
+ return data->arg2();
+ }
+ return nullptr;
+ }
+
+ // Get the path to file manager's test data directory.
+ base::FilePath GetTestDataFilePath(const std::string& file_name) {
+ // Get the path to file manager's test data directory.
+ base::FilePath source_dir;
+ CHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &source_dir));
+ base::FilePath test_data_dir = source_dir.AppendASCII("chrome")
+ .AppendASCII("test")
+ .AppendASCII("data")
+ .AppendASCII("chromeos")
+ .AppendASCII("file_manager");
+
+ // Return full test data path to the given |file_name|.
+ return test_data_dir.Append(base::FilePath::FromUTF8Unsafe(file_name));
+ }
+
+ // Copy a file from the file manager's test data directory to the specified
+ // target_path.
+ void AddFile(const std::string& file_name,
+ int64_t expected_size,
+ base::FilePath target_path) {
+ const base::FilePath entry_path = GetTestDataFilePath(file_name);
+ target_path = target_path.AppendASCII(file_name);
+ ASSERT_TRUE(base::CopyFile(entry_path, target_path))
+ << "Copy from " << entry_path.value() << " to " << target_path.value()
+ << " failed.";
+ // Verify file size.
+ base::stat_wrapper_t stat;
+ const int res = base::File::Lstat(target_path.value().c_str(), &stat);
+ ASSERT_FALSE(res < 0) << "Couldn't stat" << target_path.value();
+ ASSERT_EQ(expected_size, stat.st_size);
+ }
+
+ std::unique_ptr<TestStorageHandler> handler_;
+ content::TestWebUI web_ui_;
+ content::BrowserTaskEnvironment task_environment_;
+ std::unique_ptr<TestingProfileManager> profile_manager_;
+ Profile* profile_;
+ std::unique_ptr<calculator::SizeStatTestAPI> size_stat_test_api_;
+ std::unique_ptr<calculator::MyFilesSizeTestAPI> my_files_size_test_api_;
+ std::unique_ptr<calculator::BrowsingDataSizeTestAPI>
+ browsing_data_size_test_api_;
+ std::unique_ptr<calculator::AppsSizeTestAPI> apps_size_test_api_;
+ std::unique_ptr<calculator::CrostiniSizeTestAPI> crostini_size_test_api_;
+ std::unique_ptr<calculator::OtherUsersSizeTestAPI> other_users_size_test_api_;
+
+ private:
+ std::unique_ptr<arc::ArcServiceManager> arc_service_manager_;
+ std::unique_ptr<arc::ArcSessionManager> arc_session_manager_;
+ DISALLOW_COPY_AND_ASSIGN(StorageHandlerTest);
+};
+
+TEST_F(StorageHandlerTest, RoundByteSize) {
+ static const struct {
+ int64_t bytes;
+ const char* expected;
+ } cases[] = {
+ {0, "0 B"},
+ {3, "4 B"},
+ {4, "4 B"},
+ {5, "8 B"},
+ {8 * 1024 - 1, "8.0 KB"},
+ {8 * 1024, "8.0 KB"},
+ {8 * 1024 + 1, "16.0 KB"},
+ {31 * 1024 * 1024, "32.0 MB"},
+ {32 * 1024 * 1024, "32.0 MB"},
+ {50 * 1024 * 1024, "64.0 MB"},
+ {65LL * 1024 * 1024 * 1024, "128 GB"},
+ {130LL * 1024 * 1024 * 1024, "256 GB"},
+ {130LL * 1024 * 1024 * 1024, "256 GB"},
+ {1LL * 1024 * 1024 * 1024 * 1024, "1.0 TB"},
+ {1LL * 1024 * 1024 * 1024 * 1024 + 1, "2.0 TB"},
+ {(1LL << 61) + 1, "4,096 PB"},
+ };
+
+ for (auto& c : cases) {
+ int64_t rounded_bytes = handler_->RoundByteSize(c.bytes);
+ EXPECT_EQ(base::ASCIIToUTF16(c.expected), ui::FormatBytes(rounded_bytes));
+ }
+}
+
+TEST_F(StorageHandlerTest, GlobalSizeStat) {
+ // Get local filesystem storage statistics.
+ const base::FilePath mount_path =
+ file_manager::util::GetMyFilesFolderForProfile(profile_);
+ int64_t total_size = base::SysInfo::AmountOfTotalDiskSpace(mount_path);
+ int64_t available_size = base::SysInfo::AmountOfFreeDiskSpace(mount_path);
+
+ // Round the total size.
+ int64_t rounded_total_size = handler_->RoundByteSize(total_size);
+ int64_t used_size = rounded_total_size - available_size;
+ double used_ratio = static_cast<double>(used_size) / rounded_total_size;
+
+ // Get statistics from storage handler's UpdateSizeStat.
+ size_stat_test_api_->StartCalculation();
+ task_environment_.RunUntilIdle();
+
+ const base::Value* dictionary =
+ GetWebUICallbackMessage("storage-size-stat-changed");
+ ASSERT_TRUE(dictionary) << "No 'storage-size-stat-changed' callback";
+
+ const std::string& storage_handler_available_size =
+ dictionary->FindKey("availableSize")->GetString();
+ const std::string& storage_handler_used_size =
+ dictionary->FindKey("usedSize")->GetString();
+ double storage_handler_used_ratio =
+ dictionary->FindKey("usedRatio")->GetDouble();
+
+ EXPECT_EQ(ui::FormatBytes(available_size),
+ base::ASCIIToUTF16(storage_handler_available_size));
+ EXPECT_EQ(ui::FormatBytes(used_size),
+ base::ASCIIToUTF16(storage_handler_used_size));
+ double diff = used_ratio > storage_handler_used_ratio
+ ? used_ratio - storage_handler_used_ratio
+ : storage_handler_used_ratio - used_ratio;
+ // Running the test while writing data on disk (~400MB/s), the difference
+ // between the values returned by the two AmountOfFreeDiskSpace calls is never
+ // more than 100KB. By expecting diff to be less than 100KB /
+ // rounded_total_size, the test is very unlikely to be flaky.
+ EXPECT_LE(diff, static_cast<double>(100 * 1024) / rounded_total_size);
+}
+
+TEST_F(StorageHandlerTest, StorageSpaceState) {
+ // Less than 512 MB available, space state is critically low.
+ int64_t total_size = 1024 * 1024 * 1024;
+ int64_t available_size = 512 * 1024 * 1024 - 1;
+ int space_state = GetSpaceState(&total_size, &available_size);
+ EXPECT_EQ(static_cast<int>(StorageSpaceState::kStorageSpaceCriticallyLow),
+ space_state);
+
+ // Less than 1GB available, space state is low.
+ available_size = 512 * 1024 * 1024;
+ space_state = GetSpaceState(&total_size, &available_size);
+ EXPECT_EQ(static_cast<int>(StorageSpaceState::kStorageSpaceLow), space_state);
+ available_size = 1024 * 1024 * 1024 - 1;
+ space_state = GetSpaceState(&total_size, &available_size);
+ EXPECT_EQ(static_cast<int>(StorageSpaceState::kStorageSpaceLow), space_state);
+
+ // From 1GB, normal space state.
+ available_size = 1024 * 1024 * 1024;
+ space_state = GetSpaceState(&total_size, &available_size);
+ EXPECT_EQ(static_cast<int>(StorageSpaceState::kStorageSpaceNormal),
+ space_state);
+}
+
+TEST_F(StorageHandlerTest, MyFilesSize) {
+ base::ScopedAllowBlockingForTesting allow_blocking;
+
+ const base::FilePath my_files_path =
+ file_manager::util::GetMyFilesFolderForProfile(profile_);
+ const base::FilePath downloads_path =
+ file_manager::util::GetDownloadsFolderForProfile(profile_);
+ const base::FilePath android_files_path =
+ profile_->GetPath().Append("AndroidFiles");
+ const base::FilePath android_files_download_path =
+ android_files_path.Append("Download");
+
+ // Create directories.
+ CHECK(base::CreateDirectory(downloads_path));
+ CHECK(base::CreateDirectory(android_files_path));
+ CHECK(base::CreateDirectory(android_files_download_path));
+
+ // Register android files mount point.
+ CHECK(storage::ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
+ file_manager::util::GetAndroidFilesMountPointName(),
+ storage::kFileSystemTypeNativeLocal, storage::FileSystemMountOption(),
+ android_files_path));
+
+ // Add files in My files and android files.
+ AddFile("random.bin", 8092, my_files_path); // ~7.9 KB
+ AddFile("tall.pdf", 15271, android_files_path); // ~14.9 KB
+ // Add file in Downloads and simulate bind mount with
+ // [android files]/Download.
+ AddFile("video.ogv", 59943, downloads_path); // ~58.6 KB
+ AddFile("video.ogv", 59943, android_files_download_path);
+
+ // Calculate My files size.
+ my_files_size_test_api_->StartCalculation();
+ task_environment_.RunUntilIdle();
+
+ const base::Value* callback =
+ GetWebUICallbackMessage("storage-my-files-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-my-files-size-changed' callback";
+
+ // Check return value.
+ EXPECT_EQ("81.4 KB", callback->GetString());
+}
+
+TEST_F(StorageHandlerTest, AppsExtensionsSize) {
+ // The data for apps and extensions apps_size_test_api_installed from the
+ // webstore is stored in the Extensions folder. Add data at a random location
+ // in the Extensions folder and check UI callback message.
+ const base::FilePath extensions_data_path =
+ profile_->GetPath()
+ .AppendASCII("Extensions")
+ .AppendASCII("fake_extension_id");
+ CHECK(base::CreateDirectory(extensions_data_path));
+ AddFile("id3Audio.mp3", 180999, extensions_data_path); // ~177 KB
+
+ // Calculate web store apps and extensions size.
+ apps_size_test_api_->StartCalculation();
+ task_environment_.RunUntilIdle();
+
+ const base::Value* callback =
+ GetWebUICallbackMessage("storage-apps-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-apps-size-changed' callback";
+
+ // Check return value.
+ EXPECT_EQ("177 KB", callback->GetString());
+
+ // Simulate android apps size callback.
+ // 592840 + 25284 + 9987 = 628111 ~613 KB.
+ apps_size_test_api_->SimulateOnGetAndroidAppsSize(true /* succeeded */,
+ 592840, 25284, 9987);
+ task_environment_.RunUntilIdle();
+
+ callback = GetWebUICallbackMessage("storage-apps-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-apps-size-changed' callback";
+
+ // Check return value.
+ EXPECT_EQ("790 KB", callback->GetString());
+
+ // Add more data in the Extensions folder. Android is not running and the size
+ // of android apps is back down to 0 B.
+ AddFile("video_long.ogv", 230096, extensions_data_path); // ~225 KB
+
+ // Calculate web store apps and extensions size.
+ apps_size_test_api_->StartCalculation();
+ task_environment_.RunUntilIdle();
+
+ callback = GetWebUICallbackMessage("storage-apps-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-apps-size-changed' callback";
+
+ // Check return value.
+ EXPECT_EQ("401 KB", callback->GetString());
+}
+
+TEST_F(StorageHandlerTest, SystemSize) {
+ // The "System" row on the storage page displays the difference between the
+ // total amount of used space and the sum of the sizes of the different
+ // storage items of the storage page (My files, Browsing data, apps etc...)
+ // This test simulates callbacks from each one of these storage items; the
+ // calculation of the "System" size should only happen when all of the other
+ // storage items have been calculated.
+ const int64_t KB = 1024;
+ const int64_t MB = 1024 * KB;
+ const int64_t GB = 1024 * MB;
+ const int64_t TB = 1024 * GB;
+
+ // Simulate size stat callback.
+ int64_t total_size = TB;
+ int64_t available_size = 100 * GB;
+ size_stat_test_api_->SimulateOnGetSizeStat(&total_size, &available_size);
+ const base::Value* callback =
+ GetWebUICallbackMessage("storage-size-stat-changed");
+ ASSERT_TRUE(callback) << "No 'storage-size-stat-changed' callback";
+ EXPECT_EQ("100 GB", callback->FindKey("availableSize")->GetString());
+ EXPECT_EQ("924 GB", callback->FindKey("usedSize")->GetString());
+ // Expect no system size callback until every other item has been updated.
+ ASSERT_FALSE(GetWebUICallbackMessage("storage-system-size-changed"));
+
+ // Simulate my files size callback.
+ my_files_size_test_api_->SimulateOnGetTotalBytes(400 * GB);
+ callback = GetWebUICallbackMessage("storage-my-files-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-my-files-size-changed' callback";
+ EXPECT_EQ("400 GB", callback->GetString());
+ ASSERT_FALSE(GetWebUICallbackMessage("storage-system-size-changed"));
+
+ // Simulate browsing data callbacks. Has to be called with
+ // both |is_data_site| = true and false.
+ browsing_data_size_test_api_->SimulateOnGetBrowsingDataSize(
+ true /* is_site_data */, 10 * GB);
+ ASSERT_FALSE(GetWebUICallbackMessage("storage-browsing-data-size-changed"));
+ ASSERT_FALSE(GetWebUICallbackMessage("storage-system-size-changed"));
+ browsing_data_size_test_api_->SimulateOnGetBrowsingDataSize(
+ false /* is_site_data */, 14 * GB);
+ callback = GetWebUICallbackMessage("storage-browsing-data-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-browsing-data-size-changed' callback";
+ EXPECT_EQ("24.0 GB", callback->GetString());
+ ASSERT_FALSE(GetWebUICallbackMessage("storage-system-size-changed"));
+
+ // Simulate apps and extensions size callbacks.
+ apps_size_test_api_->SimulateOnGetAppsSize(29 * GB);
+ apps_size_test_api_->SimulateOnGetAndroidAppsSize(false, 0, 0, 0);
+ callback = GetWebUICallbackMessage("storage-apps-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-apps-size-changed' callback";
+ EXPECT_EQ("29.0 GB", callback->GetString());
+ ASSERT_FALSE(GetWebUICallbackMessage("storage-system-size-changed"));
+ apps_size_test_api_->SimulateOnGetAndroidAppsSize(
+ true /* succeeded */, 724 * MB, 100 * MB, 200 * MB);
+ callback = GetWebUICallbackMessage("storage-apps-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-apps-size-changed' callback";
+ EXPECT_EQ("30.0 GB", callback->GetString());
+ ASSERT_FALSE(GetWebUICallbackMessage("storage-system-size-changed"));
+
+ // Simulate crostini size callback.
+ crostini_size_test_api_->SimulateOnGetCrostiniSize(70 * GB);
+ callback = GetWebUICallbackMessage("storage-crostini-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-crostini-size-changed' callback";
+ EXPECT_EQ("70.0 GB", callback->GetString());
+ ASSERT_FALSE(GetWebUICallbackMessage("storage-system-size-changed"));
+
+ // Simulate other users size callback. No callback message until the sizes of
+ // every users is calculated.
+ std::vector<int64_t> other_user_sizes =
+ std::vector<int64_t>{200 * GB, 50 * GB, 50 * GB};
+ other_users_size_test_api_->InitializeOtherUserSize(other_user_sizes.size());
+ for (std::size_t i = 0; i < other_user_sizes.size(); i++) {
+ cryptohome::BaseReply result;
+ result.set_error(cryptohome::CRYPTOHOME_ERROR_NOT_SET);
+ cryptohome::GetAccountDiskUsageReply* usage_reply =
+ result.MutableExtension(cryptohome::GetAccountDiskUsageReply::reply);
+ usage_reply->set_size(other_user_sizes[i]);
+ base::Optional<cryptohome::BaseReply> reply = std::move(result);
+ other_users_size_test_api_->SimulateOnGetOtherUserSize(reply);
+ if (i < other_user_sizes.size() - 1) {
+ ASSERT_FALSE(GetWebUICallbackMessage("storage-other-users-size-changed"));
+ ASSERT_FALSE(GetWebUICallbackMessage("storage-system-size-changed"));
+ } else {
+ // When the size of the last user's cryptohome is calculated, we expect a
+ // callback with the "Other users" size.
+ callback = GetWebUICallbackMessage("storage-other-users-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-other-users-size-changed' callback";
+ EXPECT_EQ("300 GB", callback->GetString());
+ // Every item size has been calculated, system size should also be
+ // updated.
+ callback = GetWebUICallbackMessage("storage-system-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-system-size-changed' callback";
+ EXPECT_EQ("100 GB", callback->GetString());
+ }
+ }
+
+ // If there's an error while calculating the size of browsing data, the size
+ // of browsing data and system should be displayed as "Unknown".
+ browsing_data_size_test_api_->SimulateOnGetBrowsingDataSize(
+ true /* is_site_data */, -1);
+ callback = GetWebUICallbackMessage("storage-browsing-data-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-browsing-data-size-changed' callback";
+ EXPECT_EQ("Unknown", callback->GetString());
+ // The missing 24.0 GB of browsing data should be reflected in the system
+ // section instead. We expect the displayed size to be 100 + 24 GB.
+ callback = GetWebUICallbackMessage("storage-system-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-system-size-changed' callback";
+ EXPECT_EQ("124 GB", callback->GetString());
+
+ // No error while recalculating browsing data size, the UI should be updated
+ // with the right sizes.
+ browsing_data_size_test_api_->SimulateOnGetBrowsingDataSize(
+ true /* is_site_data */, 10 * GB);
+ callback = GetWebUICallbackMessage("storage-browsing-data-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-browsing-data-size-changed' callback";
+ EXPECT_EQ("24.0 GB", callback->GetString());
+ callback = GetWebUICallbackMessage("storage-system-size-changed");
+ ASSERT_TRUE(callback) << "No 'storage-system-size-changed' callback";
+ EXPECT_EQ("100 GB", callback->GetString());
+}
+
+} // namespace
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.cc
index 601eeaf2435..0a90a0e3039 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.cc
@@ -20,9 +20,7 @@
#include "chrome/common/pref_names.h"
#include "chrome/grit/generated_resources.h"
#include "components/prefs/pref_service.h"
-#include "content/public/browser/system_connector.h"
-#include "services/device/public/mojom/constants.mojom.h"
-#include "services/service_manager/public/cpp/connector.h"
+#include "content/public/browser/device_service.h"
#include "ui/base/l10n/l10n_util.h"
using session_manager::SessionManager;
@@ -57,8 +55,8 @@ std::unique_ptr<base::DictionaryValue> GetFingerprintsInfo(
} // namespace
FingerprintHandler::FingerprintHandler(Profile* profile) : profile_(profile) {
- content::GetSystemConnector()->Connect(
- device::mojom::kServiceName, fp_service_.BindNewPipeAndPassReceiver());
+ content::GetDeviceService().BindFingerprint(
+ fp_service_.BindNewPipeAndPassReceiver());
user_id_ = ProfileHelper::Get()->GetUserIdHashFromProfile(profile);
}
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/internet_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/internet_handler.cc
index e75796ecd32..bd301cfcb91 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/internet_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/internet_handler.cc
@@ -143,7 +143,8 @@ void InternetHandler::ConfigureThirdPartyVpn(const base::ListValue* args) {
return;
}
if (network->type() != shill::kTypeVPN) {
- NET_LOG(ERROR) << "ConfigureThirdPartyVpn: Network is not a VPN: " << guid;
+ NET_LOG(ERROR) << "ConfigureThirdPartyVpn: Network is not a VPN: "
+ << NetworkId(network);
return;
}
@@ -169,7 +170,8 @@ void InternetHandler::ConfigureThirdPartyVpn(const base::ListValue* args) {
}
NET_LOG(ERROR) << "ConfigureThirdPartyVpn: Unsupported VPN type: "
- << network->GetVpnProviderType() << " For: " << guid;
+ << network->GetVpnProviderType()
+ << " For: " << NetworkId(network);
}
void InternetHandler::RequestGmsCoreNotificationsDisabledDeviceNames(
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/internet_strings_provider.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/internet_strings_provider.cc
new file mode 100644
index 00000000000..90a75cf7418
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/internet_strings_provider.cc
@@ -0,0 +1,252 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/internet_strings_provider.h"
+
+#include "ash/public/cpp/network_config_service.h"
+#include "base/bind.h"
+#include "base/no_destructor.h"
+#include "chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.h"
+#include "chrome/browser/ui/webui/webui_util.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/common/webui_url_constants.h"
+#include "chrome/grit/chromium_strings.h"
+#include "chrome/grit/generated_resources.h"
+#include "chromeos/strings/grit/chromeos_strings.h"
+#include "components/strings/grit/components_strings.h"
+#include "content/public/browser/web_ui_data_source.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/webui/web_ui_util.h"
+
+namespace chromeos {
+namespace settings {
+namespace {
+
+const std::vector<SearchConcept>& GetNetworkSearchConcepts() {
+ static const base::NoDestructor<std::vector<SearchConcept>> tags({
+ {IDS_SETTINGS_TAG_NETWORK_SETTINGS,
+ chrome::kNetworksSubPage,
+ mojom::SearchResultIcon::kWifi,
+ {IDS_SETTINGS_TAG_NETWORK_SETTINGS_ALT1, SearchConcept::kAltTagEnd}},
+ });
+ return *tags;
+}
+
+const std::vector<SearchConcept>& GetEthernetSearchConcepts() {
+ static const base::NoDestructor<std::vector<SearchConcept>> tags({
+ {IDS_SETTINGS_TAG_ETHERNET_SETTINGS,
+ chrome::kEthernetSettingsSubPage,
+ mojom::SearchResultIcon::kEthernet,
+ {IDS_SETTINGS_TAG_ETHERNET_SETTINGS_ALT1, SearchConcept::kAltTagEnd}},
+ });
+ return *tags;
+}
+
+const std::vector<SearchConcept>& GetWifiSearchConcepts() {
+ static const base::NoDestructor<std::vector<SearchConcept>> tags({
+ {IDS_SETTINGS_TAG_WIFI_SETTINGS, chrome::kWiFiSettingsSubPage,
+ mojom::SearchResultIcon::kWifi},
+ {IDS_SETTINGS_TAG_TURN_ON_WIFI,
+ chrome::kWiFiSettingsSubPage,
+ mojom::SearchResultIcon::kWifi,
+ {IDS_SETTINGS_TAG_TURN_ON_WIFI_ALT1, SearchConcept::kAltTagEnd}},
+ {IDS_SETTINGS_TAG_TURN_OFF_WIFI,
+ chrome::kWiFiSettingsSubPage,
+ mojom::SearchResultIcon::kWifi,
+ {IDS_SETTINGS_TAG_TURN_OFF_WIFI_ALT1, SearchConcept::kAltTagEnd}},
+ {IDS_SETTINGS_TAG_CONNECT_WIFI, chrome::kWiFiSettingsSubPage,
+ mojom::SearchResultIcon::kWifi},
+ {IDS_SETTINGS_TAG_DISCONNECT_WIFI, chrome::kWiFiSettingsSubPage,
+ mojom::SearchResultIcon::kWifi},
+ });
+ return *tags;
+}
+
+} // namespace
+
+InternetStringsProvider::InternetStringsProvider(Profile* profile,
+ Delegate* per_page_delegate)
+ : OsSettingsPerPageStringsProvider(profile, per_page_delegate) {
+ // General network search tags are always added.
+ delegate()->AddSearchTags(GetNetworkSearchConcepts());
+
+ // Receive updates when devices (e.g., Ethernet, Wi-Fi) go on/offline.
+ ash::GetNetworkConfigService(
+ cros_network_config_.BindNewPipeAndPassReceiver());
+ cros_network_config_->AddObserver(receiver_.BindNewPipeAndPassRemote());
+
+ // Fetch initial list of devices.
+ FetchDeviceList();
+}
+
+InternetStringsProvider::~InternetStringsProvider() = default;
+
+void InternetStringsProvider::AddUiStrings(
+ content::WebUIDataSource* html_source) const {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"internetAddConnection", IDS_SETTINGS_INTERNET_ADD_CONNECTION},
+ {"internetAddConnectionExpandA11yLabel",
+ IDS_SETTINGS_INTERNET_ADD_CONNECTION_EXPAND_ACCESSIBILITY_LABEL},
+ {"internetAddConnectionNotAllowed",
+ IDS_SETTINGS_INTERNET_ADD_CONNECTION_NOT_ALLOWED},
+ {"internetAddThirdPartyVPN", IDS_SETTINGS_INTERNET_ADD_THIRD_PARTY_VPN},
+ {"internetAddVPN", IDS_SETTINGS_INTERNET_ADD_VPN},
+ {"internetAddWiFi", IDS_SETTINGS_INTERNET_ADD_WIFI},
+ {"internetConfigName", IDS_SETTINGS_INTERNET_CONFIG_NAME},
+ {"internetDetailPageTitle", IDS_SETTINGS_INTERNET_DETAIL},
+ {"internetDeviceEnabling", IDS_SETTINGS_INTERNET_DEVICE_ENABLING},
+ {"internetDeviceInitializing", IDS_SETTINGS_INTERNET_DEVICE_INITIALIZING},
+ {"internetJoinType", IDS_SETTINGS_INTERNET_JOIN_TYPE},
+ {"internetKnownNetworksPageTitle", IDS_SETTINGS_INTERNET_KNOWN_NETWORKS},
+ {"internetMobileSearching", IDS_SETTINGS_INTERNET_MOBILE_SEARCH},
+ {"internetNoNetworks", IDS_SETTINGS_INTERNET_NO_NETWORKS},
+ {"internetPageTitle", IDS_SETTINGS_INTERNET},
+ {"internetSummaryButtonA11yLabel",
+ IDS_SETTINGS_INTERNET_SUMMARY_BUTTON_ACCESSIBILITY_LABEL},
+ {"internetToggleMobileA11yLabel",
+ IDS_SETTINGS_INTERNET_TOGGLE_MOBILE_ACCESSIBILITY_LABEL},
+ {"internetToggleTetherLabel", IDS_SETTINGS_INTERNET_TOGGLE_TETHER_LABEL},
+ {"internetToggleTetherSubtext",
+ IDS_SETTINGS_INTERNET_TOGGLE_TETHER_SUBTEXT},
+ {"internetToggleWiFiA11yLabel",
+ IDS_SETTINGS_INTERNET_TOGGLE_WIFI_ACCESSIBILITY_LABEL},
+ {"knownNetworksAll", IDS_SETTINGS_INTERNET_KNOWN_NETWORKS_ALL},
+ {"knownNetworksButton", IDS_SETTINGS_INTERNET_KNOWN_NETWORKS_BUTTON},
+ {"knownNetworksMessage", IDS_SETTINGS_INTERNET_KNOWN_NETWORKS_MESSAGE},
+ {"knownNetworksPreferred",
+ IDS_SETTINGS_INTERNET_KNOWN_NETWORKS_PREFFERED},
+ {"knownNetworksMenuAddPreferred",
+ IDS_SETTINGS_INTERNET_KNOWN_NETWORKS_MENU_ADD_PREFERRED},
+ {"knownNetworksMenuRemovePreferred",
+ IDS_SETTINGS_INTERNET_KNOWN_NETWORKS_MENU_REMOVE_PREFERRED},
+ {"knownNetworksMenuForget",
+ IDS_SETTINGS_INTERNET_KNOWN_NETWORKS_MENU_FORGET},
+ {"networkAllowDataRoaming",
+ IDS_SETTINGS_SETTINGS_NETWORK_ALLOW_DATA_ROAMING},
+ {"networkAllowDataRoamingEnabledHome",
+ IDS_SETTINGS_SETTINGS_NETWORK_ALLOW_DATA_ROAMING_ENABLED_HOME},
+ {"networkAllowDataRoamingEnabledRoaming",
+ IDS_SETTINGS_SETTINGS_NETWORK_ALLOW_DATA_ROAMING_ENABLED_ROAMING},
+ {"networkAllowDataRoamingDisabled",
+ IDS_SETTINGS_SETTINGS_NETWORK_ALLOW_DATA_ROAMING_DISABLED},
+ {"networkAlwaysOnVpn", IDS_SETTINGS_INTERNET_NETWORK_ALWAYS_ON_VPN},
+ {"networkAutoConnect", IDS_SETTINGS_INTERNET_NETWORK_AUTO_CONNECT},
+ {"networkAutoConnectCellular",
+ IDS_SETTINGS_INTERNET_NETWORK_AUTO_CONNECT_CELLULAR},
+ {"networkButtonActivate", IDS_SETTINGS_INTERNET_BUTTON_ACTIVATE},
+ {"networkButtonConfigure", IDS_SETTINGS_INTERNET_BUTTON_CONFIGURE},
+ {"networkButtonConnect", IDS_SETTINGS_INTERNET_BUTTON_CONNECT},
+ {"networkButtonDisconnect", IDS_SETTINGS_INTERNET_BUTTON_DISCONNECT},
+ {"networkButtonForget", IDS_SETTINGS_INTERNET_BUTTON_FORGET},
+ {"networkButtonViewAccount", IDS_SETTINGS_INTERNET_BUTTON_VIEW_ACCOUNT},
+ {"networkConnectNotAllowed", IDS_SETTINGS_INTERNET_CONNECT_NOT_ALLOWED},
+ {"networkIPAddress", IDS_SETTINGS_INTERNET_NETWORK_IP_ADDRESS},
+ {"networkIPConfigAuto", IDS_SETTINGS_INTERNET_NETWORK_IP_CONFIG_AUTO},
+ {"networkNameserversLearnMore", IDS_LEARN_MORE},
+ {"networkPrefer", IDS_SETTINGS_INTERNET_NETWORK_PREFER},
+ {"networkPrimaryUserControlled",
+ IDS_SETTINGS_INTERNET_NETWORK_PRIMARY_USER_CONTROLLED},
+ {"networkScanningLabel", IDS_NETWORK_SCANNING_MESSAGE},
+ {"networkSectionAdvanced",
+ IDS_SETTINGS_INTERNET_NETWORK_SECTION_ADVANCED},
+ {"networkSectionAdvancedA11yLabel",
+ IDS_SETTINGS_INTERNET_NETWORK_SECTION_ADVANCED_ACCESSIBILITY_LABEL},
+ {"networkSectionNetwork", IDS_SETTINGS_INTERNET_NETWORK_SECTION_NETWORK},
+ {"networkSectionNetworkExpandA11yLabel",
+ IDS_SETTINGS_INTERNET_NETWORK_SECTION_NETWORK_ACCESSIBILITY_LABEL},
+ {"networkSectionProxy", IDS_SETTINGS_INTERNET_NETWORK_SECTION_PROXY},
+ {"networkSectionProxyExpandA11yLabel",
+ IDS_SETTINGS_INTERNET_NETWORK_SECTION_PROXY_ACCESSIBILITY_LABEL},
+ {"networkShared", IDS_SETTINGS_INTERNET_NETWORK_SHARED},
+ {"networkVpnBuiltin", IDS_NETWORK_TYPE_VPN_BUILTIN},
+ {"networkOutOfRange", IDS_SETTINGS_INTERNET_WIFI_NETWORK_OUT_OF_RANGE},
+ {"cellularContactSpecificCarrier",
+ IDS_SETTINGS_INTERNET_CELLULAR_CONTACT_SPECIFIC_CARRIER},
+ {"cellularContactDefaultCarrier",
+ IDS_SETTINGS_INTERNET_CELLULAR_CONTACT_DEFAULT_CARRIER},
+ {"tetherPhoneOutOfRange",
+ IDS_SETTINGS_INTERNET_TETHER_PHONE_OUT_OF_RANGE},
+ {"gmscoreNotificationsTitle",
+ IDS_SETTINGS_INTERNET_GMSCORE_NOTIFICATIONS_TITLE},
+ {"gmscoreNotificationsOneDeviceSubtitle",
+ IDS_SETTINGS_INTERNET_GMSCORE_NOTIFICATIONS_ONE_DEVICE_SUBTITLE},
+ {"gmscoreNotificationsTwoDevicesSubtitle",
+ IDS_SETTINGS_INTERNET_GMSCORE_NOTIFICATIONS_TWO_DEVICES_SUBTITLE},
+ {"gmscoreNotificationsManyDevicesSubtitle",
+ IDS_SETTINGS_INTERNET_GMSCORE_NOTIFICATIONS_MANY_DEVICES_SUBTITLE},
+ {"gmscoreNotificationsFirstStep",
+ IDS_SETTINGS_INTERNET_GMSCORE_NOTIFICATIONS_FIRST_STEP},
+ {"gmscoreNotificationsSecondStep",
+ IDS_SETTINGS_INTERNET_GMSCORE_NOTIFICATIONS_SECOND_STEP},
+ {"gmscoreNotificationsThirdStep",
+ IDS_SETTINGS_INTERNET_GMSCORE_NOTIFICATIONS_THIRD_STEP},
+ {"gmscoreNotificationsFourthStep",
+ IDS_SETTINGS_INTERNET_GMSCORE_NOTIFICATIONS_FOURTH_STEP},
+ {"tetherConnectionDialogTitle",
+ IDS_SETTINGS_INTERNET_TETHER_CONNECTION_DIALOG_TITLE},
+ {"tetherConnectionAvailableDeviceTitle",
+ IDS_SETTINGS_INTERNET_TETHER_CONNECTION_AVAILABLE_DEVICE_TITLE},
+ {"tetherConnectionBatteryPercentage",
+ IDS_SETTINGS_INTERNET_TETHER_CONNECTION_BATTERY_PERCENTAGE},
+ {"tetherConnectionExplanation",
+ IDS_SETTINGS_INTERNET_TETHER_CONNECTION_EXPLANATION},
+ {"tetherConnectionCarrierWarning",
+ IDS_SETTINGS_INTERNET_TETHER_CONNECTION_CARRIER_WARNING},
+ {"tetherConnectionDescriptionTitle",
+ IDS_SETTINGS_INTERNET_TETHER_CONNECTION_DESCRIPTION_TITLE},
+ {"tetherConnectionDescriptionMobileData",
+ IDS_SETTINGS_INTERNET_TETHER_CONNECTION_DESCRIPTION_MOBILE_DATA},
+ {"tetherConnectionDescriptionBattery",
+ IDS_SETTINGS_INTERNET_TETHER_CONNECTION_DESCRIPTION_BATTERY},
+ {"tetherConnectionDescriptionWiFi",
+ IDS_SETTINGS_INTERNET_TETHER_CONNECTION_DESCRIPTION_WIFI},
+ {"tetherConnectionNotNowButton",
+ IDS_SETTINGS_INTERNET_TETHER_CONNECTION_NOT_NOW_BUTTON},
+ {"tetherConnectionConnectButton",
+ IDS_SETTINGS_INTERNET_TETHER_CONNECTION_CONNECT_BUTTON},
+ {"tetherEnableBluetooth", IDS_ENABLE_BLUETOOTH},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ chromeos::network_element::AddLocalizedStrings(html_source);
+ chromeos::network_element::AddOncLocalizedStrings(html_source);
+ chromeos::network_element::AddDetailsLocalizedStrings(html_source);
+ chromeos::network_element::AddConfigLocalizedStrings(html_source);
+ chromeos::network_element::AddErrorLocalizedStrings(html_source);
+
+ html_source->AddString("networkGoogleNameserversLearnMoreUrl",
+ chrome::kGoogleNameserversLearnMoreURL);
+ html_source->AddString(
+ "internetNoNetworksMobileData",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_INTERNET_LOOKING_FOR_MOBILE_NETWORK,
+ GetHelpUrlWithBoard(chrome::kInstantTetheringLearnMoreURL)));
+}
+
+void InternetStringsProvider::OnDeviceStateListChanged() {
+ FetchDeviceList();
+}
+
+void InternetStringsProvider::FetchDeviceList() {
+ cros_network_config_->GetDeviceStateList(base::BindOnce(
+ &InternetStringsProvider::OnDeviceList, base::Unretained(this)));
+}
+
+void InternetStringsProvider::OnDeviceList(
+ std::vector<network_config::mojom::DeviceStatePropertiesPtr> devices) {
+ // Start with no search tags.
+ delegate()->RemoveSearchTags(GetEthernetSearchConcepts());
+ delegate()->RemoveSearchTags(GetWifiSearchConcepts());
+
+ // Add a search tag each time we see a device type.
+ for (const auto& device : devices) {
+ if (device->type == network_config::mojom::NetworkType::kEthernet)
+ delegate()->AddSearchTags(GetEthernetSearchConcepts());
+ else if (device->type == network_config::mojom::NetworkType::kWiFi)
+ delegate()->AddSearchTags(GetWifiSearchConcepts());
+ }
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/internet_strings_provider.h b/chromium/chrome/browser/ui/webui/settings/chromeos/internet_strings_provider.h
new file mode 100644
index 00000000000..4a0e2a2511e
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/internet_strings_provider.h
@@ -0,0 +1,59 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_INTERNET_STRINGS_PROVIDER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_INTERNET_STRINGS_PROVIDER_H_
+
+#include <vector>
+
+#include "chrome/browser/ui/webui/settings/chromeos/os_settings_per_page_strings_provider.h"
+#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/bindings/remote.h"
+
+class Profile;
+
+namespace content {
+class WebUIDataSource;
+} // namespace content
+
+namespace chromeos {
+namespace settings {
+
+class InternetStringsProvider
+ : public OsSettingsPerPageStringsProvider,
+ public network_config::mojom::CrosNetworkConfigObserver {
+ public:
+ InternetStringsProvider(Profile* profile, Delegate* per_page_delegate);
+ ~InternetStringsProvider() override;
+
+ private:
+ // OsSettingsPerPageStringsProvider:
+ void AddUiStrings(content::WebUIDataSource* html_source) const override;
+
+ // network_config::mojom::CrosNetworkConfigObserver:
+ void OnActiveNetworksChanged(
+ std::vector<network_config::mojom::NetworkStatePropertiesPtr> networks)
+ override {}
+ void OnNetworkStateChanged(
+ chromeos::network_config::mojom::NetworkStatePropertiesPtr network)
+ override {}
+ void OnNetworkStateListChanged() override {}
+ void OnVpnProvidersChanged() override {}
+ void OnNetworkCertificatesChanged() override {}
+ void OnDeviceStateListChanged() override;
+
+ void FetchDeviceList();
+ void OnDeviceList(
+ std::vector<network_config::mojom::DeviceStatePropertiesPtr> devices);
+
+ mojo::Receiver<network_config::mojom::CrosNetworkConfigObserver> receiver_{
+ this};
+ mojo::Remote<network_config::mojom::CrosNetworkConfig> cros_network_config_;
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_INTERNET_STRINGS_PROVIDER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h
index 8ee0b692ac1..a103760bd1e 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h
@@ -13,7 +13,7 @@
#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
#include "chromeos/components/multidevice/remote_device_ref.h"
#include "chromeos/services/multidevice_setup/public/cpp/multidevice_setup_client.h"
-#include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h"
+#include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom-forward.h"
#include "components/prefs/pref_change_registrar.h"
class PrefService;
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.cc
new file mode 100644
index 00000000000..653188ccf20
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.cc
@@ -0,0 +1,2136 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.h"
+
+#include "ash/public/cpp/ash_features.h"
+#include "ash/public/mojom/assistant_state_controller.mojom.h"
+#include "base/command_line.h"
+#include "base/feature_list.h"
+#include "base/i18n/number_formatting.h"
+#include "base/no_destructor.h"
+#include "base/strings/strcat.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/system/sys_info.h"
+#include "build/branding_buildflags.h"
+#include "build/build_config.h"
+#include "build/buildflag.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/browser_process_platform_part.h"
+#include "chrome/browser/chromeos/account_manager/account_manager_util.h"
+#include "chrome/browser/chromeos/arc/arc_util.h"
+#include "chrome/browser/chromeos/assistant/assistant_util.h"
+#include "chrome/browser/chromeos/crostini/crostini_features.h"
+#include "chrome/browser/chromeos/crostini/crostini_util.h"
+#include "chrome/browser/chromeos/kerberos/kerberos_credentials_manager.h"
+#include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.h"
+#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
+#include "chrome/browser/policy/profile_policy_connector.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/supervised_user/supervised_user_service.h"
+#include "chrome/browser/supervised_user/supervised_user_service_factory.h"
+#include "chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.h"
+#include "chrome/browser/ui/webui/chromeos/bluetooth_dialog_localized_strings_provider.h"
+#include "chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.h"
+#include "chrome/browser/ui/webui/chromeos/smb_shares/smb_shares_localized_strings_provider.h"
+#include "chrome/browser/ui/webui/management_ui.h"
+#include "chrome/browser/ui/webui/policy_indicator_localized_strings_provider.h"
+#include "chrome/browser/ui/webui/settings/chromeos/internet_strings_provider.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/search_concept.h"
+#include "chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.h"
+#include "chrome/browser/ui/webui/webui_util.h"
+#include "chrome/common/chrome_features.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/common/webui_url_constants.h"
+#include "chrome/grit/chromium_strings.h"
+#include "chrome/grit/generated_resources.h"
+#include "chrome/grit/locale_settings.h"
+#include "chrome/services/local_search_service/public/mojom/types.mojom.h"
+#include "chromeos/constants/chromeos_features.h"
+#include "chromeos/constants/chromeos_switches.h"
+#include "chromeos/services/assistant/public/features.h"
+#include "chromeos/services/multidevice_setup/public/cpp/url_provider.h"
+#include "chromeos/strings/grit/chromeos_strings.h"
+#include "components/google/core/common/google_util.h"
+#include "components/prefs/pref_service.h"
+#include "components/strings/grit/components_strings.h"
+#include "components/version_ui/version_ui_constants.h"
+#include "content/public/browser/web_ui_data_source.h"
+#include "content/public/common/content_features.h"
+#include "content/public/common/content_switches.h"
+#include "device/bluetooth/strings/grit/bluetooth_strings.h"
+#include "media/base/media_switches.h"
+#include "ui/accessibility/accessibility_switches.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/webui/web_ui_util.h"
+#include "ui/chromeos/devicetype_utils.h"
+#include "ui/chromeos/events/keyboard_layout_util.h"
+#include "ui/display/display_features.h"
+#include "ui/display/display_switches.h"
+#include "ui/display/manager/touch_device_manager.h"
+
+namespace chromeos {
+namespace settings {
+namespace {
+
+std::vector<local_search_service::mojom::DataPtr> ConceptVectorToDataPtrVector(
+ const std::vector<SearchConcept>& tags_group) {
+ std::vector<local_search_service::mojom::DataPtr> data_list;
+
+ for (const auto& concept : tags_group) {
+ std::vector<base::string16> search_tags;
+
+ // Add the canonical tag.
+ search_tags.push_back(
+ l10n_util::GetStringUTF16(concept.canonical_message_id));
+
+ // Add all alternate tags.
+ for (size_t i = 0; i < SearchConcept::kMaxAltTagsPerConcept; ++i) {
+ int curr_alt_tag = concept.alt_tag_ids[i];
+ if (curr_alt_tag == SearchConcept::kAltTagEnd)
+ break;
+ search_tags.push_back(l10n_util::GetStringUTF16(curr_alt_tag));
+ }
+
+ // Note: A stringified version of the canonical tag message ID is used as
+ // the identifier for this search data.
+ data_list.push_back(local_search_service::mojom::Data::New(
+ base::NumberToString(concept.canonical_message_id), search_tags));
+ }
+
+ return data_list;
+}
+
+// Generates a Google Help URL which includes a "board type" parameter. Some
+// help pages need to be adjusted depending on the type of CrOS device that is
+// accessing the page.
+base::string16 GetHelpUrlWithBoard(const std::string& original_url) {
+ return base::ASCIIToUTF16(original_url +
+ "&b=" + base::SysInfo::GetLsbReleaseBoard());
+}
+
+bool IsDeviceManaged() {
+ policy::BrowserPolicyConnectorChromeOS* connector =
+ g_browser_process->platform_part()->browser_policy_connector_chromeos();
+ return connector->IsEnterpriseManaged();
+}
+
+bool IsProfileManaged(Profile* profile) {
+ return profile->GetProfilePolicyConnector()->IsManaged();
+}
+
+void AddCommonStrings(content::WebUIDataSource* html_source, Profile* profile) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"add", IDS_ADD},
+ {"advancedPageTitle", IDS_SETTINGS_ADVANCED},
+ {"back", IDS_ACCNAME_BACK},
+ {"basicPageTitle", IDS_SETTINGS_BASIC},
+ {"cancel", IDS_CANCEL},
+ {"clear", IDS_SETTINGS_CLEAR},
+ {"close", IDS_CLOSE},
+ {"confirm", IDS_CONFIRM},
+ {"continue", IDS_SETTINGS_CONTINUE},
+ {"controlledByExtension", IDS_SETTINGS_CONTROLLED_BY_EXTENSION},
+ {"custom", IDS_SETTINGS_CUSTOM},
+ {"delete", IDS_SETTINGS_DELETE},
+ {"deviceOff", IDS_SETTINGS_DEVICE_OFF},
+ {"deviceOn", IDS_SETTINGS_DEVICE_ON},
+ {"disable", IDS_DISABLE},
+ {"done", IDS_DONE},
+ {"edit", IDS_SETTINGS_EDIT},
+ {"extensionsLinkTooltip", IDS_SETTINGS_MENU_EXTENSIONS_LINK_TOOLTIP},
+ {"learnMore", IDS_LEARN_MORE},
+ {"menu", IDS_MENU},
+ {"menuButtonLabel", IDS_SETTINGS_MENU_BUTTON_LABEL},
+ {"moreActions", IDS_SETTINGS_MORE_ACTIONS},
+ {"ok", IDS_OK},
+ {"restart", IDS_SETTINGS_RESTART},
+ {"save", IDS_SAVE},
+ {"searchResultBubbleText", IDS_SEARCH_RESULT_BUBBLE_TEXT},
+ {"searchResultsBubbleText", IDS_SEARCH_RESULTS_BUBBLE_TEXT},
+ {"settings", IDS_SETTINGS_SETTINGS},
+ {"settingsAltPageTitle", IDS_SETTINGS_ALT_PAGE_TITLE},
+ {"subpageArrowRoleDescription", IDS_SETTINGS_SUBPAGE_BUTTON},
+ {"notValidWebAddress", IDS_SETTINGS_NOT_VALID_WEB_ADDRESS},
+ {"notValidWebAddressForContentType",
+ IDS_SETTINGS_NOT_VALID_WEB_ADDRESS_FOR_CONTENT_TYPE},
+
+ // Common font related strings shown in a11y and appearance sections.
+ {"quickBrownFox", IDS_SETTINGS_QUICK_BROWN_FOX},
+ {"verySmall", IDS_SETTINGS_VERY_SMALL_FONT},
+ {"small", IDS_SETTINGS_SMALL_FONT},
+ {"medium", IDS_SETTINGS_MEDIUM_FONT},
+ {"large", IDS_SETTINGS_LARGE_FONT},
+ {"veryLarge", IDS_SETTINGS_VERY_LARGE_FONT},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddBoolean(
+ "isGuest",
+ user_manager::UserManager::Get()->IsLoggedInAsGuest() ||
+ user_manager::UserManager::Get()->IsLoggedInAsPublicAccount());
+
+ html_source->AddBoolean("isSupervised", profile->IsSupervised());
+}
+
+void AddA11yStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"a11yPageTitle", IDS_SETTINGS_ACCESSIBILITY},
+ {"a11yWebStore", IDS_SETTINGS_ACCESSIBILITY_WEB_STORE},
+ {"moreFeaturesLinkDescription",
+ IDS_SETTINGS_MORE_FEATURES_LINK_DESCRIPTION},
+ {"accessibleImageLabelsTitle",
+ IDS_SETTINGS_ACCESSIBLE_IMAGE_LABELS_TITLE},
+ {"accessibleImageLabelsSubtitle",
+ IDS_SETTINGS_ACCESSIBLE_IMAGE_LABELS_SUBTITLE},
+ {"settingsSliderRoleDescription",
+ IDS_SETTINGS_SLIDER_MIN_MAX_ARIA_ROLE_DESCRIPTION},
+ {"manageAccessibilityFeatures",
+ IDS_SETTINGS_ACCESSIBILITY_MANAGE_ACCESSIBILITY_FEATURES},
+ {"optionsInMenuLabel", IDS_SETTINGS_OPTIONS_IN_MENU_LABEL},
+ {"largeMouseCursorLabel", IDS_SETTINGS_LARGE_MOUSE_CURSOR_LABEL},
+ {"largeMouseCursorSizeLabel", IDS_SETTINGS_LARGE_MOUSE_CURSOR_SIZE_LABEL},
+ {"largeMouseCursorSizeDefaultLabel",
+ IDS_SETTINGS_LARGE_MOUSE_CURSOR_SIZE_DEFAULT_LABEL},
+ {"largeMouseCursorSizeLargeLabel",
+ IDS_SETTINGS_LARGE_MOUSE_CURSOR_SIZE_LARGE_LABEL},
+ {"highContrastLabel", IDS_SETTINGS_HIGH_CONTRAST_LABEL},
+ {"stickyKeysLabel", IDS_SETTINGS_STICKY_KEYS_LABEL},
+ {"chromeVoxLabel", IDS_SETTINGS_CHROMEVOX_LABEL},
+ {"chromeVoxOptionsLabel", IDS_SETTINGS_CHROMEVOX_OPTIONS_LABEL},
+ {"screenMagnifierLabel", IDS_SETTINGS_SCREEN_MAGNIFIER_LABEL},
+ {"screenMagnifierZoomLabel", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_LABEL},
+ {"dockedMagnifierLabel", IDS_SETTINGS_DOCKED_MAGNIFIER_LABEL},
+ {"dockedMagnifierZoomLabel", IDS_SETTINGS_DOCKED_MAGNIFIER_ZOOM_LABEL},
+ {"screenMagnifierZoom2x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_2_X},
+ {"screenMagnifierZoom4x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_4_X},
+ {"screenMagnifierZoom6x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_6_X},
+ {"screenMagnifierZoom8x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_8_X},
+ {"screenMagnifierZoom10x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_10_X},
+ {"screenMagnifierZoom12x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_12_X},
+ {"screenMagnifierZoom14x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_14_X},
+ {"screenMagnifierZoom16x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_16_X},
+ {"screenMagnifierZoom18x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_18_X},
+ {"screenMagnifierZoom20x", IDS_SETTINGS_SCREEN_MAGNIFIER_ZOOM_20_X},
+ {"tapDraggingLabel", IDS_SETTINGS_TAP_DRAGGING_LABEL},
+ {"clickOnStopLabel", IDS_SETTINGS_CLICK_ON_STOP_LABEL},
+ {"delayBeforeClickLabel", IDS_SETTINGS_DELAY_BEFORE_CLICK_LABEL},
+ {"delayBeforeClickExtremelyShort",
+ IDS_SETTINGS_DELAY_BEFORE_CLICK_EXTREMELY_SHORT},
+ {"delayBeforeClickVeryShort", IDS_SETTINGS_DELAY_BEFORE_CLICK_VERY_SHORT},
+ {"delayBeforeClickShort", IDS_SETTINGS_DELAY_BEFORE_CLICK_SHORT},
+ {"delayBeforeClickLong", IDS_SETTINGS_DELAY_BEFORE_CLICK_LONG},
+ {"delayBeforeClickVeryLong", IDS_SETTINGS_DELAY_BEFORE_CLICK_VERY_LONG},
+ {"autoclickRevertToLeftClick",
+ IDS_SETTINGS_AUTOCLICK_REVERT_TO_LEFT_CLICK},
+ {"autoclickStabilizeCursorPosition",
+ IDS_SETTINGS_AUTOCLICK_STABILIZE_CURSOR_POSITION},
+ {"autoclickMovementThresholdLabel",
+ IDS_SETTINGS_AUTOCLICK_MOVEMENT_THRESHOLD_LABEL},
+ {"autoclickMovementThresholdExtraSmall",
+ IDS_SETTINGS_AUTOCLICK_MOVEMENT_THRESHOLD_EXTRA_SMALL},
+ {"autoclickMovementThresholdSmall",
+ IDS_SETTINGS_AUTOCLICK_MOVEMENT_THRESHOLD_SMALL},
+ {"autoclickMovementThresholdDefault",
+ IDS_SETTINGS_AUTOCLICK_MOVEMENT_THRESHOLD_DEFAULT},
+ {"autoclickMovementThresholdLarge",
+ IDS_SETTINGS_AUTOCLICK_MOVEMENT_THRESHOLD_LARGE},
+ {"autoclickMovementThresholdExtraLarge",
+ IDS_SETTINGS_AUTOCLICK_MOVEMENT_THRESHOLD_EXTRA_LARGE},
+ {"dictationDescription",
+ IDS_SETTINGS_ACCESSIBILITY_DICTATION_DESCRIPTION},
+ {"dictationLabel", IDS_SETTINGS_ACCESSIBILITY_DICTATION_LABEL},
+ {"onScreenKeyboardLabel", IDS_SETTINGS_ON_SCREEN_KEYBOARD_LABEL},
+ {"monoAudioLabel", IDS_SETTINGS_MONO_AUDIO_LABEL},
+ {"startupSoundLabel", IDS_SETTINGS_STARTUP_SOUND_LABEL},
+ {"a11yExplanation", IDS_SETTINGS_ACCESSIBILITY_EXPLANATION},
+ {"caretHighlightLabel",
+ IDS_SETTINGS_ACCESSIBILITY_CARET_HIGHLIGHT_DESCRIPTION},
+ {"cursorHighlightLabel",
+ IDS_SETTINGS_ACCESSIBILITY_CURSOR_HIGHLIGHT_DESCRIPTION},
+ {"focusHighlightLabel",
+ IDS_SETTINGS_ACCESSIBILITY_FOCUS_HIGHLIGHT_DESCRIPTION},
+ {"selectToSpeakTitle", IDS_SETTINGS_ACCESSIBILITY_SELECT_TO_SPEAK_TITLE},
+ {"selectToSpeakDisabledDescription",
+ IDS_SETTINGS_ACCESSIBILITY_SELECT_TO_SPEAK_DISABLED_DESCRIPTION},
+ {"selectToSpeakDescription",
+ IDS_SETTINGS_ACCESSIBILITY_SELECT_TO_SPEAK_DESCRIPTION},
+ {"selectToSpeakDescriptionWithoutKeyboard",
+ IDS_SETTINGS_ACCESSIBILITY_SELECT_TO_SPEAK_DESCRIPTION_WITHOUT_KEYBOARD},
+ {"selectToSpeakOptionsLabel",
+ IDS_SETTINGS_ACCESSIBILITY_SELECT_TO_SPEAK_OPTIONS_LABEL},
+ {"switchAccessLabel",
+ IDS_SETTINGS_ACCESSIBILITY_SWITCH_ACCESS_DESCRIPTION},
+ {"switchAccessOptionsLabel",
+ IDS_SETTINGS_ACCESSIBILITY_SWITCH_ACCESS_OPTIONS_LABEL},
+ {"manageSwitchAccessSettings",
+ IDS_SETTINGS_MANAGE_SWITCH_ACCESS_SETTINGS},
+ {"switchAssignmentHeading", IDS_SETTINGS_SWITCH_ASSIGNMENT_HEADING},
+ {"switchAssignOptionNone", IDS_SETTINGS_SWITCH_ASSIGN_OPTION_NONE},
+ {"switchAssignOptionSpace", IDS_SETTINGS_SWITCH_ASSIGN_OPTION_SPACE},
+ {"switchAssignOptionEnter", IDS_SETTINGS_SWITCH_ASSIGN_OPTION_ENTER},
+ {"assignSelectSwitchLabel", IDS_SETTINGS_ASSIGN_SELECT_SWITCH_LABEL},
+ {"assignNextSwitchLabel", IDS_SETTINGS_ASSIGN_NEXT_SWITCH_LABEL},
+ {"assignPreviousSwitchLabel", IDS_SETTINGS_ASSIGN_PREVIOUS_SWITCH_LABEL},
+ {"switchAccessAutoScanHeading",
+ IDS_SETTINGS_SWITCH_ACCESS_AUTO_SCAN_HEADING},
+ {"switchAccessAutoScanLabel", IDS_SETTINGS_SWITCH_ACCESS_AUTO_SCAN_LABEL},
+ {"switchAccessAutoScanSpeedLabel",
+ IDS_SETTINGS_SWITCH_ACCESS_AUTO_SCAN_SPEED_LABEL},
+ {"switchAccessAutoScanKeyboardSpeedLabel",
+ IDS_SETTINGS_SWITCH_ACCESS_AUTO_SCAN_KEYBOARD_SPEED_LABEL},
+ {"durationInSeconds", IDS_SETTINGS_DURATION_IN_SECONDS},
+ {"manageAccessibilityFeatures",
+ IDS_SETTINGS_ACCESSIBILITY_MANAGE_ACCESSIBILITY_FEATURES},
+ {"textToSpeechHeading",
+ IDS_SETTINGS_ACCESSIBILITY_TEXT_TO_SPEECH_HEADING},
+ {"displayHeading", IDS_SETTINGS_ACCESSIBILITY_DISPLAY_HEADING},
+ {"displaySettingsTitle",
+ IDS_SETTINGS_ACCESSIBILITY_DISPLAY_SETTINGS_TITLE},
+ {"displaySettingsDescription",
+ IDS_SETTINGS_ACCESSIBILITY_DISPLAY_SETTINGS_DESCRIPTION},
+ {"appearanceSettingsTitle",
+ IDS_SETTINGS_ACCESSIBILITY_APPEARANCE_SETTINGS_TITLE},
+ {"appearanceSettingsDescription",
+ IDS_SETTINGS_ACCESSIBILITY_APPEARANCE_SETTINGS_DESCRIPTION},
+ {"keyboardAndTextInputHeading",
+ IDS_SETTINGS_ACCESSIBILITY_KEYBOARD_AND_TEXT_INPUT_HEADING},
+ {"keyboardSettingsTitle",
+ IDS_SETTINGS_ACCESSIBILITY_KEYBOARD_SETTINGS_TITLE},
+ {"keyboardSettingsDescription",
+ IDS_SETTINGS_ACCESSIBILITY_KEYBOARD_SETTINGS_DESCRIPTION},
+ {"mouseAndTouchpadHeading",
+ IDS_SETTINGS_ACCESSIBILITY_MOUSE_AND_TOUCHPAD_HEADING},
+ {"mouseSettingsTitle", IDS_SETTINGS_ACCESSIBILITY_MOUSE_SETTINGS_TITLE},
+ {"mouseSettingsDescription",
+ IDS_SETTINGS_ACCESSIBILITY_MOUSE_SETTINGS_DESCRIPTION},
+ {"audioAndCaptionsHeading",
+ IDS_SETTINGS_ACCESSIBILITY_AUDIO_AND_CAPTIONS_HEADING},
+ {"additionalFeaturesTitle",
+ IDS_SETTINGS_ACCESSIBILITY_ADDITIONAL_FEATURES_TITLE},
+ {"manageTtsSettings", IDS_SETTINGS_MANAGE_TTS_SETTINGS},
+ {"ttsSettingsLinkDescription", IDS_SETTINGS_TTS_LINK_DESCRIPTION},
+ {"textToSpeechVoices", IDS_SETTINGS_TEXT_TO_SPEECH_VOICES},
+ {"textToSpeechNoVoicesMessage",
+ IDS_SETTINGS_TEXT_TO_SPEECH_NO_VOICES_MESSAGE},
+ {"textToSpeechMoreLanguages", IDS_SETTINGS_TEXT_TO_SPEECH_MORE_LANGUAGES},
+ {"textToSpeechProperties", IDS_SETTINGS_TEXT_TO_SPEECH_PROPERTIES},
+ {"textToSpeechRate", IDS_SETTINGS_TEXT_TO_SPEECH_RATE},
+ {"textToSpeechRateMinimumLabel",
+ IDS_SETTINGS_TEXT_TO_SPEECH_RATE_MINIMUM_LABEL},
+ {"textToSpeechRateMaximumLabel",
+ IDS_SETTINGS_TEXT_TO_SPEECH_RATE_MAXIMUM_LABEL},
+ {"textToSpeechPitch", IDS_SETTINGS_TEXT_TO_SPEECH_PITCH},
+ {"textToSpeechPitchMinimumLabel",
+ IDS_SETTINGS_TEXT_TO_SPEECH_PITCH_MINIMUM_LABEL},
+ {"textToSpeechPitchMaximumLabel",
+ IDS_SETTINGS_TEXT_TO_SPEECH_PITCH_MAXIMUM_LABEL},
+ {"textToSpeechVolume", IDS_SETTINGS_TEXT_TO_SPEECH_VOLUME},
+ {"textToSpeechVolumeMinimumLabel",
+ IDS_SETTINGS_TEXT_TO_SPEECH_VOLUME_MINIMUM_LABEL},
+ {"textToSpeechVolumeMaximumLabel",
+ IDS_SETTINGS_TEXT_TO_SPEECH_VOLUME_MAXIMUM_LABEL},
+ {"percentage", IDS_SETTINGS_PERCENTAGE},
+ {"defaultPercentage", IDS_SETTINGS_DEFAULT_PERCENTAGE},
+ {"textToSpeechPreviewHeading",
+ IDS_SETTINGS_TEXT_TO_SPEECH_PREVIEW_HEADING},
+ {"textToSpeechPreviewInputLabel",
+ IDS_SETTINGS_TEXT_TO_SPEECH_PREVIEW_INPUT_LABEL},
+ {"textToSpeechPreviewInput", IDS_SETTINGS_TEXT_TO_SPEECH_PREVIEW_INPUT},
+ {"textToSpeechPreviewVoice", IDS_SETTINGS_TEXT_TO_SPEECH_PREVIEW_VOICE},
+ {"textToSpeechPreviewPlay", IDS_SETTINGS_TEXT_TO_SPEECH_PREVIEW_PLAY},
+ {"textToSpeechEngines", IDS_SETTINGS_TEXT_TO_SPEECH_ENGINES},
+ {"tabletModeShelfNavigationButtonsSettingLabel",
+ IDS_SETTINGS_A11Y_TABLET_MODE_SHELF_BUTTONS_LABEL},
+ {"tabletModeShelfNavigationButtonsSettingDescription",
+ IDS_SETTINGS_A11Y_TABLET_MODE_SHELF_BUTTONS_DESCRIPTION},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddString("accountManagerLearnMoreUrl",
+ chrome::kAccountManagerLearnMoreURL);
+ html_source->AddString("a11yLearnMoreUrl",
+ chrome::kChromeAccessibilityHelpURL);
+
+ base::CommandLine& cmd = *base::CommandLine::ForCurrentProcess();
+ html_source->AddBoolean(
+ "showExperimentalAccessibilitySwitchAccess",
+ cmd.HasSwitch(::switches::kEnableExperimentalAccessibilitySwitchAccess));
+
+ html_source->AddBoolean(
+ "showExperimentalAccessibilitySwitchAccessImprovedTextInput",
+ cmd.HasSwitch(
+ ::switches::kEnableExperimentalAccessibilitySwitchAccessText));
+
+ html_source->AddBoolean("showExperimentalA11yLabels",
+ base::FeatureList::IsEnabled(
+ ::features::kExperimentalAccessibilityLabels));
+
+ html_source->AddBoolean(
+ "showTabletModeShelfNavigationButtonsSettings",
+ ash::features::IsHideShelfControlsInTabletModeEnabled());
+
+ html_source->AddString("tabletModeShelfNavigationButtonsLearnMoreUrl",
+ chrome::kTabletModeGesturesLearnMoreURL);
+
+ html_source->AddBoolean("enableLiveCaption",
+ base::FeatureList::IsEnabled(media::kLiveCaption));
+
+ ::settings::AddCaptionSubpageStrings(html_source);
+}
+
+void AddLanguagesStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"orderLanguagesInstructions",
+ IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_ORDERING_INSTRUCTIONS},
+ {"osLanguagesPageTitle", IDS_OS_SETTINGS_LANGUAGES_AND_INPUT_PAGE_TITLE},
+ {"osLanguagesListTitle", IDS_OS_SETTINGS_LANGUAGES_LIST_TITLE},
+ {"inputMethodsListTitle",
+ IDS_SETTINGS_LANGUAGES_INPUT_METHODS_LIST_TITLE},
+ {"inputMethodEnabled", IDS_SETTINGS_LANGUAGES_INPUT_METHOD_ENABLED},
+ {"inputMethodsExpandA11yLabel",
+ IDS_SETTINGS_LANGUAGES_INPUT_METHODS_EXPAND_ACCESSIBILITY_LABEL},
+ {"inputMethodsManagedbyPolicy",
+ IDS_SETTINGS_LANGUAGES_INPUT_METHODS_MANAGED_BY_POLICY},
+ {"manageInputMethods", IDS_SETTINGS_LANGUAGES_INPUT_METHODS_MANAGE},
+ {"manageInputMethodsPageTitle",
+ IDS_SETTINGS_LANGUAGES_MANAGE_INPUT_METHODS_TITLE},
+ {"showImeMenu", IDS_SETTINGS_LANGUAGES_SHOW_IME_MENU},
+ {"displayLanguageRestart",
+ IDS_SETTINGS_LANGUAGES_RESTART_TO_DISPLAY_LANGUAGE},
+ {"moveDown", IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_MOVE_DOWN},
+ {"displayInThisLanguage",
+ IDS_SETTINGS_LANGUAGES_DISPLAY_IN_THIS_LANGUAGE},
+ {"searchLanguages", IDS_SETTINGS_LANGUAGE_SEARCH},
+ {"addLanguagesDialogTitle",
+ IDS_SETTINGS_LANGUAGES_MANAGE_LANGUAGES_TITLE},
+ {"moveToTop", IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_MOVE_TO_TOP},
+ {"isDisplayedInThisLanguage",
+ IDS_SETTINGS_LANGUAGES_IS_DISPLAYED_IN_THIS_LANGUAGE},
+ {"removeLanguage", IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_REMOVE},
+ {"addLanguages", IDS_SETTINGS_LANGUAGES_LANGUAGES_ADD},
+ {"moveUp", IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_MOVE_UP},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddString(
+ "languagesLearnMoreURL",
+ base::ASCIIToUTF16(chrome::kLanguageSettingsLearnMoreUrl));
+}
+
+void AddPersonalizationStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"ambientModeTitle", IDS_OS_SETTINGS_AMBIENT_MODE_TITLE},
+ {"ambientModeEnabled", IDS_OS_SETTINGS_AMBIENT_MODE_ENABLED},
+ {"ambientModeDisabled", IDS_OS_SETTINGS_AMBIENT_MODE_DISABLED},
+ {"ambientModeOn", IDS_OS_SETTINGS_AMBIENT_MODE_ON},
+ {"ambientModeOff", IDS_OS_SETTINGS_AMBIENT_MODE_OFF},
+ {"ambientModeTopicSourceTitle",
+ IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_TITLE},
+ {"ambientModeTopicSourceGooglePhotos",
+ IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_GOOGLE_PHOTOS},
+ {"ambientModeTopicSourceArtGallery",
+ IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_ART_GALLERY},
+ {"changePictureTitle", IDS_OS_SETTINGS_CHANGE_PICTURE_TITLE},
+ {"openWallpaperApp", IDS_OS_SETTINGS_OPEN_WALLPAPER_APP},
+ {"personalizationPageTitle", IDS_OS_SETTINGS_PERSONALIZATION},
+ {"setWallpaper", IDS_OS_SETTINGS_SET_WALLPAPER},
+ {"takePhoto", IDS_SETTINGS_CHANGE_PICTURE_TAKE_PHOTO},
+ {"captureVideo", IDS_SETTINGS_CHANGE_PICTURE_CAPTURE_VIDEO},
+ {"discardPhoto", IDS_SETTINGS_CHANGE_PICTURE_DISCARD_PHOTO},
+ {"previewAltText", IDS_SETTINGS_CHANGE_PICTURE_PREVIEW_ALT},
+ {"switchModeToVideo", IDS_SETTINGS_CHANGE_PICTURE_SWITCH_MODE_TO_VIDEO},
+ {"profilePhoto", IDS_SETTINGS_CHANGE_PICTURE_PROFILE_PHOTO},
+ {"changePicturePageDescription", IDS_SETTINGS_CHANGE_PICTURE_DIALOG_TEXT},
+ {"switchModeToCamera", IDS_SETTINGS_CHANGE_PICTURE_SWITCH_MODE_TO_CAMERA},
+ {"chooseFile", IDS_SETTINGS_CHANGE_PICTURE_CHOOSE_FILE},
+ {"oldPhoto", IDS_SETTINGS_CHANGE_PICTURE_OLD_PHOTO},
+ {"oldVideo", IDS_SETTINGS_CHANGE_PICTURE_OLD_VIDEO},
+ {"authorCreditText", IDS_SETTINGS_CHANGE_PICTURE_AUTHOR_CREDIT_TEXT},
+ {"photoCaptureAccessibleText",
+ IDS_SETTINGS_PHOTO_CAPTURE_ACCESSIBLE_TEXT},
+ {"photoDiscardAccessibleText",
+ IDS_SETTINGS_PHOTO_DISCARD_ACCESSIBLE_TEXT},
+ {"photoModeAccessibleText", IDS_SETTINGS_PHOTO_MODE_ACCESSIBLE_TEXT},
+ {"videoModeAccessibleText", IDS_SETTINGS_VIDEO_MODE_ACCESSIBLE_TEXT},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddBoolean(
+ "changePictureVideoModeEnabled",
+ base::FeatureList::IsEnabled(::features::kChangePictureVideoMode));
+ html_source->AddBoolean("isAmbientModeEnabled",
+ chromeos::features::IsAmbientModeEnabled());
+}
+
+void AddFingerprintListStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"lockScreenAddFingerprint",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_ADD_FINGERPRINT_BUTTON},
+ {"lockScreenRegisteredFingerprints",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_REGISTERED_FINGERPRINTS_LABEL},
+ {"lockScreenFingerprintWarning",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_FINGERPRINT_LESS_SECURE},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+}
+
+void AddSetupPinDialogStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"configurePinChoosePinTitle",
+ IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_CHOOSE_PIN_TITLE},
+ {"configurePinConfirmPinTitle",
+ IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_CONFIRM_PIN_TITLE},
+ {"configurePinMismatched", IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_MISMATCHED},
+ {"configurePinTooShort", IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_TOO_SHORT},
+ {"configurePinTooLong", IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_TOO_LONG},
+ {"configurePinWeakPin", IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_WEAK_PIN},
+ {"pinKeyboardPlaceholderPin", IDS_PIN_KEYBOARD_HINT_TEXT_PIN},
+ {"pinKeyboardPlaceholderPinPassword",
+ IDS_PIN_KEYBOARD_HINT_TEXT_PIN_PASSWORD},
+ {"pinKeyboardDeleteAccessibleName",
+ IDS_PIN_KEYBOARD_DELETE_ACCESSIBLE_NAME},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ // Format numbers to be used on the pin keyboard.
+ for (int j = 0; j <= 9; j++) {
+ html_source->AddString("pinKeyboard" + base::NumberToString(j),
+ base::FormatNumber(int64_t{j}));
+ }
+}
+
+void AddSetupFingerprintDialogStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"configureFingerprintTitle", IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_TITLE},
+ {"configureFingerprintAddAnotherButton",
+ IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_ADD_ANOTHER_BUTTON},
+ {"configureFingerprintInstructionReadyStep",
+ IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_READY},
+ {"configureFingerprintLiftFinger",
+ IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_LIFT_FINGER},
+ {"configureFingerprintTryAgain",
+ IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_TRY_AGAIN},
+ {"configureFingerprintImmobile",
+ IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_FINGER_IMMOBILE},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+}
+
+void AddFingerprintStrings(content::WebUIDataSource* html_source) {
+ int instruction_id, aria_label_id;
+ using FingerprintLocation = chromeos::quick_unlock::FingerprintLocation;
+ switch (chromeos::quick_unlock::GetFingerprintLocation()) {
+ case FingerprintLocation::TABLET_POWER_BUTTON:
+ instruction_id =
+ IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_POWER_BUTTON;
+ aria_label_id =
+ IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_POWER_BUTTON_ARIA_LABEL;
+ break;
+ case FingerprintLocation::KEYBOARD_BOTTOM_LEFT:
+ instruction_id =
+ IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD;
+ aria_label_id =
+ IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD_BOTTOM_LEFT_ARIA_LABEL;
+ break;
+ case FingerprintLocation::KEYBOARD_BOTTOM_RIGHT:
+ instruction_id =
+ IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD;
+ aria_label_id =
+ IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD_BOTTOM_RIGHT_ARIA_LABEL;
+ break;
+ case FingerprintLocation::KEYBOARD_TOP_RIGHT:
+ instruction_id =
+ IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD;
+ aria_label_id =
+ IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_INSTRUCTION_LOCATE_SCANNER_KEYBOARD_TOP_RIGHT_ARIA_LABEL;
+ break;
+ }
+ html_source->AddLocalizedString(
+ "configureFingerprintInstructionLocateScannerStep", instruction_id);
+ html_source->AddLocalizedString("configureFingerprintScannerStepAriaLabel",
+ aria_label_id);
+}
+
+void AddAccountManagerPageStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"accountManagerDescription", IDS_SETTINGS_ACCOUNT_MANAGER_DESCRIPTION},
+ {"accountManagerChildDescription",
+ IDS_SETTINGS_ACCOUNT_MANAGER_CHILD_DESCRIPTION},
+ {"accountListHeader", IDS_SETTINGS_ACCOUNT_MANAGER_LIST_HEADER},
+ {"accountManagerPrimaryAccountTooltip",
+ IDS_SETTINGS_ACCOUNT_MANAGER_PRIMARY_ACCOUNT_TOOLTIP},
+ {"accountManagerEducationAccountLabel",
+ IDS_SETTINGS_ACCOUNT_MANAGER_EDUCATION_ACCOUNT},
+ {"removeAccountLabel", IDS_SETTINGS_ACCOUNT_MANAGER_REMOVE_ACCOUNT_LABEL},
+ {"addAccountLabel", IDS_SETTINGS_ACCOUNT_MANAGER_ADD_ACCOUNT_LABEL},
+ {"addSchoolAccountLabel",
+ IDS_SETTINGS_ACCOUNT_MANAGER_ADD_SCHOOL_ACCOUNT_LABEL},
+ {"accountManagerSecondaryAccountsDisabledText",
+ IDS_SETTINGS_ACCOUNT_MANAGER_SECONDARY_ACCOUNTS_DISABLED_TEXT},
+ {"accountManagerSecondaryAccountsDisabledChildText",
+ IDS_SETTINGS_ACCOUNT_MANAGER_SECONDARY_ACCOUNTS_DISABLED_CHILD_TEXT},
+ {"accountManagerSignedOutAccountName",
+ IDS_SETTINGS_ACCOUNT_MANAGER_SIGNED_OUT_ACCOUNT_PLACEHOLDER},
+ {"accountManagerUnmigratedAccountName",
+ IDS_SETTINGS_ACCOUNT_MANAGER_UNMIGRATED_ACCOUNT_PLACEHOLDER},
+ {"accountManagerMigrationLabel",
+ IDS_SETTINGS_ACCOUNT_MANAGER_MIGRATION_LABEL},
+ {"accountManagerReauthenticationLabel",
+ IDS_SETTINGS_ACCOUNT_MANAGER_REAUTHENTICATION_LABEL},
+ {"accountManagerMigrationTooltip",
+ IDS_SETTINGS_ACCOUNT_MANAGER_MIGRATION_TOOLTIP},
+ {"accountManagerReauthenticationTooltip",
+ IDS_SETTINGS_ACCOUNT_MANAGER_REAUTHENTICATION_TOOLTIP},
+ {"accountManagerMoreActionsTooltip",
+ IDS_SETTINGS_ACCOUNT_MANAGER_MORE_ACTIONS_TOOLTIP},
+ {"accountManagerManagedLabel",
+ IDS_SETTINGS_ACCOUNT_MANAGER_MANAGEMENT_STATUS_MANAGED_ACCOUNT},
+ {"accountManagerUnmanagedLabel",
+ IDS_SETTINGS_ACCOUNT_MANAGER_MANAGEMENT_STATUS_UNMANAGED_ACCOUNT},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+}
+
+void AddSyncControlsStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"syncEverythingCheckboxLabel",
+ IDS_SETTINGS_SYNC_EVERYTHING_CHECKBOX_LABEL},
+ {"wallpaperCheckboxLabel", IDS_OS_SETTINGS_WALLPAPER_CHECKBOX_LABEL},
+ {"osSyncTurnOff", IDS_OS_SETTINGS_SYNC_TURN_OFF},
+ {"osSyncSettingsCheckboxLabel",
+ IDS_OS_SETTINGS_SYNC_SETTINGS_CHECKBOX_LABEL},
+ {"wifiConfigurationsCheckboxLabel",
+ IDS_SETTINGS_WIFI_CONFIGURATIONS_CHECKBOX_LABEL},
+ {"osSyncAppsCheckboxLabel", IDS_OS_SETTINGS_SYNC_APPS_CHECKBOX_LABEL},
+ {"osSyncTurnOn", IDS_OS_SETTINGS_SYNC_TURN_ON},
+ {"osSyncFeatureLabel", IDS_OS_SETTINGS_SYNC_FEATURE_LABEL},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddString(
+ "browserSettingsSyncSetupUrl",
+ base::StrCat({chrome::kChromeUISettingsURL, chrome::kSyncSetupSubPage}));
+}
+
+void AddCrostiniStrings(content::WebUIDataSource* html_source,
+ Profile* profile) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"crostiniPageTitle", IDS_SETTINGS_CROSTINI_TITLE},
+ {"crostiniPageLabel", IDS_SETTINGS_CROSTINI_LABEL},
+ {"crostiniEnable", IDS_SETTINGS_TURN_ON},
+ {"crostiniSharedPaths", IDS_SETTINGS_CROSTINI_SHARED_PATHS},
+ {"crostiniSharedPathsListHeading",
+ IDS_SETTINGS_CROSTINI_SHARED_PATHS_LIST_HEADING},
+ {"crostiniSharedPathsInstructionsAdd",
+ IDS_SETTINGS_CROSTINI_SHARED_PATHS_INSTRUCTIONS_ADD},
+ {"crostiniSharedPathsInstructionsRemove",
+ IDS_SETTINGS_CROSTINI_SHARED_PATHS_INSTRUCTIONS_REMOVE},
+ {"crostiniSharedPathsRemoveSharing",
+ IDS_SETTINGS_CROSTINI_SHARED_PATHS_REMOVE_SHARING},
+ {"crostiniSharedPathsRemoveFailureDialogMessage",
+ IDS_SETTINGS_CROSTINI_SHARED_PATHS_REMOVE_FAILURE_DIALOG_MESSAGE},
+ {"crostiniSharedPathsRemoveFailureDialogTitle",
+ IDS_SETTINGS_CROSTINI_SHARED_PATHS_REMOVE_FAILURE_DIALOG_TITLE},
+ {"crostiniSharedPathsRemoveFailureTryAgain",
+ IDS_SETTINGS_CROSTINI_SHARED_PATHS_REMOVE_FAILURE_TRY_AGAIN},
+ {"crostiniSharedPathsListEmptyMessage",
+ IDS_SETTINGS_CROSTINI_SHARED_PATHS_LIST_EMPTY_MESSAGE},
+ {"crostiniExportImportTitle", IDS_SETTINGS_CROSTINI_EXPORT_IMPORT_TITLE},
+ {"crostiniExport", IDS_SETTINGS_CROSTINI_EXPORT},
+ {"crostiniExportLabel", IDS_SETTINGS_CROSTINI_EXPORT_LABEL},
+ {"crostiniImport", IDS_SETTINGS_CROSTINI_IMPORT},
+ {"crostiniImportLabel", IDS_SETTINGS_CROSTINI_IMPORT_LABEL},
+ {"crostiniImportConfirmationDialogTitle",
+ IDS_SETTINGS_CROSTINI_CONFIRM_IMPORT_DIALOG_WINDOW_TITLE},
+ {"crostiniImportConfirmationDialogMessage",
+ IDS_SETTINGS_CROSTINI_CONFIRM_IMPORT_DIALOG_WINDOW_MESSAGE},
+ {"crostiniImportConfirmationDialogConfirmationButton",
+ IDS_SETTINGS_CROSTINI_IMPORT},
+ {"crostiniRemoveButton", IDS_SETTINGS_CROSTINI_REMOVE_BUTTON},
+ {"crostiniSharedUsbDevicesLabel",
+ IDS_SETTINGS_CROSTINI_SHARED_USB_DEVICES_LABEL},
+ {"crostiniSharedUsbDevicesDescription",
+ IDS_SETTINGS_CROSTINI_SHARED_USB_DEVICES_DESCRIPTION},
+ {"crostiniSharedUsbDevicesExtraDescription",
+ IDS_SETTINGS_CROSTINI_SHARED_USB_DEVICES_EXTRA_DESCRIPTION},
+ {"crostiniSharedUsbDevicesListEmptyMessage",
+ IDS_SETTINGS_CROSTINI_SHARED_USB_DEVICES_LIST_EMPTY_MESSAGE},
+ {"crostiniArcAdbTitle", IDS_SETTINGS_CROSTINI_ARC_ADB_TITLE},
+ {"crostiniArcAdbDescription", IDS_SETTINGS_CROSTINI_ARC_ADB_DESCRIPTION},
+ {"crostiniArcAdbLabel", IDS_SETTINGS_CROSTINI_ARC_ADB_LABEL},
+ {"crostiniArcAdbRestartButton",
+ IDS_SETTINGS_CROSTINI_ARC_ADB_RESTART_BUTTON},
+ {"crostiniArcAdbConfirmationTitleEnable",
+ IDS_SETTINGS_CROSTINI_ARC_ADB_CONFIRMATION_TITLE_ENABLE},
+ {"crostiniArcAdbConfirmationTitleDisable",
+ IDS_SETTINGS_CROSTINI_ARC_ADB_CONFIRMATION_TITLE_DISABLE},
+ {"crostiniContainerUpgrade",
+ IDS_SETTINGS_CROSTINI_CONTAINER_UPGRADE_MESSAGE},
+ {"crostiniContainerUpgradeSubtext",
+ IDS_SETTINGS_CROSTINI_CONTAINER_UPGRADE_SUBTEXT},
+ {"crostiniContainerUpgradeButton",
+ IDS_SETTINGS_CROSTINI_CONTAINER_UPGRADE_BUTTON},
+ {"crostiniPortForwarding", IDS_SETTINGS_CROSTINI_PORT_FORWARDING},
+ {"crostiniPortForwardingDescription",
+ IDS_SETTINGS_CROSTINI_PORT_FORWARDING_DESCRIPTION},
+ {"crostiniPortForwardingNoPorts",
+ IDS_SETTINGS_CROSTINI_PORT_FORWARDING_NO_PORTS},
+ {"crostiniPortForwardingTableTitle",
+ IDS_SETTINGS_CROSTINI_PORT_FORWARDING_TABLE_TITLE},
+ {"crostiniPortForwardingListPortNumber",
+ IDS_SETTINGS_CROSTINI_PORT_FORWARDING_LIST_PORT_NUMBER},
+ {"crostiniPortForwardingListLabel",
+ IDS_SETTINGS_CROSTINI_PORT_FORWARDING_LIST_LABEL},
+ {"crostiniPortForwardingAddPortButton",
+ IDS_SETTINGS_CROSTINI_PORT_FORWARDING_ADD_PORT_BUTTON},
+ {"crostiniPortForwardingAddPortButtonDescription",
+ IDS_SETTINGS_CROSTINI_PORT_FORWARDING_ADD_PORT_BUTTON_DESCRIPTION},
+ {"crostiniPortForwardingAddPortDialogTitle",
+ IDS_SETTINGS_CROSTINI_PORT_FORWARDING_ADD_PORT_DIALOG_TITLE},
+ {"crostiniPortForwardingAddPortDialogLabel",
+ IDS_SETTINGS_CROSTINI_PORT_FORWARDING_ADD_PORT_DIALOG_LABEL},
+ {"crostiniPortForwardingTCP", IDS_SETTINGS_CROSTINI_PORT_FORWARDING_TCP},
+ {"crostiniPortForwardingUDP", IDS_SETTINGS_CROSTINI_PORT_FORWARDING_UDP},
+ {"crostiniPortForwardingAddError",
+ IDS_SETTINGS_CROSTINI_PORT_FORWARDING_ADD_ERROR},
+ {"crostiniDiskResizeTitle", IDS_SETTINGS_CROSTINI_DISK_RESIZE_TITLE},
+ {"crostiniDiskResizeShowButton",
+ IDS_SETTINGS_CROSTINI_DISK_RESIZE_SHOW_BUTTON},
+ {"crostiniDiskResizeLabel", IDS_SETTINGS_CROSTINI_DISK_RESIZE_LABEL},
+ {"crostiniDiskResizeUnsupported",
+ IDS_SETTINGS_CROSTINI_DISK_RESIZE_UNSUPPORTED},
+ {"crostiniDiskResizeLoading", IDS_SETTINGS_CROSTINI_DISK_RESIZE_LOADING},
+ {"crostiniDiskResizeError", IDS_SETTINGS_CROSTINI_DISK_RESIZE_ERROR},
+ {"crostiniDiskResizeErrorRetry",
+ IDS_SETTINGS_CROSTINI_DISK_RESIZE_ERROR_RETRY},
+ {"crostiniDiskResizeCancel", IDS_SETTINGS_CROSTINI_DISK_RESIZE_CANCEL},
+ {"crostiniDiskResizeGoButton",
+ IDS_SETTINGS_CROSTINI_DISK_RESIZE_GO_BUTTON},
+ {"crostiniDiskResizeInProgress",
+ IDS_SETTINGS_CROSTINI_DISK_RESIZE_IN_PROGRESS},
+ {"crostiniDiskResizeResizingError",
+ IDS_SETTINGS_CROSTINI_DISK_RESIZE_RESIZING_ERROR},
+ {"crostiniDiskResizeDone", IDS_SETTINGS_CROSTINI_DISK_RESIZE_DONE},
+ {"crostiniMicTitle", IDS_SETTINGS_CROSTINI_MIC_TITLE},
+ {"crostiniMicDialogTitle", IDS_SETTINGS_CROSTINI_MIC_DIALOG_TITLE},
+ {"crostiniMicDialogLabel", IDS_SETTINGS_CROSTINI_MIC_DIALOG_LABEL},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+ html_source->AddString(
+ "crostiniSubtext",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_CROSTINI_SUBTEXT, ui::GetChromeOSDeviceName(),
+ GetHelpUrlWithBoard(chrome::kLinuxAppsLearnMoreURL)));
+ html_source->AddString(
+ "crostiniArcAdbPowerwashRequiredSublabel",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_CROSTINI_ARC_ADB_POWERWASH_REQUIRED_SUBLABEL,
+ base::ASCIIToUTF16(chrome::kArcAdbSideloadingLearnMoreURL)));
+ html_source->AddString("crostiniRemove", l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_CROSTINI_REMOVE,
+ ui::GetChromeOSDeviceName()));
+ html_source->AddString(
+ "crostiniArcAdbConfirmationMessageEnable",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_CROSTINI_ARC_ADB_CONFIRMATION_MESSAGE_ENABLE,
+ ui::GetChromeOSDeviceName()));
+ html_source->AddString(
+ "crostiniArcAdbConfirmationMessageDisable",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_CROSTINI_ARC_ADB_CONFIRMATION_MESSAGE_DISABLE,
+ ui::GetChromeOSDeviceName()));
+ html_source->AddString(
+ "crostiniSharedPathsInstructionsLocate",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_CROSTINI_SHARED_PATHS_INSTRUCTIONS_LOCATE,
+ base::ASCIIToUTF16(
+ crostini::ContainerChromeOSBaseDirectory().value())));
+ html_source->AddBoolean(
+ "showCrostiniExportImport",
+ crostini::CrostiniFeatures::Get()->IsExportImportUIAllowed(profile));
+ html_source->AddBoolean("arcAdbSideloadingSupported",
+ base::FeatureList::IsEnabled(
+ chromeos::features::kArcAdbSideloadingFeature));
+ html_source->AddBoolean("showCrostiniPortForwarding",
+ base::FeatureList::IsEnabled(
+ chromeos::features::kCrostiniPortForwarding));
+ html_source->AddBoolean("isOwnerProfile",
+ chromeos::ProfileHelper::IsOwnerProfile(profile));
+ html_source->AddBoolean("isEnterpriseManaged",
+ IsDeviceManaged() || IsProfileManaged(profile));
+ html_source->AddBoolean(
+ "canChangeAdbSideloading",
+ crostini::CrostiniFeatures::Get()->CanChangeAdbSideloading(profile));
+ html_source->AddBoolean("showCrostiniContainerUpgrade",
+ crostini::ShouldAllowContainerUpgrade(profile));
+ html_source->AddBoolean(
+ "showCrostiniDiskResize",
+ base::FeatureList::IsEnabled(chromeos::features::kCrostiniDiskResizing));
+ html_source->AddBoolean("showCrostiniMic",
+ base::FeatureList::IsEnabled(
+ chromeos::features::kCrostiniShowMicSetting));
+}
+
+void AddPluginVmStrings(content::WebUIDataSource* html_source,
+ Profile* profile) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"pluginVmPageTitle", IDS_SETTINGS_PLUGIN_VM_PAGE_TITLE},
+ {"pluginVmPageLabel", IDS_SETTINGS_PLUGIN_VM_PAGE_LABEL},
+ {"pluginVmPageSubtext", IDS_SETTINGS_PLUGIN_VM_PAGE_SUBTEXT},
+ {"pluginVmPageEnable", IDS_SETTINGS_TURN_ON},
+ {"pluginVmPrinterAccess", IDS_SETTINGS_PLUGIN_VM_PRINTER_ACCESS},
+ {"pluginVmSharedPaths", IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS},
+ {"pluginVmSharedPathsListHeading",
+ IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS_LIST_HEADING},
+ {"pluginVmSharedPathsInstructionsAdd",
+ IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS_INSTRUCTIONS_ADD},
+ {"pluginVmSharedPathsInstructionsRemove",
+ IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS_INSTRUCTIONS_REMOVE},
+ {"pluginVmSharedPathsRemoveSharing",
+ IDS_SETTINGS_PLUGIN_VM_SHARED_PATHS_REMOVE_SHARING},
+ {"pluginVmRemove", IDS_SETTINGS_PLUGIN_VM_REMOVE_LABEL},
+ {"pluginVmRemoveButton", IDS_SETTINGS_PLUGIN_VM_REMOVE_BUTTON},
+ {"pluginVmRemoveConfirmationDialogMessage",
+ IDS_SETTINGS_PLUGIN_VM_CONFIRM_REMOVE_DIALOG_BODY},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+}
+
+void AddAndroidAppStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"androidAppsPageLabel", IDS_SETTINGS_ANDROID_APPS_LABEL},
+ {"androidAppsEnable", IDS_SETTINGS_TURN_ON},
+ {"androidAppsManageApps", IDS_SETTINGS_ANDROID_APPS_MANAGE_APPS},
+ {"androidAppsRemove", IDS_SETTINGS_ANDROID_APPS_REMOVE},
+ {"androidAppsRemoveButton", IDS_SETTINGS_ANDROID_APPS_REMOVE_BUTTON},
+ {"androidAppsDisableDialogTitle",
+ IDS_SETTINGS_ANDROID_APPS_DISABLE_DIALOG_TITLE},
+ {"androidAppsDisableDialogMessage",
+ IDS_SETTINGS_ANDROID_APPS_DISABLE_DIALOG_MESSAGE},
+ {"androidAppsDisableDialogRemove",
+ IDS_SETTINGS_ANDROID_APPS_DISABLE_DIALOG_REMOVE},
+ {"androidAppsManageAppLinks", IDS_SETTINGS_ANDROID_APPS_MANAGE_APP_LINKS},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+ html_source->AddLocalizedString("androidAppsPageTitle",
+ arc::IsPlayStoreAvailable()
+ ? IDS_SETTINGS_ANDROID_APPS_TITLE
+ : IDS_SETTINGS_ANDROID_SETTINGS_TITLE);
+ html_source->AddString(
+ "androidAppsSubtext",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_ANDROID_APPS_SUBTEXT, ui::GetChromeOSDeviceName(),
+ GetHelpUrlWithBoard(chrome::kAndroidAppsLearnMoreURL)));
+}
+
+void AddAppsStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"appsPageTitle", IDS_SETTINGS_APPS_TITLE},
+ {"appManagementTitle", IDS_SETTINGS_APPS_LINK_TEXT},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+}
+
+void AddAppManagementStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"appManagementAppInstalledByPolicyLabel",
+ IDS_APP_MANAGEMENT_POLICY_APP_POLICY_STRING},
+ {"appManagementCameraPermissionLabel", IDS_APP_MANAGEMENT_CAMERA},
+ {"appManagementContactsPermissionLabel", IDS_APP_MANAGEMENT_CONTACTS},
+ {"appManagementLocationPermissionLabel", IDS_APP_MANAGEMENT_LOCATION},
+ {"appManagementMicrophonePermissionLabel", IDS_APP_MANAGEMENT_MICROPHONE},
+ {"appManagementMoreSettingsLabel", IDS_APP_MANAGEMENT_MORE_SETTINGS},
+ {"appManagementNoAppsFound", IDS_APP_MANAGEMENT_NO_APPS_FOUND},
+ {"appManagementNoPermissions",
+ IDS_APPLICATION_INFO_APP_NO_PERMISSIONS_TEXT},
+ {"appManagementNotificationsLabel", IDS_APP_MANAGEMENT_NOTIFICATIONS},
+ {"appManagementPermissionsLabel", IDS_APP_MANAGEMENT_PERMISSIONS},
+ {"appManagementPinToShelfLabel", IDS_APP_MANAGEMENT_PIN_TO_SHELF},
+ {"appManagementSearchPrompt", IDS_APP_MANAGEMENT_SEARCH_PROMPT},
+ {"appManagementStoragePermissionLabel", IDS_APP_MANAGEMENT_STORAGE},
+ {"appManagementUninstallLabel", IDS_APP_MANAGEMENT_UNINSTALL_APP},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+}
+
+void AddParentalControlStrings(content::WebUIDataSource* html_source,
+ Profile* profile) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"parentalControlsPageTitle", IDS_SETTINGS_PARENTAL_CONTROLS_PAGE_TITLE},
+ {"parentalControlsPageSetUpLabel",
+ IDS_SETTINGS_PARENTAL_CONTROLS_PAGE_SET_UP_LABEL},
+ {"parentalControlsPageViewSettingsLabel",
+ IDS_SETTINGS_PARENTAL_CONTROLS_PAGE_VIEW_SETTINGS_LABEL},
+ {"parentalControlsPageConnectToInternetLabel",
+ IDS_SETTINGS_PARENTAL_CONTROLS_PAGE_CONNECT_TO_INTERNET_LABEL},
+ {"parentalControlsSetUpButtonLabel",
+ IDS_SETTINGS_PARENTAL_CONTROLS_SET_UP_BUTTON_LABEL},
+ {"parentalControlsSetUpButtonRole",
+ IDS_SETTINGS_PARENTAL_CONTROLS_SET_UP_BUTTON_ROLE},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddBoolean(
+ "isChild", user_manager::UserManager::Get()->IsLoggedInAsChildUser());
+
+ if (user_manager::UserManager::Get()->IsLoggedInAsChildUser()) {
+ SupervisedUserService* supervised_user_service =
+ SupervisedUserServiceFactory::GetForProfile(profile);
+ std::string custodian = supervised_user_service->GetCustodianName();
+ std::string second_custodian =
+ supervised_user_service->GetSecondCustodianName();
+
+ base::string16 child_managed_tooltip;
+ if (second_custodian.empty()) {
+ child_managed_tooltip = l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_ACCOUNT_MANAGER_CHILD_MANAGED_BY_ONE_PARENT_TOOLTIP,
+ base::UTF8ToUTF16(custodian));
+ } else {
+ child_managed_tooltip = l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_ACCOUNT_MANAGER_CHILD_MANAGED_BY_TWO_PARENTS_TOOLTIP,
+ base::UTF8ToUTF16(custodian), base::UTF8ToUTF16(second_custodian));
+ }
+ html_source->AddString("accountManagerPrimaryAccountChildManagedTooltip",
+ child_managed_tooltip);
+ }
+}
+
+void AddBluetoothStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"bluetoothConnected", IDS_SETTINGS_BLUETOOTH_CONNECTED},
+ {"bluetoothConnectedWithBattery",
+ IDS_SETTINGS_BLUETOOTH_CONNECTED_WITH_BATTERY},
+ {"bluetoothConnecting", IDS_SETTINGS_BLUETOOTH_CONNECTING},
+ {"bluetoothDeviceListPaired", IDS_SETTINGS_BLUETOOTH_DEVICE_LIST_PAIRED},
+ {"bluetoothDeviceListUnpaired",
+ IDS_SETTINGS_BLUETOOTH_DEVICE_LIST_UNPAIRED},
+ {"bluetoothConnect", IDS_SETTINGS_BLUETOOTH_CONNECT},
+ {"bluetoothDisconnect", IDS_SETTINGS_BLUETOOTH_DISCONNECT},
+ {"bluetoothToggleA11yLabel",
+ IDS_SETTINGS_BLUETOOTH_TOGGLE_ACCESSIBILITY_LABEL},
+ {"bluetoothExpandA11yLabel",
+ IDS_SETTINGS_BLUETOOTH_EXPAND_ACCESSIBILITY_LABEL},
+ {"bluetoothNoDevices", IDS_SETTINGS_BLUETOOTH_NO_DEVICES},
+ {"bluetoothNoDevicesFound", IDS_SETTINGS_BLUETOOTH_NO_DEVICES_FOUND},
+ {"bluetoothNotConnected", IDS_SETTINGS_BLUETOOTH_NOT_CONNECTED},
+ {"bluetoothPageTitle", IDS_SETTINGS_BLUETOOTH},
+ {"bluetoothPairDevicePageTitle",
+ IDS_SETTINGS_BLUETOOTH_PAIR_DEVICE_TITLE},
+ {"bluetoothRemove", IDS_SETTINGS_BLUETOOTH_REMOVE},
+ {"bluetoothPrimaryUserControlled",
+ IDS_SETTINGS_BLUETOOTH_PRIMARY_USER_CONTROLLED},
+ {"bluetoothDeviceType_computer",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_COMPUTER},
+ {"bluetoothDeviceType_phone",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_PHONE},
+ {"bluetoothDeviceType_modem",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_MODEM},
+ {"bluetoothDeviceType_audio",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_AUDIO},
+ {"bluetoothDeviceType_carAudio",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_CAR_AUDIO},
+ {"bluetoothDeviceType_video",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_VIDEO},
+ {"bluetoothDeviceType_peripheral",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_PERIPHERAL},
+ {"bluetoothDeviceType_joystick",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_JOYSTICK},
+ {"bluetoothDeviceType_gamepad",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_GAMEPAD},
+ {"bluetoothDeviceType_keyboard",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_KEYBOARD},
+ {"bluetoothDeviceType_mouse",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_MOUSE},
+ {"bluetoothDeviceType_tablet",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_TABLET},
+ {"bluetoothDeviceType_keyboardMouseCombo",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_KEYBOARD_MOUSE_COMBO},
+ {"bluetoothDeviceType_unknown",
+ IDS_BLUETOOTH_ACCESSIBILITY_DEVICE_TYPE_UNKNOWN},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+ chromeos::bluetooth_dialog::AddLocalizedStrings(html_source);
+}
+
+void AddChromeOSUserStrings(content::WebUIDataSource* html_source,
+ Profile* profile) {
+ user_manager::UserManager* user_manager = user_manager::UserManager::Get();
+
+ const user_manager::User* user =
+ chromeos::ProfileHelper::Get()->GetUserByProfile(profile);
+ const user_manager::User* primary_user = user_manager->GetPrimaryUser();
+ std::string primary_user_email = primary_user->GetAccountId().GetUserEmail();
+ html_source->AddString("primaryUserEmail", primary_user_email);
+ html_source->AddString("browserSettingsBannerText",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_BROWSER_SETTINGS_BANNER,
+ base::ASCIIToUTF16(chrome::kChromeUISettingsURL)));
+ html_source->AddBoolean("isActiveDirectoryUser",
+ user && user->IsActiveDirectoryUser());
+ html_source->AddBoolean(
+ "isSecondaryUser",
+ user && user->GetAccountId() != primary_user->GetAccountId());
+ html_source->AddString(
+ "secondaryUserBannerText",
+ l10n_util::GetStringFUTF16(IDS_SETTINGS_SECONDARY_USER_BANNER,
+ base::ASCIIToUTF16(primary_user_email)));
+
+ if (!IsDeviceManaged() && !user_manager->IsCurrentUserOwner()) {
+ html_source->AddString("ownerEmail",
+ user_manager->GetOwnerAccountId().GetUserEmail());
+ }
+}
+
+void AddDevicePointersStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kPointersStrings[] = {
+ {"mouseTitle", IDS_SETTINGS_MOUSE_TITLE},
+ {"touchpadTitle", IDS_SETTINGS_TOUCHPAD_TITLE},
+ {"mouseAndTouchpadTitle", IDS_SETTINGS_MOUSE_AND_TOUCHPAD_TITLE},
+ {"touchpadTapToClickEnabledLabel",
+ IDS_SETTINGS_TOUCHPAD_TAP_TO_CLICK_ENABLED_LABEL},
+ {"touchpadSpeed", IDS_SETTINGS_TOUCHPAD_SPEED_LABEL},
+ {"pointerSlow", IDS_SETTINGS_POINTER_SPEED_SLOW_LABEL},
+ {"pointerFast", IDS_SETTINGS_POINTER_SPEED_FAST_LABEL},
+ {"mouseScrollSpeed", IDS_SETTINGS_MOUSE_SCROLL_SPEED_LABEL},
+ {"mouseSpeed", IDS_SETTINGS_MOUSE_SPEED_LABEL},
+ {"mouseSwapButtons", IDS_SETTINGS_MOUSE_SWAP_BUTTONS_LABEL},
+ {"mouseReverseScroll", IDS_SETTINGS_MOUSE_REVERSE_SCROLL_LABEL},
+ {"mouseAccelerationLabel", IDS_SETTINGS_MOUSE_ACCELERATION_LABEL},
+ {"mouseScrollAccelerationLabel",
+ IDS_SETTINGS_MOUSE_SCROLL_ACCELERATION_LABEL},
+ {"touchpadAccelerationLabel", IDS_SETTINGS_TOUCHPAD_ACCELERATION_LABEL},
+ {"touchpadScrollAccelerationLabel",
+ IDS_SETTINGS_TOUCHPAD_SCROLL_ACCELERATION_LABEL},
+ {"touchpadScrollSpeed", IDS_SETTINGS_TOUCHPAD_SCROLL_SPEED_LABEL},
+ };
+ AddLocalizedStringsBulk(html_source, kPointersStrings);
+
+ html_source->AddString("naturalScrollLearnMoreLink",
+ GetHelpUrlWithBoard(chrome::kNaturalScrollHelpURL));
+
+ html_source->AddBoolean(
+ "allowDisableMouseAcceleration",
+ base::FeatureList::IsEnabled(::features::kAllowDisableMouseAcceleration));
+ html_source->AddBoolean(
+ "allowScrollSettings",
+ base::FeatureList::IsEnabled(features::kAllowScrollSettings));
+}
+
+void AddDeviceKeyboardStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString keyboard_strings[] = {
+ {"keyboardTitle", IDS_SETTINGS_KEYBOARD_TITLE},
+ {"keyboardKeyCtrl", IDS_SETTINGS_KEYBOARD_KEY_LEFT_CTRL},
+ {"keyboardKeyAlt", IDS_SETTINGS_KEYBOARD_KEY_LEFT_ALT},
+ {"keyboardKeyCapsLock", IDS_SETTINGS_KEYBOARD_KEY_CAPS_LOCK},
+ {"keyboardKeyCommand", IDS_SETTINGS_KEYBOARD_KEY_COMMAND},
+ {"keyboardKeyDiamond", IDS_SETTINGS_KEYBOARD_KEY_DIAMOND},
+ {"keyboardKeyEscape", IDS_SETTINGS_KEYBOARD_KEY_ESCAPE},
+ {"keyboardKeyBackspace", IDS_SETTINGS_KEYBOARD_KEY_BACKSPACE},
+ {"keyboardKeyAssistant", IDS_SETTINGS_KEYBOARD_KEY_ASSISTANT},
+ {"keyboardKeyDisabled", IDS_SETTINGS_KEYBOARD_KEY_DISABLED},
+ {"keyboardKeyExternalCommand",
+ IDS_SETTINGS_KEYBOARD_KEY_EXTERNAL_COMMAND},
+ {"keyboardKeyExternalMeta", IDS_SETTINGS_KEYBOARD_KEY_EXTERNAL_META},
+ {"keyboardKeyMeta", IDS_SETTINGS_KEYBOARD_KEY_META},
+ {"keyboardSendFunctionKeys", IDS_SETTINGS_KEYBOARD_SEND_FUNCTION_KEYS},
+ {"keyboardEnableAutoRepeat", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_ENABLE},
+ {"keyRepeatDelay", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_DELAY},
+ {"keyRepeatDelayLong", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_DELAY_LONG},
+ {"keyRepeatDelayShort", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_DELAY_SHORT},
+ {"keyRepeatRate", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_RATE},
+ {"keyRepeatRateSlow", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_RATE_SLOW},
+ {"keyRepeatRateFast", IDS_SETTINGS_KEYBOARD_AUTO_REPEAT_FAST},
+ {"showKeyboardShortcutViewer",
+ IDS_SETTINGS_KEYBOARD_SHOW_SHORTCUT_VIEWER},
+ {"keyboardShowLanguageAndInput",
+ IDS_SETTINGS_KEYBOARD_SHOW_LANGUAGE_AND_INPUT},
+ };
+ AddLocalizedStringsBulk(html_source, keyboard_strings);
+
+ html_source->AddLocalizedString("keyboardKeySearch",
+ ui::DeviceUsesKeyboardLayout2()
+ ? IDS_SETTINGS_KEYBOARD_KEY_LAUNCHER
+ : IDS_SETTINGS_KEYBOARD_KEY_SEARCH);
+ html_source->AddLocalizedString(
+ "keyboardSendFunctionKeysDescription",
+ ui::DeviceUsesKeyboardLayout2()
+ ? IDS_SETTINGS_KEYBOARD_SEND_FUNCTION_KEYS_LAYOUT2_DESCRIPTION
+ : IDS_SETTINGS_KEYBOARD_SEND_FUNCTION_KEYS_DESCRIPTION);
+}
+
+void AddDeviceStylusStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kStylusStrings[] = {
+ {"stylusTitle", IDS_SETTINGS_STYLUS_TITLE},
+ {"stylusEnableStylusTools", IDS_SETTINGS_STYLUS_ENABLE_STYLUS_TOOLS},
+ {"stylusAutoOpenStylusTools", IDS_SETTINGS_STYLUS_AUTO_OPEN_STYLUS_TOOLS},
+ {"stylusFindMoreAppsPrimary", IDS_SETTINGS_STYLUS_FIND_MORE_APPS_PRIMARY},
+ {"stylusFindMoreAppsSecondary",
+ IDS_SETTINGS_STYLUS_FIND_MORE_APPS_SECONDARY},
+ {"stylusNoteTakingApp", IDS_SETTINGS_STYLUS_NOTE_TAKING_APP_LABEL},
+ {"stylusNoteTakingAppEnabledOnLockScreen",
+ IDS_SETTINGS_STYLUS_NOTE_TAKING_APP_LOCK_SCREEN_CHECKBOX},
+ {"stylusNoteTakingAppKeepsLastNoteOnLockScreen",
+ IDS_SETTINGS_STYLUS_NOTE_TAKING_APP_KEEP_LATEST_NOTE},
+ {"stylusNoteTakingAppLockScreenSettingsHeader",
+ IDS_SETTINGS_STYLUS_LOCK_SCREEN_NOTES_TITLE},
+ {"stylusNoteTakingAppNoneAvailable",
+ IDS_SETTINGS_STYLUS_NOTE_TAKING_APP_NONE_AVAILABLE},
+ {"stylusNoteTakingAppWaitingForAndroid",
+ IDS_SETTINGS_STYLUS_NOTE_TAKING_APP_WAITING_FOR_ANDROID}};
+ AddLocalizedStringsBulk(html_source, kStylusStrings);
+}
+
+void AddDeviceDisplayStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kDisplayStrings[] = {
+ {"displayTitle", IDS_SETTINGS_DISPLAY_TITLE},
+ {"displayArrangementText", IDS_SETTINGS_DISPLAY_ARRANGEMENT_TEXT},
+ {"displayArrangementTitle", IDS_SETTINGS_DISPLAY_ARRANGEMENT_TITLE},
+ {"displayMirror", IDS_SETTINGS_DISPLAY_MIRROR},
+ {"displayMirrorDisplayName", IDS_SETTINGS_DISPLAY_MIRROR_DISPLAY_NAME},
+ {"displayAmbientColorTitle", IDS_SETTINGS_DISPLAY_AMBIENT_COLOR_TITLE},
+ {"displayAmbientColorSubtitle",
+ IDS_SETTINGS_DISPLAY_AMBIENT_COLOR_SUBTITLE},
+ {"displayNightLightLabel", IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_LABEL},
+ {"displayNightLightOnAtSunset",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_ON_AT_SUNSET},
+ {"displayNightLightOffAtSunrise",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_OFF_AT_SUNRISE},
+ {"displayNightLightScheduleCustom",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_CUSTOM},
+ {"displayNightLightScheduleLabel",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_LABEL},
+ {"displayNightLightScheduleNever",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_NEVER},
+ {"displayNightLightScheduleSunsetToSunRise",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_SCHEDULE_SUNSET_TO_SUNRISE},
+ {"displayNightLightStartTime",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_START_TIME},
+ {"displayNightLightStopTime", IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_STOP_TIME},
+ {"displayNightLightText", IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEXT},
+ {"displayNightLightTemperatureLabel",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEMPERATURE_LABEL},
+ {"displayNightLightTempSliderMaxLabel",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEMP_SLIDER_MAX_LABEL},
+ {"displayNightLightTempSliderMinLabel",
+ IDS_SETTINGS_DISPLAY_NIGHT_LIGHT_TEMP_SLIDER_MIN_LABEL},
+ {"displayUnifiedDesktop", IDS_SETTINGS_DISPLAY_UNIFIED_DESKTOP},
+ {"displayUnifiedDesktopOn", IDS_SETTINGS_DISPLAY_UNIFIED_DESKTOP_ON},
+ {"displayUnifiedDesktopOff", IDS_SETTINGS_DISPLAY_UNIFIED_DESKTOP_OFF},
+ {"displayResolutionTitle", IDS_SETTINGS_DISPLAY_RESOLUTION_TITLE},
+ {"displayResolutionText", IDS_SETTINGS_DISPLAY_RESOLUTION_TEXT},
+ {"displayResolutionTextBest", IDS_SETTINGS_DISPLAY_RESOLUTION_TEXT_BEST},
+ {"displayResolutionTextNative",
+ IDS_SETTINGS_DISPLAY_RESOLUTION_TEXT_NATIVE},
+ {"displayResolutionSublabel", IDS_SETTINGS_DISPLAY_RESOLUTION_SUBLABEL},
+ {"displayResolutionMenuItem", IDS_SETTINGS_DISPLAY_RESOLUTION_MENU_ITEM},
+ {"displayResolutionInterlacedMenuItem",
+ IDS_SETTINGS_DISPLAY_RESOLUTION_INTERLACED_MENU_ITEM},
+ {"displayZoomTitle", IDS_SETTINGS_DISPLAY_ZOOM_TITLE},
+ {"displayZoomSublabel", IDS_SETTINGS_DISPLAY_ZOOM_SUBLABEL},
+ {"displayZoomValue", IDS_SETTINGS_DISPLAY_ZOOM_VALUE},
+ {"displayZoomLogicalResolutionText",
+ IDS_SETTINGS_DISPLAY_ZOOM_LOGICAL_RESOLUTION_TEXT},
+ {"displayZoomNativeLogicalResolutionNativeText",
+ IDS_SETTINGS_DISPLAY_ZOOM_LOGICAL_RESOLUTION_NATIVE_TEXT},
+ {"displayZoomLogicalResolutionDefaultText",
+ IDS_SETTINGS_DISPLAY_ZOOM_LOGICAL_RESOLUTION_DEFAULT_TEXT},
+ {"displaySizeSliderMinLabel", IDS_SETTINGS_DISPLAY_ZOOM_SLIDER_MINIMUM},
+ {"displaySizeSliderMaxLabel", IDS_SETTINGS_DISPLAY_ZOOM_SLIDER_MAXIMUM},
+ {"displayScreenTitle", IDS_SETTINGS_DISPLAY_SCREEN},
+ {"displayScreenExtended", IDS_SETTINGS_DISPLAY_SCREEN_EXTENDED},
+ {"displayScreenPrimary", IDS_SETTINGS_DISPLAY_SCREEN_PRIMARY},
+ {"displayOrientation", IDS_SETTINGS_DISPLAY_ORIENTATION},
+ {"displayOrientationStandard", IDS_SETTINGS_DISPLAY_ORIENTATION_STANDARD},
+ {"displayOrientationAutoRotate",
+ IDS_SETTINGS_DISPLAY_ORIENTATION_AUTO_ROTATE},
+ {"displayOverscanPageText", IDS_SETTINGS_DISPLAY_OVERSCAN_TEXT},
+ {"displayOverscanPageTitle", IDS_SETTINGS_DISPLAY_OVERSCAN_TITLE},
+ {"displayOverscanSubtitle", IDS_SETTINGS_DISPLAY_OVERSCAN_SUBTITLE},
+ {"displayOverscanInstructions",
+ IDS_SETTINGS_DISPLAY_OVERSCAN_INSTRUCTIONS},
+ {"displayOverscanResize", IDS_SETTINGS_DISPLAY_OVERSCAN_RESIZE},
+ {"displayOverscanPosition", IDS_SETTINGS_DISPLAY_OVERSCAN_POSITION},
+ {"displayOverscanReset", IDS_SETTINGS_DISPLAY_OVERSCAN_RESET},
+ {"displayTouchCalibrationTitle",
+ IDS_SETTINGS_DISPLAY_TOUCH_CALIBRATION_TITLE},
+ {"displayTouchCalibrationText",
+ IDS_SETTINGS_DISPLAY_TOUCH_CALIBRATION_TEXT}};
+ AddLocalizedStringsBulk(html_source, kDisplayStrings);
+
+ base::CommandLine& cmd = *base::CommandLine::ForCurrentProcess();
+ html_source->AddBoolean("unifiedDesktopAvailable",
+ cmd.HasSwitch(::switches::kEnableUnifiedDesktop));
+
+ html_source->AddBoolean("listAllDisplayModes",
+ display::features::IsListAllDisplayModesEnabled());
+
+ html_source->AddBoolean("deviceSupportsAmbientColor",
+ ash::features::IsAllowAmbientEQEnabled());
+
+ html_source->AddBoolean(
+ "enableTouchCalibrationSetting",
+ cmd.HasSwitch(chromeos::switches::kEnableTouchCalibrationSetting));
+
+ html_source->AddBoolean("hasExternalTouchDevice",
+ display::HasExternalTouchscreenDevice());
+}
+
+void AddDeviceStorageStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kStorageStrings[] = {
+ {"storageTitle", IDS_SETTINGS_STORAGE_TITLE},
+ {"storageItemInUse", IDS_SETTINGS_STORAGE_ITEM_IN_USE},
+ {"storageItemAvailable", IDS_SETTINGS_STORAGE_ITEM_AVAILABLE},
+ {"storageItemSystem", IDS_SETTINGS_STORAGE_ITEM_SYSTEM},
+ {"storageItemMyFiles", IDS_SETTINGS_STORAGE_ITEM_MY_FILES},
+ {"storageItemBrowsingData", IDS_SETTINGS_STORAGE_ITEM_BROWSING_DATA},
+ {"storageItemApps", IDS_SETTINGS_STORAGE_ITEM_APPS},
+ {"storageItemCrostini", IDS_SETTINGS_STORAGE_ITEM_CROSTINI},
+ {"storageItemOtherUsers", IDS_SETTINGS_STORAGE_ITEM_OTHER_USERS},
+ {"storageSizeComputing", IDS_SETTINGS_STORAGE_SIZE_CALCULATING},
+ {"storageSizeUnknown", IDS_SETTINGS_STORAGE_SIZE_UNKNOWN},
+ {"storageSpaceLowMessageTitle",
+ IDS_SETTINGS_STORAGE_SPACE_LOW_MESSAGE_TITLE},
+ {"storageSpaceLowMessageLine1",
+ IDS_SETTINGS_STORAGE_SPACE_LOW_MESSAGE_LINE_1},
+ {"storageSpaceLowMessageLine2",
+ IDS_SETTINGS_STORAGE_SPACE_LOW_MESSAGE_LINE_2},
+ {"storageSpaceCriticallyLowMessageTitle",
+ IDS_SETTINGS_STORAGE_SPACE_CRITICALLY_LOW_MESSAGE_TITLE},
+ {"storageSpaceCriticallyLowMessageLine1",
+ IDS_SETTINGS_STORAGE_SPACE_CRITICALLY_LOW_MESSAGE_LINE_1},
+ {"storageSpaceCriticallyLowMessageLine2",
+ IDS_SETTINGS_STORAGE_SPACE_CRITICALLY_LOW_MESSAGE_LINE_2},
+ {"storageExternal", IDS_SETTINGS_STORAGE_EXTERNAL},
+ {"storageExternalStorageEmptyListHeader",
+ IDS_SETTINGS_STORAGE_EXTERNAL_STORAGE_EMPTY_LIST_HEADER},
+ {"storageExternalStorageListHeader",
+ IDS_SETTINGS_STORAGE_EXTERNAL_STORAGE_LIST_HEADER},
+ {"storageOverviewAriaLabel", IDS_SETTINGS_STORAGE_OVERVIEW_ARIA_LABEL}};
+ AddLocalizedStringsBulk(html_source, kStorageStrings);
+
+ html_source->AddString(
+ "storageAndroidAppsExternalDrivesNote",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_STORAGE_ANDROID_APPS_ACCESS_EXTERNAL_DRIVES_NOTE,
+ base::ASCIIToUTF16(chrome::kArcExternalStorageLearnMoreURL)));
+}
+
+void AddDevicePowerStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kPowerStrings[] = {
+ {"powerTitle", IDS_SETTINGS_POWER_TITLE},
+ {"powerSourceLabel", IDS_SETTINGS_POWER_SOURCE_LABEL},
+ {"powerSourceBattery", IDS_SETTINGS_POWER_SOURCE_BATTERY},
+ {"powerSourceAcAdapter", IDS_SETTINGS_POWER_SOURCE_AC_ADAPTER},
+ {"powerSourceLowPowerCharger",
+ IDS_SETTINGS_POWER_SOURCE_LOW_POWER_CHARGER},
+ {"calculatingPower", IDS_SETTINGS_POWER_SOURCE_CALCULATING},
+ {"powerIdleLabel", IDS_SETTINGS_POWER_IDLE_LABEL},
+ {"powerIdleWhileChargingLabel",
+ IDS_SETTINGS_POWER_IDLE_WHILE_CHARGING_LABEL},
+ {"powerIdleWhileChargingAriaLabel",
+ IDS_SETTINGS_POWER_IDLE_WHILE_CHARGING_ARIA_LABEL},
+ {"powerIdleWhileOnBatteryLabel",
+ IDS_SETTINGS_POWER_IDLE_WHILE_ON_BATTERY_LABEL},
+ {"powerIdleWhileOnBatteryAriaLabel",
+ IDS_SETTINGS_POWER_IDLE_WHILE_ON_BATTERY_ARIA_LABEL},
+ {"powerIdleDisplayOffSleep", IDS_SETTINGS_POWER_IDLE_DISPLAY_OFF_SLEEP},
+ {"powerIdleDisplayOff", IDS_SETTINGS_POWER_IDLE_DISPLAY_OFF},
+ {"powerIdleDisplayOn", IDS_SETTINGS_POWER_IDLE_DISPLAY_ON},
+ {"powerIdleOther", IDS_SETTINGS_POWER_IDLE_OTHER},
+ {"powerLidSleepLabel", IDS_SETTINGS_POWER_LID_CLOSED_SLEEP_LABEL},
+ {"powerLidSignOutLabel", IDS_SETTINGS_POWER_LID_CLOSED_SIGN_OUT_LABEL},
+ {"powerLidShutDownLabel", IDS_SETTINGS_POWER_LID_CLOSED_SHUT_DOWN_LABEL},
+ };
+ AddLocalizedStringsBulk(html_source, kPowerStrings);
+}
+
+void AddDeviceStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kDeviceStrings[] = {
+ {"devicePageTitle", IDS_SETTINGS_DEVICE_TITLE},
+ {"scrollLabel", IDS_SETTINGS_SCROLL_LABEL},
+ {"touchPadScrollLabel", IDS_OS_SETTINGS_TOUCHPAD_REVERSE_SCROLL_LABEL},
+ };
+ AddLocalizedStringsBulk(html_source, kDeviceStrings);
+
+ AddDevicePointersStrings(html_source);
+ AddDeviceKeyboardStrings(html_source);
+ AddDeviceStylusStrings(html_source);
+ AddDeviceDisplayStrings(html_source);
+ AddDeviceStorageStrings(html_source);
+ AddDevicePowerStrings(html_source);
+}
+
+void AddFilesStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"disconnectGoogleDriveAccount", IDS_SETTINGS_DISCONNECT_GOOGLE_DRIVE},
+ {"filesPageTitle", IDS_OS_SETTINGS_FILES},
+ {"smbSharesTitle", IDS_SETTINGS_DOWNLOADS_SMB_SHARES},
+ {"smbSharesLearnMoreLabel",
+ IDS_SETTINGS_DOWNLOADS_SMB_SHARES_LEARN_MORE_LABEL},
+ {"addSmbShare", IDS_SETTINGS_DOWNLOADS_SMB_SHARES_ADD_SHARE},
+ {"smbShareAddedSuccessfulMessage",
+ IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_SUCCESS_MESSAGE},
+ {"smbShareAddedErrorMessage",
+ IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_ERROR_MESSAGE},
+ {"smbShareAddedAuthFailedMessage",
+ IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_AUTH_FAILED_MESSAGE},
+ {"smbShareAddedNotFoundMessage",
+ IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_NOT_FOUND_MESSAGE},
+ {"smbShareAddedUnsupportedDeviceMessage",
+ IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_UNSUPPORTED_DEVICE_MESSAGE},
+ {"smbShareAddedMountExistsMessage",
+ IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_MOUNT_EXISTS_MESSAGE},
+ {"smbShareAddedTooManyMountsMessage",
+ IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_TOO_MANY_MOUNTS_MESSAGE},
+ {"smbShareAddedInvalidURLMessage",
+ IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_MOUNT_INVALID_URL_MESSAGE},
+ {"smbShareAddedInvalidSSOURLMessage",
+ IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_MOUNT_INVALID_SSO_URL_MESSAGE},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ chromeos::smb_dialog::AddLocalizedStrings(html_source);
+
+ html_source->AddString("smbSharesLearnMoreURL",
+ GetHelpUrlWithBoard(chrome::kSmbSharesLearnMoreURL));
+}
+
+void AddEasyUnlockStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"easyUnlockSectionTitle", IDS_SETTINGS_EASY_UNLOCK_SECTION_TITLE},
+ {"easyUnlockUnlockDeviceOnly",
+ IDS_SETTINGS_EASY_UNLOCK_UNLOCK_DEVICE_ONLY},
+ {"easyUnlockUnlockDeviceAndAllowSignin",
+ IDS_SETTINGS_EASY_UNLOCK_UNLOCK_DEVICE_AND_ALLOW_SIGNIN},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+}
+
+void AddMultideviceStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"multidevicePageTitle", IDS_SETTINGS_MULTIDEVICE},
+ {"multideviceSetupButton", IDS_SETTINGS_MULTIDEVICE_SETUP_BUTTON},
+ {"multideviceVerifyButton", IDS_SETTINGS_MULTIDEVICE_VERIFY_BUTTON},
+ {"multideviceSetupItemHeading",
+ IDS_SETTINGS_MULTIDEVICE_SETUP_ITEM_HEADING},
+ {"multideviceEnabled", IDS_SETTINGS_MULTIDEVICE_ENABLED},
+ {"multideviceDisabled", IDS_SETTINGS_MULTIDEVICE_DISABLED},
+ {"multideviceSmartLockItemTitle", IDS_SETTINGS_EASY_UNLOCK_SECTION_TITLE},
+ {"multideviceInstantTetheringItemTitle",
+ IDS_SETTINGS_MULTIDEVICE_INSTANT_TETHERING},
+ {"multideviceInstantTetheringItemSummary",
+ IDS_SETTINGS_MULTIDEVICE_INSTANT_TETHERING_SUMMARY},
+ {"multideviceAndroidMessagesItemTitle",
+ IDS_SETTINGS_MULTIDEVICE_ANDROID_MESSAGES},
+ {"multideviceForgetDevice", IDS_SETTINGS_MULTIDEVICE_FORGET_THIS_DEVICE},
+ {"multideviceSmartLockOptions",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_OPTIONS_LOCK},
+ {"multideviceForgetDeviceDisconnect",
+ IDS_SETTINGS_MULTIDEVICE_FORGET_THIS_DEVICE_DISCONNECT},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddString(
+ "multideviceForgetDeviceSummary",
+ ui::SubstituteChromeOSDeviceType(
+ IDS_SETTINGS_MULTIDEVICE_FORGET_THIS_DEVICE_EXPLANATION));
+ html_source->AddString(
+ "multideviceForgetDeviceDialogMessage",
+ ui::SubstituteChromeOSDeviceType(
+ IDS_SETTINGS_MULTIDEVICE_FORGET_DEVICE_DIALOG_MESSAGE));
+ html_source->AddString(
+ "multideviceVerificationText",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_MULTIDEVICE_VERIFICATION_TEXT,
+ base::UTF8ToUTF16(
+ chromeos::multidevice_setup::
+ GetBoardSpecificBetterTogetherSuiteLearnMoreUrl()
+ .spec())));
+ html_source->AddString(
+ "multideviceSetupSummary",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_MULTIDEVICE_SETUP_SUMMARY, ui::GetChromeOSDeviceName(),
+ base::UTF8ToUTF16(
+ chromeos::multidevice_setup::
+ GetBoardSpecificBetterTogetherSuiteLearnMoreUrl()
+ .spec())));
+ html_source->AddString(
+ "multideviceNoHostText",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_MULTIDEVICE_NO_ELIGIBLE_HOSTS,
+ base::UTF8ToUTF16(
+ chromeos::multidevice_setup::
+ GetBoardSpecificBetterTogetherSuiteLearnMoreUrl()
+ .spec())));
+ html_source->AddString(
+ "multideviceAndroidMessagesItemSummary",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_MULTIDEVICE_ANDROID_MESSAGES_SUMMARY,
+ ui::GetChromeOSDeviceName(),
+ base::UTF8ToUTF16(chromeos::multidevice_setup::
+ GetBoardSpecificMessagesLearnMoreUrl()
+ .spec())));
+ html_source->AddString(
+ "multideviceSmartLockItemSummary",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_MULTIDEVICE_SMART_LOCK_SUMMARY,
+ ui::GetChromeOSDeviceName(),
+ GetHelpUrlWithBoard(chrome::kEasyUnlockLearnMoreUrl)));
+
+ AddEasyUnlockStrings(html_source);
+}
+
+void AddKerberosAccountsPageStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"kerberosAccountsAddAccountLabel",
+ IDS_SETTINGS_KERBEROS_ACCOUNTS_ADD_ACCOUNT_LABEL},
+ {"kerberosAccountsRefreshNowLabel",
+ IDS_SETTINGS_KERBEROS_ACCOUNTS_REFRESH_NOW_LABEL},
+ {"kerberosAccountsSetAsActiveAccountLabel",
+ IDS_SETTINGS_KERBEROS_ACCOUNTS_SET_AS_ACTIVE_ACCOUNT_LABEL},
+ {"kerberosAccountsSignedOut", IDS_SETTINGS_KERBEROS_ACCOUNTS_SIGNED_OUT},
+ {"kerberosAccountsListHeader",
+ IDS_SETTINGS_KERBEROS_ACCOUNTS_LIST_HEADER},
+ {"kerberosAccountsRemoveAccountLabel",
+ IDS_SETTINGS_KERBEROS_ACCOUNTS_REMOVE_ACCOUNT_LABEL},
+ {"kerberosAccountsReauthenticationLabel",
+ IDS_SETTINGS_KERBEROS_ACCOUNTS_REAUTHENTICATION_LABEL},
+ {"kerberosAccountsTicketActive",
+ IDS_SETTINGS_KERBEROS_ACCOUNTS_TICKET_ACTIVE},
+ {"kerberosAccountsAccountRemovedTip",
+ IDS_SETTINGS_KERBEROS_ACCOUNTS_ACCOUNT_REMOVED_TIP},
+ {"kerberosAccountsAccountRefreshedTip",
+ IDS_SETTINGS_KERBEROS_ACCOUNTS_ACCOUNT_REFRESHED_TIP},
+ {"kerberosAccountsSignedIn", IDS_SETTINGS_KERBEROS_ACCOUNTS_SIGNED_IN},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ PrefService* local_state = g_browser_process->local_state();
+
+ // Whether new Kerberos accounts may be added.
+ html_source->AddBoolean(
+ "kerberosAddAccountsAllowed",
+ local_state->GetBoolean(prefs::kKerberosAddAccountsAllowed));
+
+ // Kerberos accounts page with "Learn more" link.
+ html_source->AddString(
+ "kerberosAccountsDescription",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_KERBEROS_ACCOUNTS_DESCRIPTION,
+ GetHelpUrlWithBoard(chrome::kKerberosAccountsLearnMoreURL)));
+}
+
+void AddKerberosAddAccountDialogStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"kerberosAccountsAdvancedConfigLabel",
+ IDS_SETTINGS_KERBEROS_ACCOUNTS_ADVANCED_CONFIG_LABEL},
+ {"kerberosAdvancedConfigTitle",
+ IDS_SETTINGS_KERBEROS_ADVANCED_CONFIG_TITLE},
+ {"kerberosAdvancedConfigDesc",
+ IDS_SETTINGS_KERBEROS_ADVANCED_CONFIG_DESC},
+ {"addKerberosAccountRememberPassword",
+ IDS_SETTINGS_ADD_KERBEROS_ACCOUNT_REMEMBER_PASSWORD},
+ {"kerberosPassword", IDS_SETTINGS_KERBEROS_PASSWORD},
+ {"kerberosUsername", IDS_SETTINGS_KERBEROS_USERNAME},
+ {"addKerberosAccountDescription",
+ IDS_SETTINGS_ADD_KERBEROS_ACCOUNT_DESCRIPTION},
+ {"kerberosErrorNetworkProblem",
+ IDS_SETTINGS_KERBEROS_ERROR_NETWORK_PROBLEM},
+ {"kerberosErrorUsernameInvalid",
+ IDS_SETTINGS_KERBEROS_ERROR_USERNAME_INVALID},
+ {"kerberosErrorUsernameUnknown",
+ IDS_SETTINGS_KERBEROS_ERROR_USERNAME_UNKNOWN},
+ {"kerberosErrorDuplicatePrincipalName",
+ IDS_SETTINGS_KERBEROS_ERROR_DUPLICATE_PRINCIPAL_NAME},
+ {"kerberosErrorContactingServer",
+ IDS_SETTINGS_KERBEROS_ERROR_CONTACTING_SERVER},
+ {"kerberosErrorPasswordInvalid",
+ IDS_SETTINGS_KERBEROS_ERROR_PASSWORD_INVALID},
+ {"kerberosErrorPasswordExpired",
+ IDS_SETTINGS_KERBEROS_ERROR_PASSWORD_EXPIRED},
+ {"kerberosErrorKdcEncType", IDS_SETTINGS_KERBEROS_ERROR_KDC_ENC_TYPE},
+ {"kerberosErrorGeneral", IDS_SETTINGS_KERBEROS_ERROR_GENERAL},
+ {"kerberosConfigErrorSectionNestedInGroup",
+ IDS_SETTINGS_KERBEROS_CONFIG_ERROR_SECTION_NESTED_IN_GROUP},
+ {"kerberosConfigErrorSectionSyntax",
+ IDS_SETTINGS_KERBEROS_CONFIG_ERROR_SECTION_SYNTAX},
+ {"kerberosConfigErrorExpectedOpeningCurlyBrace",
+ IDS_SETTINGS_KERBEROS_CONFIG_ERROR_EXPECTED_OPENING_CURLY_BRACE},
+ {"kerberosConfigErrorExtraCurlyBrace",
+ IDS_SETTINGS_KERBEROS_CONFIG_ERROR_EXTRA_CURLY_BRACE},
+ {"kerberosConfigErrorRelationSyntax",
+ IDS_SETTINGS_KERBEROS_CONFIG_ERROR_RELATION_SYNTAX_ERROR},
+ {"kerberosConfigErrorKeyNotSupported",
+ IDS_SETTINGS_KERBEROS_CONFIG_ERROR_KEY_NOT_SUPPORTED},
+ {"kerberosConfigErrorSectionNotSupported",
+ IDS_SETTINGS_KERBEROS_CONFIG_ERROR_SECTION_NOT_SUPPORTED},
+ {"kerberosConfigErrorKrb5FailedToParse",
+ IDS_SETTINGS_KERBEROS_CONFIG_ERROR_KRB5_FAILED_TO_PARSE},
+ {"addKerberosAccountRefreshButtonLabel",
+ IDS_SETTINGS_ADD_KERBEROS_ACCOUNT_REFRESH_BUTTON_LABEL},
+ {"addKerberosAccount", IDS_SETTINGS_ADD_KERBEROS_ACCOUNT},
+ {"refreshKerberosAccount", IDS_SETTINGS_REFRESH_KERBEROS_ACCOUNT},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ PrefService* local_state = g_browser_process->local_state();
+
+ // Whether the 'Remember password' checkbox is enabled.
+ html_source->AddBoolean(
+ "kerberosRememberPasswordEnabled",
+ local_state->GetBoolean(prefs::kKerberosRememberPasswordEnabled));
+
+ // Kerberos default configuration.
+ html_source->AddString(
+ "defaultKerberosConfig",
+ chromeos::KerberosCredentialsManager::GetDefaultKerberosConfig());
+}
+
+void AddLockScreenPageStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"lockScreenNotificationTitle",
+ IDS_ASH_SETTINGS_LOCK_SCREEN_NOTIFICATION_TITLE},
+ {"lockScreenNotificationHideSensitive",
+ IDS_ASH_SETTINGS_LOCK_SCREEN_NOTIFICATION_HIDE_SENSITIVE},
+ {"enableScreenlock", IDS_SETTINGS_PEOPLE_ENABLE_SCREENLOCK},
+ {"lockScreenNotificationShow",
+ IDS_ASH_SETTINGS_LOCK_SCREEN_NOTIFICATION_SHOW},
+ {"lockScreenPinOrPassword",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_PIN_OR_PASSWORD},
+ {"lockScreenSetupFingerprintButton",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_FINGERPRINT_SETUP_BUTTON},
+ {"lockScreenNotificationHide",
+ IDS_ASH_SETTINGS_LOCK_SCREEN_NOTIFICATION_HIDE},
+ {"lockScreenEditFingerprints",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_EDIT_FINGERPRINTS},
+ {"lockScreenPasswordOnly", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_PASSWORD_ONLY},
+ {"lockScreenChangePinButton",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_CHANGE_PIN_BUTTON},
+ {"lockScreenEditFingerprintsDescription",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_EDIT_FINGERPRINTS_DESCRIPTION},
+ {"lockScreenNumberFingerprints",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_NUM_FINGERPRINTS},
+ {"lockScreenNone", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_NONE},
+ {"lockScreenFingerprintNewName",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_NEW_FINGERPRINT_DEFAULT_NAME},
+ {"lockScreenDeleteFingerprintLabel",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_DELETE_FINGERPRINT_ARIA_LABEL},
+ {"lockScreenOptionsLock", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_OPTIONS_LOCK},
+ {"lockScreenOptionsLoginLock",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_OPTIONS_LOGIN_LOCK},
+ {"lockScreenSetupPinButton",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_SETUP_PIN_BUTTON},
+ {"lockScreenTitleLock", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_TITLE_LOCK},
+ {"lockScreenTitleLoginLock",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_TITLE_LOGIN_LOCK},
+ {"passwordPromptEnterPasswordLock",
+ IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_ENTER_PASSWORD_LOCK},
+ {"passwordPromptEnterPasswordLoginLock",
+ IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_ENTER_PASSWORD_LOGIN_LOCK},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+}
+
+void AddUsersStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"usersModifiedByOwnerLabel", IDS_SETTINGS_USERS_MODIFIED_BY_OWNER_LABEL},
+ {"guestBrowsingLabel", IDS_SETTINGS_USERS_GUEST_BROWSING_LABEL},
+ {"settingsManagedLabel", IDS_SETTINGS_USERS_MANAGED_LABEL},
+ {"showOnSigninLabel", IDS_SETTINGS_USERS_SHOW_ON_SIGNIN_LABEL},
+ {"restrictSigninLabel", IDS_SETTINGS_USERS_RESTRICT_SIGNIN_LABEL},
+ {"deviceOwnerLabel", IDS_SETTINGS_USERS_DEVICE_OWNER_LABEL},
+ {"removeUserTooltip", IDS_SETTINGS_USERS_REMOVE_USER_TOOLTIP},
+ {"addUsers", IDS_SETTINGS_USERS_ADD_USERS},
+ {"addUsersEmail", IDS_SETTINGS_USERS_ADD_USERS_EMAIL},
+ {"userExistsError", IDS_SETTINGS_USER_EXISTS_ERROR},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+}
+
+void AddGoogleAssistantStrings(content::WebUIDataSource* html_source,
+ Profile* profile) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"googleAssistantPageTitle", IDS_SETTINGS_GOOGLE_ASSISTANT},
+ {"googleAssistantEnableContext", IDS_ASSISTANT_SCREEN_CONTEXT_TITLE},
+ {"googleAssistantEnableContextDescription",
+ IDS_ASSISTANT_SCREEN_CONTEXT_DESC},
+ {"googleAssistantEnableHotword",
+ IDS_SETTINGS_GOOGLE_ASSISTANT_ENABLE_HOTWORD},
+ {"googleAssistantEnableHotwordDescription",
+ IDS_SETTINGS_GOOGLE_ASSISTANT_ENABLE_HOTWORD_DESCRIPTION},
+ {"googleAssistantVoiceSettings",
+ IDS_SETTINGS_GOOGLE_ASSISTANT_VOICE_SETTINGS},
+ {"googleAssistantVoiceSettingsDescription",
+ IDS_ASSISTANT_VOICE_MATCH_RECORDING},
+ {"googleAssistantVoiceSettingsRetrainButton",
+ IDS_SETTINGS_GOOGLE_ASSISTANT_VOICE_SETTINGS_RETRAIN},
+ {"googleAssistantEnableHotwordWithoutDspDescription",
+ IDS_SETTINGS_GOOGLE_ASSISTANT_ENABLE_HOTWORD_WITHOUT_DSP_DESCRIPTION},
+ {"googleAssistantEnableHotwordWithoutDspRecommended",
+ IDS_SETTINGS_GOOGLE_ASSISTANT_ENABLE_HOTWORD_WITHOUT_DSP_RECOMMENDED},
+ {"googleAssistantEnableHotwordWithoutDspAlwaysOn",
+ IDS_SETTINGS_GOOGLE_ASSISTANT_ENABLE_HOTWORD_WITHOUT_DSP_ALWAYS_ON},
+ {"googleAssistantEnableHotwordWithoutDspOff",
+ IDS_SETTINGS_GOOGLE_ASSISTANT_ENABLE_HOTWORD_WITHOUT_DSP_OFF},
+ {"googleAssistantEnableNotification",
+ IDS_SETTINGS_GOOGLE_ASSISTANT_ENABLE_NOTIFICATION},
+ {"googleAssistantEnableNotificationDescription",
+ IDS_SETTINGS_GOOGLE_ASSISTANT_ENABLE_NOTIFICATION_DESCRIPTION},
+ {"googleAssistantLaunchWithMicOpen",
+ IDS_SETTINGS_GOOGLE_ASSISTANT_LAUNCH_WITH_MIC_OPEN},
+ {"googleAssistantLaunchWithMicOpenDescription",
+ IDS_SETTINGS_GOOGLE_ASSISTANT_LAUNCH_WITH_MIC_OPEN_DESCRIPTION},
+ {"googleAssistantSettings", IDS_SETTINGS_GOOGLE_ASSISTANT_SETTINGS},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddBoolean("hotwordDspAvailable",
+ chromeos::IsHotwordDspAvailable());
+ html_source->AddBoolean(
+ "voiceMatchDisabled",
+ chromeos::assistant::features::IsVoiceMatchDisabled());
+}
+
+void AddPrintingStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"printingPageTitle", IDS_SETTINGS_PRINTING},
+ {"cupsPrintersTitle", IDS_SETTINGS_PRINTING_CUPS_PRINTERS},
+ {"cupsPrintersLearnMoreLabel",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTERS_LEARN_MORE_LABEL},
+ {"addCupsPrinter", IDS_SETTINGS_PRINTING_CUPS_PRINTERS_ADD_PRINTER},
+ {"editPrinter", IDS_SETTINGS_PRINTING_CUPS_PRINTERS_EDIT},
+ {"removePrinter", IDS_SETTINGS_PRINTING_CUPS_PRINTERS_REMOVE},
+ {"setupPrinter", IDS_SETTINGS_PRINTING_CUPS_PRINTER_SETUP_BUTTON},
+ {"setupPrinterAria",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_SETUP_BUTTON_ARIA},
+ {"savePrinter", IDS_SETTINGS_PRINTING_CUPS_PRINTER_SAVE_BUTTON},
+ {"savePrinterAria", IDS_SETTINGS_PRINTING_CUPS_PRINTER_SAVE_BUTTON_ARIA},
+ {"searchLabel", IDS_SETTINGS_PRINTING_CUPS_SEARCH_LABEL},
+ {"noSearchResults", IDS_SEARCH_NO_RESULTS},
+ {"printerDetailsTitle", IDS_SETTINGS_PRINTING_CUPS_PRINTER_DETAILS_TITLE},
+ {"printerName", IDS_SETTINGS_PRINTING_CUPS_PRINTER_DETAILS_NAME},
+ {"printerModel", IDS_SETTINGS_PRINTING_CUPS_PRINTER_DETAILS_MODEL},
+ {"printerQueue", IDS_SETTINGS_PRINTING_CUPS_PRINTER_DETAILS_QUEUE},
+ {"savedPrintersTitle", IDS_SETTINGS_PRINTING_CUPS_SAVED_PRINTERS_TITLE},
+ {"savedPrintersCountMany",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTERS_SAVED_PRINTERS_COUNT_MANY},
+ {"savedPrintersCountOne",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTERS_SAVED_PRINTERS_COUNT_ONE},
+ {"savedPrintersCountNone",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTERS_SAVED_PRINTERS_COUNT_NONE},
+ {"showMorePrinters", IDS_SETTINGS_PRINTING_CUPS_SHOW_MORE},
+ {"addPrintersNearbyTitle",
+ IDS_SETTINGS_PRINTING_CUPS_ADD_PRINTERS_NEARBY_TITLE},
+ {"addPrintersManuallyTitle",
+ IDS_SETTINGS_PRINTING_CUPS_ADD_PRINTERS_MANUALLY_TITLE},
+ {"manufacturerAndModelDialogTitle",
+ IDS_SETTINGS_PRINTING_CUPS_SELECT_MANUFACTURER_AND_MODEL_TITLE},
+ {"nearbyPrintersListTitle",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTERS_AVAILABLE_PRINTERS},
+ {"nearbyPrintersCountMany",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTERS_AVAILABLE_PRINTERS_COUNT_MANY},
+ {"nearbyPrintersCountOne",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTERS_AVAILABLE_PRINTER_COUNT_ONE},
+ {"nearbyPrintersCountNone",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTERS_AVAILABLE_PRINTER_COUNT_NONE},
+ {"nearbyPrintersListDescription",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTERS_ADD_DETECTED_OR_NEW_PRINTER},
+ {"manufacturerAndModelAdditionalInformation",
+ IDS_SETTINGS_PRINTING_CUPS_MANUFACTURER_MODEL_ADDITIONAL_INFORMATION},
+ {"addPrinterButtonText",
+ IDS_SETTINGS_PRINTING_CUPS_ADD_PRINTER_BUTTON_ADD},
+ {"printerDetailsAdvanced", IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADVANCED},
+ {"printerDetailsA11yLabel",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADVANCED_ACCESSIBILITY_LABEL},
+ {"printerAddress", IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADVANCED_ADDRESS},
+ {"printerProtocol", IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADVANCED_PROTOCOL},
+ {"printerURI", IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADVANCED_URI},
+ {"manuallyAddPrinterButtonText",
+ IDS_SETTINGS_PRINTING_CUPS_ADD_PRINTER_BUTTON_MANUAL_ADD},
+ {"discoverPrintersButtonText",
+ IDS_SETTINGS_PRINTING_CUPS_ADD_PRINTER_BUTTON_DISCOVER_PRINTERS},
+ {"printerProtocolIpp", IDS_SETTINGS_PRINTING_CUPS_PRINTER_PROTOCOL_IPP},
+ {"printerProtocolIpps", IDS_SETTINGS_PRINTING_CUPS_PRINTER_PROTOCOL_IPPS},
+ {"printerProtocolHttp", IDS_SETTINGS_PRINTING_CUPS_PRINTER_PROTOCOL_HTTP},
+ {"printerProtocolHttps",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_PROTOCOL_HTTPS},
+ {"printerProtocolAppSocket",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_PROTOCOL_APP_SOCKET},
+ {"printerProtocolLpd", IDS_SETTINGS_PRINTING_CUPS_PRINTER_PROTOCOL_LPD},
+ {"printerProtocolUsb", IDS_SETTINGS_PRINTING_CUPS_PRINTER_PROTOCOL_USB},
+ {"printerProtocolIppUsb",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_PROTOCOL_IPPUSB},
+ {"printerConfiguringMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_CONFIGURING_MESSAGE},
+ {"printerManufacturer", IDS_SETTINGS_PRINTING_CUPS_PRINTER_MANUFACTURER},
+ {"selectDriver", IDS_SETTINGS_PRINTING_CUPS_PRINTER_SELECT_DRIVER},
+ {"selectDriverButtonText",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_BUTTON_SELECT_DRIVER},
+ {"selectDriverButtonAriaLabel",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_BUTTON_SELECT_DRIVER_ARIA_LABEL},
+ {"selectDriverErrorMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_INVALID_DRIVER},
+ {"printerAddedSuccessfulMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_PRINTER_DONE_MESSAGE},
+ {"printerEditedSuccessfulMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_EDITED_PRINTER_DONE_MESSAGE},
+ {"printerUnavailableMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_UNAVAILABLE_MESSAGE},
+ {"noPrinterNearbyMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_NO_PRINTER_NEARBY},
+ {"searchingNearbyPrinters",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_SEARCHING_NEARBY_PRINTER},
+ {"printerAddedFailedMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_PRINTER_ERROR_MESSAGE},
+ {"printerAddedFatalErrorMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_PRINTER_FATAL_ERROR_MESSAGE},
+ {"printerAddedUnreachableMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_PRINTER_PRINTER_UNREACHABLE_MESSAGE},
+ {"printerAddedPpdTooLargeMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_PRINTER_PPD_TOO_LARGE_MESSAGE},
+ {"printerAddedInvalidPpdMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_PRINTER_INVALID_PPD_MESSAGE},
+ {"printerAddedPpdNotFoundMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_PRINTER_PPD_NOT_FOUND},
+ {"printerAddedPpdUnretrievableMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_PRINTER_PPD_UNRETRIEVABLE},
+ {"printerAddedNativePrintersNotAllowedMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_ADDED_NATIVE_PRINTERS_NOT_ALLOWED_MESSAGE},
+ {"editPrinterInvalidPrinterUpdate",
+ IDS_SETTINGS_PRINTING_CUPS_EDIT_PRINTER_INVALID_PRINTER_UPDATE},
+ {"requireNetworkMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_REQUIRE_INTERNET_MESSAGE},
+ {"checkNetworkMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_CHECK_CONNECTION_MESSAGE},
+ {"noInternetConnection",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_NO_INTERNET_CONNECTION},
+ {"checkNetworkAndTryAgain",
+ IDS_SETTINGS_PRINTING_CUPS_PRINTER_CONNECT_TO_NETWORK_SUBTEXT},
+ {"editPrinterDialogTitle",
+ IDS_SETTINGS_PRINTING_CUPS_EDIT_PRINTER_DIALOG_TITLE},
+ {"editPrinterButtonText", IDS_SETTINGS_PRINTING_CUPS_EDIT_PRINTER_BUTTON},
+ {"currentPpdMessage",
+ IDS_SETTINGS_PRINTING_CUPS_EDIT_PRINTER_CURRENT_PPD_MESSAGE},
+ {"printerEulaNotice", IDS_SETTINGS_PRINTING_CUPS_EULA_NOTICE},
+ {"ippPrinterUnreachable", IDS_SETTINGS_PRINTING_CUPS_IPP_URI_UNREACHABLE},
+ {"generalPrinterDialogError",
+ IDS_SETTINGS_PRINTING_CUPS_DIALOG_GENERAL_ERROR},
+ {"printServerButtonText", IDS_SETTINGS_PRINTING_CUPS_PRINT_SERVER},
+ {"addPrintServerTitle",
+ IDS_SETTINGS_PRINTING_CUPS_ADD_PRINT_SERVER_TITLE},
+ {"printServerAddress", IDS_SETTINGS_PRINTING_CUPS_PRINT_SERVER_ADDRESS},
+ {"printServerFoundZeroPrinters",
+ IDS_SETTINGS_PRINTING_CUPS_PRINT_SERVER_FOUND_ZERO_PRINTERS},
+ {"printServerFoundOnePrinter",
+ IDS_SETTINGS_PRINTING_CUPS_PRINT_SERVER_FOUND_ONE_PRINTER},
+ {"printServerFoundManyPrinters",
+ IDS_SETTINGS_PRINTING_CUPS_PRINT_SERVER_FOUND_MANY_PRINTERS},
+ {"printServerInvalidUrlAddress",
+ IDS_SETTINGS_PRINTING_CUPS_PRINT_SERVER_INVALID_URL_ADDRESS},
+ {"printServerConnectionError",
+ IDS_SETTINGS_PRINTING_CUPS_PRINT_SERVER_CONNECTION_ERROR},
+ {"printServerConfigurationErrorMessage",
+ IDS_SETTINGS_PRINTING_CUPS_PRINT_SERVER_REACHABLE_BUT_CANNOT_ADD},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddString("printingCUPSPrintLearnMoreUrl",
+ GetHelpUrlWithBoard(chrome::kCupsPrintLearnMoreURL));
+ html_source->AddString(
+ "printingCUPSPrintPpdLearnMoreUrl",
+ GetHelpUrlWithBoard(chrome::kCupsPrintPPDLearnMoreURL));
+ html_source->AddBoolean(
+ "consumerPrintServerUiEnabled",
+ base::FeatureList::IsEnabled(::features::kPrintServerUi));
+}
+
+void AddSearchInSettingsStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"searchPrompt", IDS_SETTINGS_SEARCH_PROMPT},
+ {"searchNoResults", IDS_SEARCH_NO_RESULTS},
+ {"searchResults", IDS_SEARCH_RESULTS},
+ // TODO(dpapad): IDS_DOWNLOAD_CLEAR_SEARCH and IDS_HISTORY_CLEAR_SEARCH
+ // are identical, merge them to one and re-use here.
+ {"clearSearch", IDS_DOWNLOAD_CLEAR_SEARCH},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddString(
+ "searchNoOsResultsHelp",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_SEARCH_NO_RESULTS_HELP,
+ base::ASCIIToUTF16(chrome::kOsSettingsSearchHelpURL)));
+
+ html_source->AddBoolean(
+ "newOsSettingsSearch",
+ base::FeatureList::IsEnabled(chromeos::features::kNewOsSettingsSearch));
+}
+
+void AddDateTimeStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"dateTimePageTitle", IDS_SETTINGS_DATE_TIME},
+ {"timeZone", IDS_SETTINGS_TIME_ZONE},
+ {"selectTimeZoneResolveMethod",
+ IDS_SETTINGS_SELECT_TIME_ZONE_RESOLVE_METHOD},
+ {"timeZoneGeolocation", IDS_SETTINGS_TIME_ZONE_GEOLOCATION},
+ {"timeZoneButton", IDS_SETTINGS_TIME_ZONE_BUTTON},
+ {"timeZoneSubpageTitle", IDS_SETTINGS_TIME_ZONE_SUBPAGE_TITLE},
+ {"setTimeZoneAutomaticallyDisabled",
+ IDS_SETTINGS_TIME_ZONE_DETECTION_MODE_DISABLED},
+ {"setTimeZoneAutomaticallyOn",
+ IDS_SETTINGS_TIME_ZONE_DETECTION_SET_AUTOMATICALLY},
+ {"setTimeZoneAutomaticallyOff",
+ IDS_SETTINGS_TIME_ZONE_DETECTION_CHOOSE_FROM_LIST},
+ {"setTimeZoneAutomaticallyIpOnlyDefault",
+ IDS_SETTINGS_TIME_ZONE_DETECTION_MODE_IP_ONLY_DEFAULT},
+ {"setTimeZoneAutomaticallyWithWiFiAccessPointsData",
+ IDS_SETTINGS_TIME_ZONE_DETECTION_MODE_SEND_WIFI_AP},
+ {"setTimeZoneAutomaticallyWithAllLocationInfo",
+ IDS_SETTINGS_TIME_ZONE_DETECTION_MODE_SEND_ALL_INFO},
+ {"use24HourClock", IDS_SETTINGS_USE_24_HOUR_CLOCK},
+ {"setDateTime", IDS_SETTINGS_SET_DATE_TIME},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddString(
+ "timeZoneSettingsLearnMoreURL",
+ base::ASCIIToUTF16(base::StringPrintf(
+ chrome::kTimeZoneSettingsLearnMoreURL,
+ g_browser_process->GetApplicationLocale().c_str())));
+}
+
+void AddAboutStrings(content::WebUIDataSource* html_source, Profile* profile) {
+ // Top level About page strings.
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"aboutProductLogoAlt", IDS_SHORT_PRODUCT_LOGO_ALT_TEXT},
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
+ {"aboutReportAnIssue", IDS_SETTINGS_ABOUT_PAGE_REPORT_AN_ISSUE},
+#endif
+ {"aboutRelaunch", IDS_SETTINGS_ABOUT_PAGE_RELAUNCH},
+ {"aboutUpgradeCheckStarted", IDS_SETTINGS_ABOUT_UPGRADE_CHECK_STARTED},
+ {"aboutUpgradeRelaunch", IDS_SETTINGS_UPGRADE_SUCCESSFUL_RELAUNCH},
+ {"aboutUpgradeUpdating", IDS_SETTINGS_UPGRADE_UPDATING},
+ {"aboutUpgradeUpdatingPercent", IDS_SETTINGS_UPGRADE_UPDATING_PERCENT},
+ {"aboutGetHelpUsingChrome", IDS_SETTINGS_GET_HELP_USING_CHROME},
+ {"aboutPageTitle", IDS_SETTINGS_ABOUT_PROGRAM},
+ {"aboutProductTitle", IDS_PRODUCT_NAME},
+
+ {"aboutEndOfLifeTitle", IDS_SETTINGS_ABOUT_PAGE_END_OF_LIFE_TITLE},
+ {"aboutRelaunchAndPowerwash",
+ IDS_SETTINGS_ABOUT_PAGE_RELAUNCH_AND_POWERWASH},
+ {"aboutRollbackInProgress", IDS_SETTINGS_UPGRADE_ROLLBACK_IN_PROGRESS},
+ {"aboutRollbackSuccess", IDS_SETTINGS_UPGRADE_ROLLBACK_SUCCESS},
+ {"aboutUpgradeUpdatingChannelSwitch",
+ IDS_SETTINGS_UPGRADE_UPDATING_CHANNEL_SWITCH},
+ {"aboutUpgradeSuccessChannelSwitch",
+ IDS_SETTINGS_UPGRADE_SUCCESSFUL_CHANNEL_SWITCH},
+ {"aboutTPMFirmwareUpdateTitle",
+ IDS_SETTINGS_ABOUT_TPM_FIRMWARE_UPDATE_TITLE},
+ {"aboutTPMFirmwareUpdateDescription",
+ IDS_SETTINGS_ABOUT_TPM_FIRMWARE_UPDATE_DESCRIPTION},
+
+ // About page, channel switcher dialog.
+ {"aboutChangeChannel", IDS_SETTINGS_ABOUT_PAGE_CHANGE_CHANNEL},
+ {"aboutChangeChannelAndPowerwash",
+ IDS_SETTINGS_ABOUT_PAGE_CHANGE_CHANNEL_AND_POWERWASH},
+ {"aboutDelayedWarningMessage",
+ IDS_SETTINGS_ABOUT_PAGE_DELAYED_WARNING_MESSAGE},
+ {"aboutDelayedWarningTitle", IDS_SETTINGS_ABOUT_PAGE_DELAYED_WARNING_TITLE},
+ {"aboutPowerwashWarningMessage",
+ IDS_SETTINGS_ABOUT_PAGE_POWERWASH_WARNING_MESSAGE},
+ {"aboutPowerwashWarningTitle",
+ IDS_SETTINGS_ABOUT_PAGE_POWERWASH_WARNING_TITLE},
+ {"aboutUnstableWarningMessage",
+ IDS_SETTINGS_ABOUT_PAGE_UNSTABLE_WARNING_MESSAGE},
+ {"aboutUnstableWarningTitle",
+ IDS_SETTINGS_ABOUT_PAGE_UNSTABLE_WARNING_TITLE},
+ {"aboutChannelDialogBeta", IDS_SETTINGS_ABOUT_PAGE_DIALOG_CHANNEL_BETA},
+ {"aboutChannelDialogDev", IDS_SETTINGS_ABOUT_PAGE_DIALOG_CHANNEL_DEV},
+ {"aboutChannelDialogStable", IDS_SETTINGS_ABOUT_PAGE_DIALOG_CHANNEL_STABLE},
+
+ // About page, update warning dialog.
+ {"aboutUpdateWarningMessage",
+ IDS_SETTINGS_ABOUT_PAGE_UPDATE_WARNING_MESSAGE},
+ {"aboutUpdateWarningTitle", IDS_SETTINGS_ABOUT_PAGE_UPDATE_WARNING_TITLE},
+
+ // Detailed build information
+ {"aboutBuildDetailsTitle", IDS_OS_SETTINGS_ABOUT_PAGE_BUILD_DETAILS},
+ {"aboutChannelBeta", IDS_SETTINGS_ABOUT_PAGE_CURRENT_CHANNEL_BETA},
+ {"aboutChannelCanary", IDS_SETTINGS_ABOUT_PAGE_CURRENT_CHANNEL_CANARY},
+ {"aboutChannelDev", IDS_SETTINGS_ABOUT_PAGE_CURRENT_CHANNEL_DEV},
+ {"aboutChannelLabel", IDS_SETTINGS_ABOUT_PAGE_CHANNEL},
+ {"aboutChannelStable", IDS_SETTINGS_ABOUT_PAGE_CURRENT_CHANNEL_STABLE},
+ {"aboutCheckForUpdates", IDS_SETTINGS_ABOUT_PAGE_CHECK_FOR_UPDATES},
+ {"aboutCurrentlyOnChannel", IDS_SETTINGS_ABOUT_PAGE_CURRENT_CHANNEL},
+ {"aboutDetailedBuildInfo", IDS_SETTINGS_ABOUT_PAGE_DETAILED_BUILD_INFO},
+ {version_ui::kApplicationLabel, IDS_PRODUCT_NAME},
+ {version_ui::kPlatform, IDS_PLATFORM_LABEL},
+ {version_ui::kFirmwareVersion, IDS_VERSION_UI_FIRMWARE_VERSION},
+ {version_ui::kARC, IDS_ARC_LABEL},
+ {"aboutBuildDetailsCopyTooltipLabel",
+ IDS_OS_SETTINGS_ABOUT_PAGE_BUILD_DETAILS_COPY_TOOLTIP_LABEL},
+ {"aboutIsArcStatusTitle", IDS_OS_SETTINGS_ABOUT_ARC_STATUS_TITLE},
+ {"aboutIsDeveloperModeTitle", IDS_OS_SETTINGS_ABOUT_DEVELOPER_MODE},
+ {"isEnterpriseManagedTitle",
+ IDS_OS_SETTINGS_ABOUT_PAGE_ENTERPRISE_ENNROLLED_TITLE},
+ {"aboutOsPageTitle", IDS_SETTINGS_ABOUT_OS},
+ {"aboutGetHelpUsingChromeOs", IDS_SETTINGS_GET_HELP_USING_CHROME_OS},
+ {"aboutOsProductTitle", IDS_PRODUCT_OS_NAME},
+ {"aboutReleaseNotesOffline", IDS_SETTINGS_ABOUT_PAGE_RELEASE_NOTES},
+ {"aboutShowReleaseNotes", IDS_SETTINGS_ABOUT_PAGE_SHOW_RELEASE_NOTES},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddString("aboutTPMFirmwareUpdateLearnMoreURL",
+ chrome::kTPMFirmwareUpdateLearnMoreURL);
+ html_source->AddString(
+ "aboutUpgradeUpToDate",
+ ui::SubstituteChromeOSDeviceType(IDS_SETTINGS_UPGRADE_UP_TO_DATE));
+ html_source->AddString("managementPage",
+ ManagementUI::GetManagementPageSubtitle(profile));
+}
+
+void AddResetStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"resetPageTitle", IDS_SETTINGS_RESET},
+ {"powerwashTitle", IDS_SETTINGS_FACTORY_RESET},
+ {"powerwashDialogTitle", IDS_SETTINGS_FACTORY_RESET_HEADING},
+ {"powerwashDialogButton", IDS_SETTINGS_RESTART},
+ {"powerwashButton", IDS_SETTINGS_FACTORY_RESET_BUTTON_LABEL},
+ {"powerwashDialogExplanation", IDS_SETTINGS_FACTORY_RESET_WARNING},
+ {"powerwashLearnMoreUrl", IDS_FACTORY_RESET_HELP_URL},
+ {"powerwashButtonRoleDescription",
+ IDS_SETTINGS_FACTORY_RESET_BUTTON_ROLE},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddString(
+ "powerwashDescription",
+ l10n_util::GetStringFUTF16(IDS_SETTINGS_FACTORY_RESET_DESCRIPTION,
+ l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)));
+}
+
+void AddSearchStrings(content::WebUIDataSource* html_source, Profile* profile) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"osSearchEngineLabel", IDS_OS_SETTINGS_SEARCH_ENGINE_LABEL},
+ {"searchGoogleAssistant", IDS_SETTINGS_SEARCH_GOOGLE_ASSISTANT},
+ {"searchGoogleAssistantEnabled",
+ IDS_SETTINGS_SEARCH_GOOGLE_ASSISTANT_ENABLED},
+ {"searchGoogleAssistantDisabled",
+ IDS_SETTINGS_SEARCH_GOOGLE_ASSISTANT_DISABLED},
+ {"searchGoogleAssistantOn", IDS_SETTINGS_SEARCH_GOOGLE_ASSISTANT_ON},
+ {"searchGoogleAssistantOff", IDS_SETTINGS_SEARCH_GOOGLE_ASSISTANT_OFF},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ // NOTE: This will be false when the flag is disabled.
+ const bool is_assistant_allowed =
+ ::assistant::IsAssistantAllowedForProfile(profile) ==
+ ash::mojom::AssistantAllowedState::ALLOWED;
+ html_source->AddBoolean("isAssistantAllowed", is_assistant_allowed);
+ html_source->AddLocalizedString("osSearchPageTitle",
+ is_assistant_allowed
+ ? IDS_SETTINGS_SEARCH_AND_ASSISTANT
+ : IDS_SETTINGS_SEARCH);
+ html_source->AddString("searchExplanation",
+ l10n_util::GetStringFUTF16(
+ IDS_SETTINGS_SEARCH_EXPLANATION,
+ base::ASCIIToUTF16(chrome::kOmniboxLearnMoreURL)));
+ html_source->AddString(
+ "osSearchEngineTooltip",
+ ui::SubstituteChromeOSDeviceType(IDS_OS_SETTINGS_SEARCH_ENGINE_TOOLTIP));
+}
+
+void AddPrivacyStrings(content::WebUIDataSource* html_source) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"privacyPageTitle", IDS_SETTINGS_PRIVACY},
+ {"enableLogging", IDS_SETTINGS_ENABLE_LOGGING_PREF},
+ {"enableLoggingDesc", IDS_SETTINGS_ENABLE_LOGGING_PREF_DESC},
+ {"wakeOnWifi", IDS_SETTINGS_WAKE_ON_WIFI_DESCRIPTION},
+ {"enableContentProtectionAttestation",
+ IDS_SETTINGS_ENABLE_CONTENT_PROTECTION_ATTESTATION},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ html_source->AddString("syncAndGoogleServicesLearnMoreURL",
+ chrome::kSyncAndGoogleServicesLearnMoreURL);
+ ::settings::AddPersonalizationOptionsStrings(html_source);
+}
+
+void AddPeoplePageStrings(content::WebUIDataSource* html_source,
+ Profile* profile) {
+ static constexpr webui::LocalizedString kLocalizedStrings[] = {
+ {"osPeoplePageTitle", IDS_OS_SETTINGS_PEOPLE},
+ {"accountManagerSubMenuLabel",
+ IDS_SETTINGS_ACCOUNT_MANAGER_SUBMENU_LABEL},
+ {"accountManagerPageTitle", IDS_SETTINGS_ACCOUNT_MANAGER_PAGE_TITLE},
+ {"kerberosAccountsSubMenuLabel",
+ IDS_SETTINGS_KERBEROS_ACCOUNTS_SUBMENU_LABEL},
+ {"accountManagerPageTitle", IDS_SETTINGS_ACCOUNT_MANAGER_PAGE_TITLE},
+ {"kerberosAccountsPageTitle", IDS_SETTINGS_KERBEROS_ACCOUNTS_PAGE_TITLE},
+ {"lockScreenFingerprintTitle",
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_FINGERPRINT_SUBPAGE_TITLE},
+ {"manageOtherPeople", IDS_SETTINGS_PEOPLE_MANAGE_OTHER_PEOPLE},
+ {"osSyncPageTitle", IDS_OS_SETTINGS_SYNC_PAGE_TITLE},
+ {"syncAndNonPersonalizedServices",
+ IDS_SETTINGS_SYNC_SYNC_AND_NON_PERSONALIZED_SERVICES},
+ {"syncDisconnectConfirm", IDS_SETTINGS_SYNC_DISCONNECT_CONFIRM},
+ };
+ AddLocalizedStringsBulk(html_source, kLocalizedStrings);
+
+ // Toggles the Chrome OS Account Manager submenu in the People section.
+ html_source->AddBoolean("isAccountManagerEnabled",
+ chromeos::IsAccountManagerAvailable(profile));
+
+ if (chromeos::features::IsSplitSyncConsentEnabled()) {
+ static constexpr webui::LocalizedString kTurnOffStrings[] = {
+ {"syncDisconnect", IDS_SETTINGS_PEOPLE_SYNC_TURN_OFF},
+ {"syncDisconnectTitle",
+ IDS_SETTINGS_TURN_OFF_SYNC_AND_SIGN_OUT_DIALOG_TITLE},
+ };
+ AddLocalizedStringsBulk(html_source, kTurnOffStrings);
+ } else {
+ static constexpr webui::LocalizedString kSignOutStrings[] = {
+ {"syncDisconnect", IDS_SETTINGS_PEOPLE_SIGN_OUT},
+ {"syncDisconnectTitle", IDS_SETTINGS_SYNC_DISCONNECT_TITLE},
+ };
+ AddLocalizedStringsBulk(html_source, kSignOutStrings);
+ }
+
+ std::string sync_dashboard_url =
+ google_util::AppendGoogleLocaleParam(
+ GURL(chrome::kSyncGoogleDashboardURL),
+ g_browser_process->GetApplicationLocale())
+ .spec();
+
+ html_source->AddString(
+ "syncDisconnectExplanation",
+ l10n_util::GetStringFUTF8(IDS_SETTINGS_SYNC_DISCONNECT_EXPLANATION,
+ base::ASCIIToUTF16(sync_dashboard_url)));
+
+ AddAccountManagerPageStrings(html_source);
+ AddKerberosAccountsPageStrings(html_source);
+ AddKerberosAddAccountDialogStrings(html_source);
+ AddLockScreenPageStrings(html_source);
+ AddFingerprintListStrings(html_source);
+ AddFingerprintStrings(html_source);
+ AddSetupFingerprintDialogStrings(html_source);
+ AddSetupPinDialogStrings(html_source);
+ AddSyncControlsStrings(html_source);
+
+ ::settings::AddSyncControlsStrings(html_source);
+ ::settings::AddSyncAccountControlStrings(html_source);
+ ::settings::AddPasswordPromptDialogStrings(html_source);
+ ::settings::AddSyncPageStrings(html_source);
+}
+
+void AddPageVisibilityStrings(content::WebUIDataSource* html_source) {
+ PrefService* local_state = g_browser_process->local_state();
+ // Toggles the Chrome OS Kerberos Accounts submenu in the People section.
+ // Note that the handler is also dependent on this pref.
+ html_source->AddBoolean("isKerberosEnabled",
+ local_state->GetBoolean(prefs::kKerberosEnabled));
+}
+
+} // namespace
+
+OsSettingsLocalizedStringsProvider::OsSettingsLocalizedStringsProvider(
+ Profile* profile,
+ local_search_service::mojom::LocalSearchService* local_search_service) {
+ local_search_service->GetIndex(
+ local_search_service::mojom::LocalSearchService::IndexId::CROS_SETTINGS,
+ index_remote_.BindNewPipeAndPassReceiver());
+
+ // Add per-page string providers.
+ // TODO(khorimoto): Add providers for the remaining pages.
+ per_page_providers_.push_back(
+ std::make_unique<InternetStringsProvider>(profile, /*delegate=*/this));
+}
+
+OsSettingsLocalizedStringsProvider::~OsSettingsLocalizedStringsProvider() =
+ default;
+
+void OsSettingsLocalizedStringsProvider::AddOsLocalizedStrings(
+ content::WebUIDataSource* html_source,
+ Profile* profile) {
+ for (const auto& per_page_provider : per_page_providers_)
+ per_page_provider->AddUiStrings(html_source);
+
+ // TODO(khorimoto): Migrate these to OsSettingsPerPageStringsProvider
+ // instances.
+ AddAboutStrings(html_source, profile);
+ AddA11yStrings(html_source);
+ AddAndroidAppStrings(html_source);
+ AddAppManagementStrings(html_source);
+ AddAppsStrings(html_source);
+ AddBluetoothStrings(html_source);
+ AddChromeOSUserStrings(html_source, profile);
+ AddCommonStrings(html_source, profile);
+ AddCrostiniStrings(html_source, profile);
+ AddDateTimeStrings(html_source);
+ AddDeviceStrings(html_source);
+ AddFilesStrings(html_source);
+ AddGoogleAssistantStrings(html_source, profile);
+ AddLanguagesStrings(html_source);
+ AddMultideviceStrings(html_source);
+ AddParentalControlStrings(html_source, profile);
+ AddPageVisibilityStrings(html_source);
+ AddPeoplePageStrings(html_source, profile);
+ AddPersonalizationStrings(html_source);
+ AddPluginVmStrings(html_source, profile);
+ AddPrintingStrings(html_source);
+ AddPrivacyStrings(html_source);
+ AddResetStrings(html_source);
+ AddSearchInSettingsStrings(html_source);
+ AddSearchStrings(html_source, profile);
+ AddUsersStrings(html_source);
+
+ policy_indicator::AddLocalizedStrings(html_source);
+
+ html_source->UseStringsJs();
+}
+
+const SearchConcept*
+OsSettingsLocalizedStringsProvider::GetCanonicalTagMetadata(
+ int canonical_message_id) const {
+ const auto it = canonical_id_to_metadata_map_.find(canonical_message_id);
+ if (it == canonical_id_to_metadata_map_.end())
+ return nullptr;
+ return it->second;
+}
+
+void OsSettingsLocalizedStringsProvider::Shutdown() {
+ index_remote_.reset();
+}
+
+void OsSettingsLocalizedStringsProvider::AddSearchTags(
+ const std::vector<SearchConcept>& tags_group) {
+ index_remote_->AddOrUpdate(ConceptVectorToDataPtrVector(tags_group),
+ /*callback=*/base::DoNothing());
+
+ // Add each concept to the map. Note that it is safe to take the address of
+ // each concept because all concepts are allocated via static
+ // base::NoDestructor objects in the Get*SearchConcepts() helper functions.
+ for (const auto& concept : tags_group)
+ canonical_id_to_metadata_map_[concept.canonical_message_id] = &concept;
+}
+
+void OsSettingsLocalizedStringsProvider::RemoveSearchTags(
+ const std::vector<SearchConcept>& tags_group) {
+ std::vector<std::string> ids;
+ for (const auto& concept : tags_group) {
+ canonical_id_to_metadata_map_.erase(concept.canonical_message_id);
+ ids.push_back(base::NumberToString(concept.canonical_message_id));
+ }
+
+ index_remote_->Delete(ids, /*callback=*/base::DoNothing());
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.h b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.h
new file mode 100644
index 00000000000..c0d8c5adcd2
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.h
@@ -0,0 +1,91 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_OS_SETTINGS_LOCALIZED_STRINGS_PROVIDER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_OS_SETTINGS_LOCALIZED_STRINGS_PROVIDER_H_
+
+#include <memory>
+#include <unordered_map>
+#include <vector>
+
+#include "chrome/browser/ui/webui/settings/chromeos/os_settings_per_page_strings_provider.h"
+#include "chrome/services/local_search_service/public/mojom/local_search_service.mojom.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "mojo/public/cpp/bindings/remote.h"
+
+class Profile;
+
+namespace content {
+class WebUIDataSource;
+} // namespace content
+
+namespace chromeos {
+namespace settings {
+
+struct SearchConcept;
+
+// Provides two types of localized strings for OS settings:
+//
+// (1) UI strings: Strings displayed in the normal settings UI. This contains
+// strings such as headers, labels, instructional notes, etc. These strings
+// are added directly to the settings app's WebUIDataSource before the app
+// starts up via the static AddOsLocalizedStrings() function and are
+// accessible within settings via loadTimeData.
+//
+// (2) Search tags: Strings used as potential matches for user search queries
+// within settings. These strings don't appear in the normal UI; instead,
+// they specify actions which can be taken in settings. When a user types a
+// search query in settings, we compare the query against these strings to
+// look for potential matches. For each potential search result, there is a
+// "canonical" tag which represents a common phrase, and zero or more
+// alternate phrases (e.g., canonical: "Display settings", alternate:
+// "Monitor settings").
+//
+// Since some of the settings sections may be unavailable (e.g., we don't
+// show Bluetooth settings unless the device has Bluetooth capabilities),
+// these strings are added/removed according to the Add/Remove*SearchTags()
+// instance functions.
+class OsSettingsLocalizedStringsProvider
+ : public KeyedService,
+ public OsSettingsPerPageStringsProvider::Delegate {
+ public:
+ OsSettingsLocalizedStringsProvider(
+ Profile* profile,
+ local_search_service::mojom::LocalSearchService* local_search_service);
+ OsSettingsLocalizedStringsProvider(
+ const OsSettingsLocalizedStringsProvider& other) = delete;
+ OsSettingsLocalizedStringsProvider& operator=(
+ const OsSettingsLocalizedStringsProvider& other) = delete;
+ ~OsSettingsLocalizedStringsProvider() override;
+
+ // Adds the strings needed by the OS settings page to |html_source|
+ // This function causes |html_source| to expose a strings.js file from its
+ // source which contains a mapping from string's name to its translated value.
+ void AddOsLocalizedStrings(content::WebUIDataSource* html_source,
+ Profile* profile);
+
+ // Returns the tag metadata associated with |canonical_message_id|, which must
+ // be one of the canonical IDS_SETTINGS_TAG_* identifiers used for a search
+ // tag. If no metadata is available or if |canonical_message_id| instead
+ // refers to an alternate tag's ID, null is returned.
+ const SearchConcept* GetCanonicalTagMetadata(int canonical_message_id) const;
+
+ private:
+ // KeyedService:
+ void Shutdown() override;
+
+ // OsSettingsPerPageStringsProvider::Delegate:
+ void AddSearchTags(const std::vector<SearchConcept>& tags_group) override;
+ void RemoveSearchTags(const std::vector<SearchConcept>& tags_group) override;
+
+ std::vector<std::unique_ptr<OsSettingsPerPageStringsProvider>>
+ per_page_providers_;
+ mojo::Remote<local_search_service::mojom::Index> index_remote_;
+ std::unordered_map<int, const SearchConcept*> canonical_id_to_metadata_map_;
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_OS_SETTINGS_LOCALIZED_STRINGS_PROVIDER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_factory.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_factory.cc
new file mode 100644
index 00000000000..8375790e5ca
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_factory.cc
@@ -0,0 +1,66 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_factory.h"
+
+#include "chrome/browser/local_search_service/local_search_service_proxy.h"
+#include "chrome/browser/local_search_service/local_search_service_proxy_factory.h"
+#include "chrome/browser/profiles/incognito_helpers.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+
+namespace chromeos {
+namespace settings {
+
+// static
+OsSettingsLocalizedStringsProvider*
+OsSettingsLocalizedStringsProviderFactory::GetForProfile(Profile* profile) {
+ return static_cast<OsSettingsLocalizedStringsProvider*>(
+ OsSettingsLocalizedStringsProviderFactory::GetInstance()
+ ->GetServiceForBrowserContext(profile, /*create=*/true));
+}
+
+// static
+OsSettingsLocalizedStringsProviderFactory*
+OsSettingsLocalizedStringsProviderFactory::GetInstance() {
+ return base::Singleton<OsSettingsLocalizedStringsProviderFactory>::get();
+}
+
+OsSettingsLocalizedStringsProviderFactory::
+ OsSettingsLocalizedStringsProviderFactory()
+ : BrowserContextKeyedServiceFactory(
+ "OsSettingsLocalizedStringsProvider",
+ BrowserContextDependencyManager::GetInstance()) {
+ DependsOn(
+ local_search_service::LocalSearchServiceProxyFactory::GetInstance());
+}
+
+OsSettingsLocalizedStringsProviderFactory::
+ ~OsSettingsLocalizedStringsProviderFactory() = default;
+
+KeyedService*
+OsSettingsLocalizedStringsProviderFactory::BuildServiceInstanceFor(
+ content::BrowserContext* context) const {
+ Profile* profile = Profile::FromBrowserContext(context);
+ return new OsSettingsLocalizedStringsProvider(
+ profile,
+ local_search_service::LocalSearchServiceProxyFactory::GetForProfile(
+ Profile::FromBrowserContext(profile))
+ ->GetLocalSearchService());
+}
+
+bool OsSettingsLocalizedStringsProviderFactory::ServiceIsNULLWhileTesting()
+ const {
+ return true;
+}
+
+content::BrowserContext*
+OsSettingsLocalizedStringsProviderFactory::GetBrowserContextToUse(
+ content::BrowserContext* context) const {
+ return chrome::GetBrowserContextOwnInstanceInIncognito(context);
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_factory.h b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_factory.h
new file mode 100644
index 00000000000..d1b7df331e2
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_factory.h
@@ -0,0 +1,47 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_OS_SETTINGS_LOCALIZED_STRINGS_PROVIDER_FACTORY_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_OS_SETTINGS_LOCALIZED_STRINGS_PROVIDER_FACTORY_H_
+
+#include "base/memory/singleton.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+
+class Profile;
+
+namespace chromeos {
+namespace settings {
+
+class OsSettingsLocalizedStringsProvider;
+
+class OsSettingsLocalizedStringsProviderFactory
+ : public BrowserContextKeyedServiceFactory {
+ public:
+ static OsSettingsLocalizedStringsProvider* GetForProfile(Profile* profile);
+ static OsSettingsLocalizedStringsProviderFactory* GetInstance();
+
+ private:
+ friend struct base::DefaultSingletonTraits<
+ OsSettingsLocalizedStringsProviderFactory>;
+
+ OsSettingsLocalizedStringsProviderFactory();
+ ~OsSettingsLocalizedStringsProviderFactory() override;
+
+ OsSettingsLocalizedStringsProviderFactory(
+ const OsSettingsLocalizedStringsProviderFactory&) = delete;
+ OsSettingsLocalizedStringsProviderFactory& operator=(
+ const OsSettingsLocalizedStringsProviderFactory&) = delete;
+
+ // BrowserContextKeyedServiceFactory:
+ KeyedService* BuildServiceInstanceFor(
+ content::BrowserContext* context) const override;
+ bool ServiceIsNULLWhileTesting() const override;
+ content::BrowserContext* GetBrowserContextToUse(
+ content::BrowserContext* context) const override;
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_OS_SETTINGS_LOCALIZED_STRINGS_PROVIDER_FACTORY_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_unittest.cc
new file mode 100644
index 00000000000..c8eb26b6746
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_unittest.cc
@@ -0,0 +1,104 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.h"
+
+#include "base/run_loop.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/search_concept.h"
+#include "chrome/common/webui_url_constants.h"
+#include "chrome/grit/generated_resources.h"
+#include "chrome/services/local_search_service/local_search_service_impl.h"
+#include "chrome/services/local_search_service/public/mojom/local_search_service.mojom-test-utils.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "chrome/test/base/testing_profile.h"
+#include "chrome/test/base/testing_profile_manager.h"
+#include "chromeos/network/network_state_test_helper.h"
+#include "chromeos/services/network_config/public/cpp/cros_network_config_test_helper.h"
+#include "content/public/test/browser_task_environment.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/cros_system_api/dbus/shill/dbus-constants.h"
+
+namespace chromeos {
+namespace settings {
+
+class OsSettingsLocalizedStringsProviderTest : public testing::Test {
+ protected:
+ OsSettingsLocalizedStringsProviderTest()
+ : profile_manager_(TestingBrowserProcess::GetGlobal()) {}
+ ~OsSettingsLocalizedStringsProviderTest() override = default;
+
+ // testing::Test:
+ void SetUp() override {
+ ASSERT_TRUE(profile_manager_.SetUp());
+
+ provider_ = std::make_unique<OsSettingsLocalizedStringsProvider>(
+ profile_manager_.CreateTestingProfile("TestingProfile"),
+ &local_search_service_);
+
+ local_search_service_.GetIndex(
+ local_search_service::mojom::LocalSearchService::IndexId::CROS_SETTINGS,
+ index_remote_.BindNewPipeAndPassReceiver());
+
+ // Allow asynchronous networking code to complete (networking functionality
+ // is tested below).
+ base::RunLoop().RunUntilIdle();
+ }
+
+ content::BrowserTaskEnvironment task_environment_;
+ TestingProfileManager profile_manager_;
+ chromeos::network_config::CrosNetworkConfigTestHelper network_config_helper_;
+ mojo::Remote<local_search_service::mojom::Index> index_remote_;
+ local_search_service::LocalSearchServiceImpl local_search_service_;
+ std::unique_ptr<OsSettingsLocalizedStringsProvider> provider_;
+};
+
+// To prevent this from becoming a change-detector test, this test simply
+// verifies that when the provider starts up, it adds *some* strings without
+// checking the exact number. It also checks one specific canonical tag.
+TEST_F(OsSettingsLocalizedStringsProviderTest, WifiTags) {
+ uint64_t initial_num_items = 0;
+ local_search_service::mojom::IndexAsyncWaiter(index_remote_.get())
+ .GetSize(&initial_num_items);
+ EXPECT_GT(initial_num_items, 0u);
+
+ const SearchConcept* network_settings_concept =
+ provider_->GetCanonicalTagMetadata(IDS_SETTINGS_TAG_NETWORK_SETTINGS);
+ ASSERT_TRUE(network_settings_concept);
+ EXPECT_EQ(chrome::kNetworksSubPage,
+ network_settings_concept->url_path_with_parameters);
+ EXPECT_EQ(mojom::SearchResultIcon::kWifi, network_settings_concept->icon);
+
+ // Ethernet is not present by default, so no Ethernet concepts have yet been
+ // added.
+ const SearchConcept* ethernet_settings_concept =
+ provider_->GetCanonicalTagMetadata(IDS_SETTINGS_TAG_ETHERNET_SETTINGS);
+ ASSERT_FALSE(ethernet_settings_concept);
+
+ // Add Ethernet and let asynchronous handlers run. This should cause Ethernet
+ // tags to be added.
+ network_config_helper_.network_state_helper().device_test()->AddDevice(
+ "/device/stub_eth_device", shill::kTypeEthernet, "stub_eth_device");
+ base::RunLoop().RunUntilIdle();
+
+ uint64_t num_items_after_adding_ethernet = 0;
+ local_search_service::mojom::IndexAsyncWaiter(index_remote_.get())
+ .GetSize(&num_items_after_adding_ethernet);
+ EXPECT_GT(num_items_after_adding_ethernet, initial_num_items);
+
+ ethernet_settings_concept =
+ provider_->GetCanonicalTagMetadata(IDS_SETTINGS_TAG_ETHERNET_SETTINGS);
+ ASSERT_TRUE(ethernet_settings_concept);
+ EXPECT_EQ(chrome::kEthernetSettingsSubPage,
+ ethernet_settings_concept->url_path_with_parameters);
+ EXPECT_EQ(mojom::SearchResultIcon::kEthernet,
+ ethernet_settings_concept->icon);
+}
+
+// Note that other tests do not need to be added for different group of tags,
+// since these tests would only be verifying the contents of
+// os_settings_localized_strings_provider.cc.
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_per_page_strings_provider.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_per_page_strings_provider.cc
new file mode 100644
index 00000000000..26ac31b8cf6
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_per_page_strings_provider.cc
@@ -0,0 +1,32 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/os_settings_per_page_strings_provider.h"
+
+#include "base/logging.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/system/sys_info.h"
+
+namespace chromeos {
+namespace settings {
+
+// static
+base::string16 OsSettingsPerPageStringsProvider::GetHelpUrlWithBoard(
+ const std::string& original_url) {
+ return base::ASCIIToUTF16(original_url +
+ "&b=" + base::SysInfo::GetLsbReleaseBoard());
+}
+
+OsSettingsPerPageStringsProvider::~OsSettingsPerPageStringsProvider() = default;
+
+OsSettingsPerPageStringsProvider::OsSettingsPerPageStringsProvider(
+ Profile* profile,
+ Delegate* delegate)
+ : profile_(profile), delegate_(delegate) {
+ DCHECK(profile);
+ DCHECK(delegate);
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_per_page_strings_provider.h b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_per_page_strings_provider.h
new file mode 100644
index 00000000000..c2a6771c85b
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_per_page_strings_provider.h
@@ -0,0 +1,73 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_OS_SETTINGS_PER_PAGE_STRINGS_PROVIDER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_OS_SETTINGS_PER_PAGE_STRINGS_PROVIDER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/strings/string16.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/search_concept.h"
+
+class Profile;
+
+namespace content {
+class WebUIDataSource;
+} // namespace content
+
+namespace chromeos {
+namespace settings {
+
+// Provides strings for an individual page in OS settings (i.e., each subpage is
+// expected to have its own implementation. Responsible for two types of
+// strings:
+//
+// (1) UI strings: Strings (e.g., headers, labels) displayed in the settings UI.
+// Added to a WebUIDataSource via the pure virtual AddUiStrings() function.
+//
+// (2) Search tags: Strings used as potential matches for user search queries
+// within settings. Added/removed via the {Add|Remove}SearchTagsGroup
+// delegate functions. Tags which are always searchable should be added in
+// the class' constructor; however, tags which apply to content which is
+// dynamically shown/hidden should be added when that content is visible and
+// removed when the content is no longer visible.
+class OsSettingsPerPageStringsProvider {
+ public:
+ class Delegate {
+ public:
+ ~Delegate() = default;
+ virtual void AddSearchTags(
+ const std::vector<SearchConcept>& tags_group) = 0;
+ virtual void RemoveSearchTags(
+ const std::vector<SearchConcept>& tags_group) = 0;
+ };
+
+ virtual ~OsSettingsPerPageStringsProvider();
+
+ OsSettingsPerPageStringsProvider(
+ const OsSettingsPerPageStringsProvider& other) = delete;
+ OsSettingsPerPageStringsProvider& operator=(
+ const OsSettingsPerPageStringsProvider& other) = delete;
+
+ // Adds strings to be displayed in the UI via loadTimeData.
+ virtual void AddUiStrings(content::WebUIDataSource* html_source) const = 0;
+
+ protected:
+ static base::string16 GetHelpUrlWithBoard(const std::string& original_url);
+
+ OsSettingsPerPageStringsProvider(Profile* profile, Delegate* delegate);
+
+ Profile* profile() { return profile_; }
+ Delegate* delegate() { return delegate_; }
+
+ private:
+ Profile* profile_;
+ Delegate* delegate_;
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_OS_SETTINGS_PER_PAGE_STRINGS_PROVIDER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc
index a91606bde11..dd4edc8807a 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc
@@ -11,14 +11,32 @@
#include <utility>
#include <vector>
+#include "ash/public/cpp/ash_features.h"
#include "ash/public/cpp/network_config_service.h"
#include "ash/public/cpp/resources/grit/ash_public_unscaled_resources.h"
+#include "ash/public/cpp/stylus_utils.h"
#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/feature_list.h"
+#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_functions.h"
#include "build/build_config.h"
-#include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/browser_process_platform_part.h"
+#include "chrome/browser/chromeos/account_manager/account_manager_util.h"
+#include "chrome/browser/chromeos/arc/arc_util.h"
+#include "chrome/browser/chromeos/crostini/crostini_features.h"
+#include "chrome/browser/chromeos/login/demo_mode/demo_session.h"
+#include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.h"
+#include "chrome/browser/chromeos/multidevice_setup/multidevice_setup_client_factory.h"
+#include "chrome/browser/chromeos/plugin_vm/plugin_vm_pref_names.h"
+#include "chrome/browser/chromeos/plugin_vm/plugin_vm_util.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
+#include "chrome/browser/signin/identity_manager_factory.h"
+#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/webui/app_management/app_management.mojom.h"
#include "chrome/browser/ui/webui/app_management/app_management_page_handler.h"
+#include "chrome/browser/ui/webui/chromeos/smb_shares/smb_handler.h"
#include "chrome/browser/ui/webui/chromeos/sync/os_sync_handler.h"
#include "chrome/browser/ui/webui/managed_ui_handler.h"
#include "chrome/browser/ui/webui/metrics_handler.h"
@@ -26,7 +44,33 @@
#include "chrome/browser/ui/webui/settings/about_handler.h"
#include "chrome/browser/ui/webui/settings/accessibility_main_handler.h"
#include "chrome/browser/ui/webui/settings/browser_lifetime_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/account_manager_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/android_apps_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/crostini_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/date_time_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/device_pointer_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/device_power_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/google_assistant_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/internet_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/kerberos_accounts_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.h"
+#include "chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_factory.h"
#include "chrome/browser/ui/webui/settings/chromeos/parental_controls_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/pref_names.h"
+#include "chrome/browser/ui/webui/settings/chromeos/quick_unlock_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/search_handler.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/search_handler_factory.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker.h"
#include "chrome/browser/ui/webui/settings/chromeos/wallpaper_handler.h"
#include "chrome/browser/ui/webui/settings/downloads_handler.h"
#include "chrome/browser/ui/webui/settings/extension_control_handler.h"
@@ -40,7 +84,9 @@
#include "chrome/browser/ui/webui/settings/settings_cookies_view_handler.h"
#include "chrome/browser/ui/webui/settings/settings_localized_strings_provider.h"
#include "chrome/browser/ui/webui/settings/settings_media_devices_selection_handler.h"
-#include "chrome/browser/ui/webui/settings/settings_ui.h"
+#include "chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.h"
+#include "chrome/browser/ui/webui/settings/tts_handler.h"
+#include "chrome/browser/ui/webui/webui_util.h"
#include "chrome/browser/web_applications/system_web_app_manager.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/webui_url_constants.h"
@@ -48,17 +94,36 @@
#include "chrome/grit/generated_resources.h"
#include "chrome/grit/os_settings_resources.h"
#include "chrome/grit/os_settings_resources_map.h"
+#include "chromeos/components/account_manager/account_manager.h"
+#include "chromeos/components/account_manager/account_manager_factory.h"
+#include "chromeos/components/web_applications/manifest_request_filter.h"
#include "chromeos/constants/chromeos_features.h"
+#include "chromeos/constants/chromeos_pref_names.h"
+#include "chromeos/login/auth/password_visibility_utils.h"
+#include "chromeos/services/multidevice_setup/public/cpp/prefs.h"
#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h"
#include "components/password_manager/core/common/password_manager_features.h"
+#include "components/pref_registry/pref_registry_syncable.h"
+#include "components/prefs/pref_service.h"
#include "content/public/browser/web_ui_data_source.h"
+#include "media/base/media_switches.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "ui/base/webui/web_ui_util.h"
+#include "ui/chromeos/resources/grit/ui_chromeos_resources.h"
+#include "ui/resources/grit/webui_resources.h"
namespace chromeos {
namespace settings {
+// static
+void OSSettingsUI::RegisterProfilePrefs(
+ user_prefs::PrefRegistrySyncable* registry) {
+ registry->RegisterBooleanPref(prefs::kSyncOsWallpaper, false);
+}
+
OSSettingsUI::OSSettingsUI(content::WebUI* web_ui)
: ui::MojoWebUIController(web_ui, /*enable_chrome_send=*/true),
+ time_when_opened_(base::TimeTicks::Now()),
webui_load_timer_(web_ui->GetWebContents(),
"ChromeOS.Settings.LoadDocumentTime",
"ChromeOS.Settings.LoadCompletedTime") {
@@ -66,7 +131,7 @@ OSSettingsUI::OSSettingsUI(content::WebUI* web_ui)
content::WebUIDataSource* html_source =
content::WebUIDataSource::Create(chrome::kChromeUIOSSettingsHost);
- ::settings::SettingsUI::InitOSWebUIHandlers(profile, web_ui, html_source);
+ InitOSWebUIHandlers(html_source);
// This handler is for chrome://os-settings.
html_source->AddBoolean("isOSSettings", true);
@@ -78,6 +143,9 @@ OSSettingsUI::OSSettingsUI(content::WebUI* web_ui)
html_source->AddBoolean(
"showParentalControls",
chromeos::settings::ShouldShowParentalControls(profile));
+ html_source->AddBoolean(
+ "syncSetupFriendlySettings",
+ base::FeatureList::IsEnabled(::features::kSyncSetupFriendlySettings));
AddSettingsPageUIHandler(
std::make_unique<::settings::AccessibilityMainHandler>());
@@ -103,19 +171,17 @@ OSSettingsUI::OSSettingsUI(content::WebUI* web_ui)
std::make_unique<::settings::ProtocolHandlersHandler>());
AddSettingsPageUIHandler(
std::make_unique<::settings::SearchEnginesHandler>(profile));
- AddSettingsPageUIHandler(
- std::make_unique<chromeos::settings::WallpaperHandler>(web_ui));
html_source->AddBoolean("showAppManagement", base::FeatureList::IsEnabled(
::features::kAppManagement));
html_source->AddBoolean("splitSettingsSyncEnabled",
chromeos::features::IsSplitSettingsSyncEnabled());
+ html_source->AddBoolean("splitSyncConsent",
+ chromeos::features::IsSplitSyncConsentEnabled());
-#if defined(OS_CHROMEOS)
html_source->AddBoolean(
"isSupportedArcVersion",
AppManagementPageHandler::IsCurrentArcVersionSupported(profile));
-#endif // OS_CHROMEOS
AddSettingsPageUIHandler(
base::WrapUnique(::settings::AboutHandler::Create(html_source, profile)));
@@ -126,7 +192,6 @@ OSSettingsUI::OSSettingsUI(content::WebUI* web_ui)
web_ui->AddMessageHandler(std::make_unique<MetricsHandler>());
// Add the System Web App resources for Settings.
- // TODO(jamescook|calamity): Migrate to chromeos::settings::OSSettingsUI.
if (web_app::SystemWebAppManager::IsEnabled()) {
html_source->AddResourcePath("icon-192.png", IDR_SETTINGS_LOGO_192);
html_source->AddResourcePath("pwa.html", IDR_PWA_HTML);
@@ -151,18 +216,37 @@ OSSettingsUI::OSSettingsUI(content::WebUI* web_ui)
#endif
html_source->AddResourcePath("app-management/app_management.mojom-lite.js",
- IDR_APP_MANAGEMENT_MOJO_LITE_JS);
- html_source->AddResourcePath("app-management/types.mojom-lite.js",
- IDR_APP_MANAGEMENT_TYPES_MOJO_LITE_JS);
- html_source->AddResourcePath("app-management/bitmap.mojom-lite.js",
- IDR_APP_MANAGEMENT_BITMAP_MOJO_LITE_JS);
- html_source->AddResourcePath("app-management/image.mojom-lite.js",
- IDR_APP_MANAGEMENT_IMAGE_MOJO_LITE_JS);
- html_source->AddResourcePath("app-management/image_info.mojom-lite.js",
- IDR_APP_MANAGEMENT_IMAGE_INFO_MOJO_LITE_JS);
-
- ::settings::AddLocalizedStrings(html_source, profile,
- web_ui->GetWebContents());
+ IDR_OS_SETTINGS_APP_MANAGEMENT_MOJO_LITE_JS);
+ html_source->AddResourcePath(
+ "app-management/types.mojom-lite.js",
+ IDR_OS_SETTINGS_APP_MANAGEMENT_TYPES_MOJO_LITE_JS);
+ html_source->AddResourcePath(
+ "app-management/bitmap.mojom-lite.js",
+ IDR_OS_SETTINGS_APP_MANAGEMENT_BITMAP_MOJO_LITE_JS);
+ html_source->AddResourcePath(
+ "app-management/file_path.mojom-lite.js",
+ IDR_OS_SETTINGS_APP_MANAGEMENT_FILE_PATH_MOJO_LITE_JS);
+ html_source->AddResourcePath(
+ "app-management/image.mojom-lite.js",
+ IDR_OS_SETTINGS_APP_MANAGEMENT_IMAGE_MOJO_LITE_JS);
+ html_source->AddResourcePath(
+ "app-management/image_info.mojom-lite.js",
+ IDR_OS_SETTINGS_APP_MANAGEMENT_IMAGE_INFO_MOJO_LITE_JS);
+
+ html_source->AddResourcePath(
+ "search/user_action_recorder.mojom-lite.js",
+ IDR_OS_SETTINGS_USER_ACTION_RECORDER_MOJOM_LITE_JS);
+ html_source->AddResourcePath(
+ "search/search_result_icon.mojom-lite.js",
+ IDR_OS_SETTINGS_SEARCH_RESULT_ICON_MOJOM_LITE_JS);
+ html_source->AddResourcePath("search/search.mojom-lite.js",
+ IDR_OS_SETTINGS_SEARCH_MOJOM_LITE_JS);
+
+ // AddOsLocalizedStrings must be added after AddBrowserLocalizedStrings
+ // as repeated keys used by the OS strings should override the same keys
+ // that may be used in the Browser string provider.
+ OsSettingsLocalizedStringsProviderFactory::GetForProfile(profile)
+ ->AddOsLocalizedStrings(html_source, profile);
auto plural_string_handler = std::make_unique<PluralStringHandler>();
plural_string_handler->AddLocalizedString("profileLabel",
@@ -173,16 +257,210 @@ OSSettingsUI::OSSettingsUI(content::WebUI* web_ui)
content::WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(),
html_source);
+}
- AddHandlerToRegistry(base::BindRepeating(&OSSettingsUI::BindCrosNetworkConfig,
- base::Unretained(this)));
-
- AddHandlerToRegistry(
- base::BindRepeating(&OSSettingsUI::BindAppManagementPageHandlerFactory,
- base::Unretained(this)));
+OSSettingsUI::~OSSettingsUI() {
+ // Note: OSSettingsUI lifetime is tied to the lifetime of the browser window.
+ base::UmaHistogramCustomTimes("ChromeOS.Settings.WindowOpenDuration",
+ base::TimeTicks::Now() - time_when_opened_,
+ /*min=*/base::TimeDelta::FromMicroseconds(500),
+ /*max=*/base::TimeDelta::FromHours(1),
+ /*buckets=*/50);
}
-OSSettingsUI::~OSSettingsUI() = default;
+void OSSettingsUI::InitOSWebUIHandlers(content::WebUIDataSource* html_source) {
+ Profile* profile = Profile::FromWebUI(web_ui());
+
+ // TODO(jamescook): Sort out how account management is split between Chrome OS
+ // and browser settings.
+ if (chromeos::IsAccountManagerAvailable(profile)) {
+ chromeos::AccountManagerFactory* factory =
+ g_browser_process->platform_part()->GetAccountManagerFactory();
+ chromeos::AccountManager* account_manager =
+ factory->GetAccountManager(profile->GetPath().value());
+ DCHECK(account_manager);
+
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::AccountManagerUIHandler>(
+ account_manager, IdentityManagerFactory::GetForProfile(profile)));
+ html_source->AddBoolean(
+ "secondaryGoogleAccountSigninAllowed",
+ profile->GetPrefs()->GetBoolean(
+ chromeos::prefs::kSecondaryGoogleAccountSigninAllowed));
+ html_source->AddBoolean("isEduCoexistenceEnabled",
+ features::IsEduCoexistenceEnabled());
+ }
+
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::ChangePictureHandler>());
+
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::AccessibilityHandler>(profile));
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::AndroidAppsHandler>(profile));
+ if (crostini::CrostiniFeatures::Get()->IsUIAllowed(profile,
+ /*check_policy=*/false)) {
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::CrostiniHandler>(profile));
+ }
+ web_ui()->AddMessageHandler(
+ chromeos::settings::CupsPrintersHandler::Create(web_ui()));
+ web_ui()->AddMessageHandler(base::WrapUnique(
+ chromeos::settings::DateTimeHandler::Create(html_source)));
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::FingerprintHandler>(profile));
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::GoogleAssistantHandler>(profile));
+
+ std::unique_ptr<chromeos::settings::KerberosAccountsHandler>
+ kerberos_accounts_handler =
+ chromeos::settings::KerberosAccountsHandler::CreateIfKerberosEnabled(
+ profile);
+ if (kerberos_accounts_handler) {
+ // Note that the UI is enabled only if Kerberos is enabled.
+ web_ui()->AddMessageHandler(std::move(kerberos_accounts_handler));
+ }
+
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::KeyboardHandler>());
+
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::WallpaperHandler>(web_ui()));
+
+ // If |!allow_plugin_vm| we still want to |show_plugin_vm| if the VM image is
+ // on disk, so that users are still able to delete the image at will.
+ const bool allow_plugin_vm = plugin_vm::IsPluginVmAllowedForProfile(profile);
+ const bool show_plugin_vm =
+ allow_plugin_vm ||
+ profile->GetPrefs()->GetBoolean(plugin_vm::prefs::kPluginVmImageExists);
+
+ if (show_plugin_vm) {
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::PluginVmHandler>(profile));
+ }
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::PointerHandler>());
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::QuickUnlockHandler>());
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::StorageHandler>(profile,
+ html_source));
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::StylusHandler>());
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::InternetHandler>(profile));
+ web_ui()->AddMessageHandler(std::make_unique<::settings::TtsHandler>());
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::smb_dialog::SmbHandler>(profile,
+ base::DoNothing()));
+
+ if (!profile->IsGuestSession()) {
+ chromeos::android_sms::AndroidSmsService* android_sms_service =
+ chromeos::android_sms::AndroidSmsServiceFactory::GetForBrowserContext(
+ profile);
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::MultideviceHandler>(
+ profile->GetPrefs(),
+ chromeos::multidevice_setup::MultiDeviceSetupClientFactory::
+ GetForProfile(profile),
+ android_sms_service
+ ? android_sms_service->android_sms_pairing_state_tracker()
+ : nullptr,
+ android_sms_service ? android_sms_service->android_sms_app_manager()
+ : nullptr));
+ if (chromeos::settings::ShouldShowParentalControls(profile)) {
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::ParentalControlsHandler>(
+ profile));
+ }
+
+ if (chromeos::features::IsAmbientModeEnabled()) {
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::AmbientModeHandler>());
+ }
+ }
+
+ html_source->AddBoolean(
+ "privacySettingsRedesignEnabled",
+ base::FeatureList::IsEnabled(::features::kPrivacySettingsRedesign));
+
+ html_source->AddBoolean(
+ "multideviceAllowedByPolicy",
+ chromeos::multidevice_setup::AreAnyMultiDeviceFeaturesAllowed(
+ profile->GetPrefs()));
+ html_source->AddBoolean(
+ "quickUnlockEnabled",
+ chromeos::quick_unlock::IsPinEnabled(profile->GetPrefs()));
+ html_source->AddBoolean(
+ "quickUnlockDisabledByPolicy",
+ chromeos::quick_unlock::IsPinDisabledByPolicy(profile->GetPrefs()));
+ html_source->AddBoolean(
+ "userCannotManuallyEnterPassword",
+ !chromeos::password_visibility::AccountHasUserFacingPassword(
+ chromeos::ProfileHelper::Get()
+ ->GetUserByProfile(profile)
+ ->GetAccountId()));
+ const bool fingerprint_unlock_enabled =
+ chromeos::quick_unlock::IsFingerprintEnabled(profile);
+ html_source->AddBoolean("fingerprintUnlockEnabled",
+ fingerprint_unlock_enabled);
+ if (fingerprint_unlock_enabled) {
+ html_source->AddInteger(
+ "fingerprintReaderLocation",
+ static_cast<int32_t>(chromeos::quick_unlock::GetFingerprintLocation()));
+
+ // To use lottie, the worker-src CSP needs to be updated for the web ui that
+ // is using it. Since as of now there are only a couple of webuis using
+ // lottie animations, this update has to be performed manually. As the usage
+ // increases, set this as the default so manual override is no longer
+ // required.
+ html_source->OverrideContentSecurityPolicyWorkerSrc(
+ "worker-src blob: 'self';");
+ html_source->AddResourcePath("finger_print.json",
+ IDR_LOGIN_FINGER_PRINT_TABLET_ANIMATION);
+ }
+ html_source->AddBoolean("lockScreenNotificationsEnabled",
+ ash::features::IsLockScreenNotificationsEnabled());
+ html_source->AddBoolean(
+ "lockScreenHideSensitiveNotificationsSupported",
+ ash::features::IsLockScreenHideSensitiveNotificationsSupported());
+ html_source->AddBoolean("showTechnologyBadge",
+ !ash::features::IsSeparateNetworkIconsEnabled());
+ html_source->AddBoolean("hasInternalStylus",
+ ash::stylus_utils::HasInternalStylus());
+
+ html_source->AddBoolean("showCrostini",
+ crostini::CrostiniFeatures::Get()->IsUIAllowed(
+ profile, /*check_policy=*/false));
+
+ html_source->AddBoolean(
+ "allowCrostini", crostini::CrostiniFeatures::Get()->IsUIAllowed(profile));
+
+ html_source->AddBoolean("allowPluginVm", allow_plugin_vm);
+ html_source->AddBoolean("showPluginVm", show_plugin_vm);
+
+ html_source->AddBoolean("isDemoSession",
+ chromeos::DemoSession::IsDeviceInDemoMode());
+
+ // We have 2 variants of Android apps settings. Default case, when the Play
+ // Store app exists we show expandable section that allows as to
+ // enable/disable the Play Store and link to Android settings which is
+ // available once settings app is registered in the system.
+ // For AOSP images we don't have the Play Store app. In last case we Android
+ // apps settings consists only from root link to Android settings and only
+ // visible once settings app is registered.
+ html_source->AddBoolean("androidAppsVisible",
+ arc::IsArcAllowedForProfile(profile));
+ html_source->AddBoolean("havePlayStoreApp", arc::IsPlayStoreAvailable());
+
+ html_source->AddBoolean("enablePowerSettings", true);
+ web_ui()->AddMessageHandler(
+ std::make_unique<chromeos::settings::PowerHandler>(profile->GetPrefs()));
+
+ html_source->AddBoolean(
+ "showParentalControlsSettings",
+ chromeos::settings::ShouldShowParentalControls(profile));
+}
void OSSettingsUI::AddSettingsPageUIHandler(
std::unique_ptr<content::WebUIMessageHandler> handler) {
@@ -190,12 +468,24 @@ void OSSettingsUI::AddSettingsPageUIHandler(
web_ui()->AddMessageHandler(std::move(handler));
}
-void OSSettingsUI::BindCrosNetworkConfig(
+void OSSettingsUI::BindInterface(
mojo::PendingReceiver<network_config::mojom::CrosNetworkConfig> receiver) {
ash::GetNetworkConfigService(std::move(receiver));
}
-void OSSettingsUI::BindAppManagementPageHandlerFactory(
+void OSSettingsUI::BindInterface(
+ mojo::PendingReceiver<mojom::UserActionRecorder> receiver) {
+ user_action_recorder_ =
+ std::make_unique<SettingsUserActionTracker>(std::move(receiver));
+}
+
+void OSSettingsUI::BindInterface(
+ mojo::PendingReceiver<mojom::SearchHandler> receiver) {
+ SearchHandlerFactory::GetForProfile(Profile::FromWebUI(web_ui()))
+ ->BindInterface(std::move(receiver));
+}
+
+void OSSettingsUI::BindInterface(
mojo::PendingReceiver<app_management::mojom::PageHandlerFactory> receiver) {
if (!app_management_page_handler_factory_) {
app_management_page_handler_factory_ =
@@ -205,5 +495,7 @@ void OSSettingsUI::BindAppManagementPageHandlerFactory(
app_management_page_handler_factory_->Bind(std::move(receiver));
}
+WEB_UI_CONTROLLER_TYPE_IMPL(OSSettingsUI)
+
} // namespace settings
} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.h b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.h
index ff325c20bc3..c72c6b57c22 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.h
@@ -8,40 +8,75 @@
#include <memory>
#include "base/macros.h"
+#include "base/time/time.h"
#include "chrome/browser/ui/webui/app_management/app_management.mojom-forward.h"
#include "chrome/browser/ui/webui/settings/chromeos/app_management/app_management_page_handler_factory.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/user_action_recorder.mojom-forward.h"
#include "chrome/browser/ui/webui/webui_load_timer.h"
#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom-forward.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "ui/webui/mojo_web_ui_controller.h"
namespace content {
+class WebUIDataSource;
class WebUIMessageHandler;
-}
+} // namespace content
+
+namespace user_prefs {
+class PrefRegistrySyncable;
+} // namespace user_prefs
namespace chromeos {
namespace settings {
+namespace mojom {
+class SearchHandler;
+} // namespace mojom
+
// The WebUI handler for chrome://os-settings.
class OSSettingsUI : public ui::MojoWebUIController {
public:
+ static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
+
explicit OSSettingsUI(content::WebUI* web_ui);
~OSSettingsUI() override;
- private:
- void AddSettingsPageUIHandler(
- std::unique_ptr<content::WebUIMessageHandler> handler);
- void BindCrosNetworkConfig(
+ // Initializes the WebUI message handlers for OS-specific settings.
+ void InitOSWebUIHandlers(content::WebUIDataSource* html_source);
+
+ // Instantiates implementor of the mojom::CrosNetworkConfig mojo interface
+ // passing the pending receiver that will be internally bound.
+ void BindInterface(
mojo::PendingReceiver<network_config::mojom::CrosNetworkConfig> receiver);
- void BindAppManagementPageHandlerFactory(
+
+ // Instantiates implementor of the mojom::UserActionRecorder mojo interface
+ // passing the pending receiver that will be internally bound.
+ void BindInterface(mojo::PendingReceiver<mojom::UserActionRecorder> receiver);
+
+ // Instantiates implementor of the mojom::SearchHandler mojo interface
+ // passing the pending receiver that will be internally bound.
+ void BindInterface(mojo::PendingReceiver<mojom::SearchHandler> receiver);
+
+ // Instantiates implementor of the mojom::PageHandlerFactory mojo interface
+ // passing the pending receiver that will be internally bound.
+ void BindInterface(
mojo::PendingReceiver<app_management::mojom::PageHandlerFactory>
receiver);
+ private:
+ void AddSettingsPageUIHandler(
+ std::unique_ptr<content::WebUIMessageHandler> handler);
+
+ base::TimeTicks time_when_opened_;
+
WebuiLoadTimer webui_load_timer_;
+ std::unique_ptr<mojom::UserActionRecorder> user_action_recorder_;
std::unique_ptr<AppManagementPageHandlerFactory>
app_management_page_handler_factory_;
+ WEB_UI_CONTROLLER_TYPE_DECL();
+
DISALLOW_COPY_AND_ASSIGN(OSSettingsUI);
};
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.cc
index 715782b0b11..db5d9d79e67 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.cc
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.cc
@@ -12,6 +12,8 @@
#include "base/bind_helpers.h"
#include "chrome/browser/chromeos/file_manager/path_util.h"
#include "chrome/browser/chromeos/guest_os/guest_os_share_path.h"
+#include "chrome/browser/chromeos/plugin_vm/plugin_vm_manager.h"
+#include "chrome/browser/chromeos/plugin_vm/plugin_vm_util.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/browser_thread.h"
@@ -32,6 +34,14 @@ void PluginVmHandler::RegisterMessages() {
"removePluginVmSharedPath",
base::BindRepeating(&PluginVmHandler::HandleRemovePluginVmSharedPath,
weak_ptr_factory_.GetWeakPtr()));
+ web_ui()->RegisterMessageCallback(
+ "removePluginVm",
+ base::BindRepeating(&PluginVmHandler::HandleRemovePluginVm,
+ weak_ptr_factory_.GetWeakPtr()));
+ web_ui()->RegisterMessageCallback(
+ "requestPluginVmInstallerView",
+ base::BindRepeating(&PluginVmHandler::HandleRequestPluginVmInstallerView,
+ weak_ptr_factory_.GetWeakPtr()));
}
void PluginVmHandler::HandleGetPluginVmSharedPathsDisplayText(
@@ -68,5 +78,28 @@ void PluginVmHandler::HandleRemovePluginVmSharedPath(
path));
}
+void PluginVmHandler::HandleRemovePluginVm(const base::ListValue* args) {
+ CHECK_EQ(0U, args->GetSize());
+
+ auto* manager = plugin_vm::PluginVmManager::GetForProfile(profile_);
+ if (!manager) {
+ LOG(ERROR) << "removePluginVm called from an invalid profile.";
+ return;
+ }
+ manager->UninstallPluginVm();
+}
+
+void PluginVmHandler::HandleRequestPluginVmInstallerView(
+ const base::ListValue* args) {
+ CHECK(args->empty());
+
+ if (plugin_vm::IsPluginVmEnabled(profile_)) {
+ LOG(ERROR) << "requestPluginVmInstallerView called from a profile which "
+ "already has Plugin VM installed.";
+ return;
+ }
+ plugin_vm::ShowPluginVmInstallerView(profile_);
+}
+
} // namespace settings
} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.h
index d57b34da1db..b003a9e3e11 100644
--- a/chromium/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.h
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.h
@@ -32,6 +32,10 @@ class PluginVmHandler : public ::settings::SettingsPageUIHandler {
void HandleGetPluginVmSharedPathsDisplayText(const base::ListValue* args);
// Remove a specified path from being shared.
void HandleRemovePluginVmSharedPath(const base::ListValue* args);
+ // Remove Plugin VM.
+ void HandleRemovePluginVm(const base::ListValue* args);
+ // Show the Plugin VM installer view if Plugin VM is not currently installed.
+ void HandleRequestPluginVmInstallerView(const base::ListValue* args);
Profile* profile_;
// weak_ptr_factory_ should always be last member.
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/pref_names.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/pref_names.cc
new file mode 100644
index 00000000000..c36221f6270
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/pref_names.cc
@@ -0,0 +1,20 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/pref_names.h"
+
+namespace chromeos {
+namespace settings {
+namespace prefs {
+
+// Boolean specifying whether OS wallpaper sync is enabled. This is stored
+// separately from the other OS sync preferences because it's an edge case;
+// wallpaper does not have its own ModelType, so it cannot be part of
+// UserSelectableOsType like the other OS sync types.
+// TODO(https://crbug.com/967987): Break this dependency.
+const char kSyncOsWallpaper[] = "sync.os_wallpaper";
+
+} // namespace prefs
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/pref_names.h b/chromium/chrome/browser/ui/webui/settings/chromeos/pref_names.h
new file mode 100644
index 00000000000..df2e7dce599
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/pref_names.h
@@ -0,0 +1,18 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_PREF_NAMES_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_PREF_NAMES_H_
+
+namespace chromeos {
+namespace settings {
+namespace prefs {
+
+extern const char kSyncOsWallpaper[];
+
+} // namespace prefs
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_PREF_NAMES_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/quick_unlock_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/quick_unlock_handler.cc
new file mode 100644
index 00000000000..f74ec2b9c89
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/quick_unlock_handler.cc
@@ -0,0 +1,38 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/quick_unlock_handler.h"
+
+#include "base/bind.h"
+#include "chrome/browser/chromeos/login/quick_unlock/pin_backend.h"
+#include "content/public/browser/web_ui.h"
+
+namespace chromeos {
+namespace settings {
+
+QuickUnlockHandler::QuickUnlockHandler() = default;
+
+QuickUnlockHandler::~QuickUnlockHandler() = default;
+
+void QuickUnlockHandler::RegisterMessages() {
+ web_ui()->RegisterMessageCallback(
+ "RequestPinLoginState",
+ base::BindRepeating(&QuickUnlockHandler::HandleRequestPinLoginState,
+ base::Unretained(this)));
+}
+
+void QuickUnlockHandler::HandleRequestPinLoginState(
+ const base::ListValue* args) {
+ AllowJavascript();
+ quick_unlock::PinBackend::GetInstance()->HasLoginSupport(
+ base::BindOnce(&QuickUnlockHandler::OnPinLoginAvailable,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void QuickUnlockHandler::OnPinLoginAvailable(bool is_available) {
+ FireWebUIListener("pin-login-available-changed", base::Value(is_available));
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/quick_unlock_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/quick_unlock_handler.h
new file mode 100644
index 00000000000..4796c99ce3c
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/quick_unlock_handler.h
@@ -0,0 +1,42 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_QUICK_UNLOCK_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_QUICK_UNLOCK_HANDLER_H_
+
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+
+namespace base {
+class ListValue;
+} // namespace base
+
+namespace chromeos {
+namespace settings {
+
+// Settings WebUI handler for quick unlock settings.
+class QuickUnlockHandler : public ::settings::SettingsPageUIHandler {
+ public:
+ QuickUnlockHandler();
+ QuickUnlockHandler(const QuickUnlockHandler&) = delete;
+ QuickUnlockHandler& operator=(const QuickUnlockHandler&) = delete;
+ ~QuickUnlockHandler() override;
+
+ // SettingsPageUIHandler:
+ void RegisterMessages() override;
+ void OnJavascriptAllowed() override {}
+ void OnJavascriptDisallowed() override {}
+
+ private:
+ void HandleRequestPinLoginState(const base::ListValue* args);
+
+ void OnPinLoginAvailable(bool is_available);
+
+ base::WeakPtrFactory<QuickUnlockHandler> weak_ptr_factory_{this};
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_QUICK_UNLOCK_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/BUILD.gn b/chromium/chrome/browser/ui/webui/settings/chromeos/search/BUILD.gn
new file mode 100644
index 00000000000..b4554acf90b
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/BUILD.gn
@@ -0,0 +1,17 @@
+# Copyright 2020 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//mojo/public/tools/bindings/mojom.gni")
+
+assert(is_chromeos)
+
+mojom("mojo_bindings") {
+ sources = [
+ "search.mojom",
+ "search_result_icon.mojom",
+ "user_action_recorder.mojom",
+ ]
+
+ public_deps = [ "//mojo/public/mojom/base" ]
+}
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/OWNERS b/chromium/chrome/browser/ui/webui/settings/chromeos/search/OWNERS
new file mode 100644
index 00000000000..2d3d2668edc
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/OWNERS
@@ -0,0 +1,7 @@
+khorimoto@chromium.org
+zentaro@chromium.org
+
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
+
+# COMPONENT: OS>Systems>Settings
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search.mojom b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search.mojom
new file mode 100644
index 00000000000..d319e8d1079
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search.mojom
@@ -0,0 +1,33 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module chromeos.settings.mojom;
+
+import "chrome/browser/ui/webui/settings/chromeos/search/search_result_icon.mojom";
+import "mojo/public/mojom/base/string16.mojom";
+
+// Search result metadata.
+struct SearchResult {
+ // String to be displayed as a result in the UI. Meant to be displayed
+ // directly (i.e., not an ID but rather the actual text).
+ mojo_base.mojom.String16 result_text;
+
+ // The URL path containing the relevant setting, which may or may not contain
+ // URL parameters. For example, the Wi-Fi list settings page is
+ // chrome://os-settings/networks?type=WiFi, so the field would be
+ // "networks?type=WiFi" for this page.
+ string url_path_with_parameters;
+
+ // Icon to display for the search result.
+ SearchResultIcon icon;
+};
+
+// Provides settings search results. Implemented in the browser process;
+// intended to be called from settings JS and Launcher C++.
+interface SearchHandler {
+ // Searches settings for the given query and returns a list of results, sorted
+ // from most relevant to least relevant. An empty array indicates no relevant
+ // results.
+ Search(mojo_base.mojom.String16 query) => (array<SearchResult> results);
+};
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_concept.h b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_concept.h
new file mode 100644
index 00000000000..f6dc3b8c6f6
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_concept.h
@@ -0,0 +1,62 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_CONCEPT_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_CONCEPT_H_
+
+#include "chrome/browser/ui/webui/settings/chromeos/search/search_result_icon.mojom.h"
+
+namespace chromeos {
+namespace settings {
+
+// Represents a potential search result. In this context, "concept" refers to
+// the fact that this search result represents an idea which may be described
+// by more than just one phrase. For example, a concept of "Display settings"
+// may also be described as "Monitor settings".
+//
+// Each concept has a canonical description search tag as well as up to
+// |kMaxAltTagsPerConcept| alternate descriptions search tags.
+struct SearchConcept {
+ static constexpr size_t kMaxAltTagsPerConcept = 4;
+ static constexpr int kAltTagEnd = 0;
+
+ SearchConcept(const SearchConcept& other) = default;
+ SearchConcept& operator=(const SearchConcept& other) = default;
+
+ // Message ID (from os_settings_search_tag_strings.grdp) corresponding to the
+ // canonical search tag for this concept.
+ int canonical_message_id;
+
+ // URL path corresponding to the settings subpage at which the user can
+ // change a setting associated with the tag. This string can also contain
+ // URL parameters.
+ //
+ // Example 1 - Display settings (chrome://os-settings/device/display):
+ // ==> "device/display".
+ // Example 2 - Wi-Fi settings (chrome://os-settings/networks?type=WiFi):
+ // ==> "networks?type=WiFi"
+ const char* url_path_with_parameters;
+
+ // Icon to display for search results associated with this concept.
+ mojom::SearchResultIcon icon;
+
+ // Alternate message IDs (from os_settings_search_tag_strings.grdp)
+ // corresponding to this concept. These IDs refer to messages which represent
+ // an alternate way of describing the same concept (e.g., "Monitor settings"
+ // is an alternate phrase for "Display settings").
+ //
+ // This field provides up to |kMaxAltTagsPerConcept| alternate tags, but not
+ // all concepts will require this many. A value of kAltTagEnd is used to
+ // indicate that there are no further tags.
+ //
+ // Example 1 - Four alternate tags: [1234, 1235, 1236, 1237]
+ // Example 2 - Two alternate tags: [1234, 1235, kAltTagEnd, _]
+ // Example 3 - Zero alternate tags: [kAltTagEnd, _, _, _]
+ int alt_tag_ids[kMaxAltTagsPerConcept] = {kAltTagEnd};
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_CONCEPT_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc
new file mode 100644
index 00000000000..a94db926427
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc
@@ -0,0 +1,107 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/search/search_handler.h"
+
+#include "base/strings/string_number_conversions.h"
+#include "chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/search_concept.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/search_result_icon.mojom.h"
+#include "chrome/services/local_search_service/local_search_service_impl.h"
+#include "chrome/services/local_search_service/public/mojom/types.mojom.h"
+#include "ui/base/l10n/l10n_util.h"
+
+namespace chromeos {
+namespace settings {
+namespace {
+
+const int32_t kLocalSearchServiceMaxResults = 10;
+
+} // namespace
+
+// static
+const size_t SearchHandler::kNumMaxResults = 5;
+
+SearchHandler::SearchHandler(
+ OsSettingsLocalizedStringsProvider* strings_provider,
+ local_search_service::LocalSearchServiceImpl* local_search_service)
+ : strings_provider_(strings_provider),
+ index_(local_search_service->GetIndexImpl(
+ local_search_service::IndexId::kCrosSettings)) {}
+
+SearchHandler::~SearchHandler() = default;
+
+void SearchHandler::BindInterface(
+ mojo::PendingReceiver<mojom::SearchHandler> pending_receiver) {
+ receivers_.Add(this, std::move(pending_receiver));
+}
+
+std::vector<mojom::SearchResultPtr> SearchHandler::Search(
+ const base::string16& query) {
+ std::vector<local_search_service::Result> local_search_service_results;
+ local_search_service::ResponseStatus response_status = index_->Find(
+ query, kLocalSearchServiceMaxResults, &local_search_service_results);
+
+ if (response_status != local_search_service::ResponseStatus::kSuccess) {
+ LOG(ERROR) << "Cannot search; LocalSearchService returned "
+ << static_cast<int>(response_status)
+ << ". Returning empty results array.";
+ return {};
+ }
+
+ return GenerateSearchResultsArray(local_search_service_results);
+}
+
+void SearchHandler::Search(const base::string16& query,
+ SearchCallback callback) {
+ std::move(callback).Run(Search(query));
+}
+
+std::vector<mojom::SearchResultPtr> SearchHandler::GenerateSearchResultsArray(
+ const std::vector<local_search_service::Result>&
+ local_search_service_results) {
+ std::vector<mojom::SearchResultPtr> search_results;
+ for (const auto& result : local_search_service_results) {
+ mojom::SearchResultPtr result_ptr = ResultToSearchResult(result);
+ if (result_ptr)
+ search_results.push_back(std::move(result_ptr));
+
+ // Limit the number of results to return.
+ if (search_results.size() == kNumMaxResults)
+ break;
+ }
+
+ return search_results;
+}
+
+mojom::SearchResultPtr SearchHandler::ResultToSearchResult(
+ const local_search_service::Result& result) {
+ int message_id;
+
+ // The result's ID is expected to be a stringified int.
+ if (!base::StringToInt(result.id, &message_id))
+ return nullptr;
+
+ const SearchConcept* concept =
+ strings_provider_->GetCanonicalTagMetadata(message_id);
+
+ // If the concept was not registered, no metadata is available. This can occur
+ // if the search tag was dynamically unregistered during the asynchronous
+ // Find() call.
+ if (!concept)
+ return nullptr;
+
+ return mojom::SearchResult::New(l10n_util::GetStringUTF16(message_id),
+ concept->url_path_with_parameters,
+ concept->icon);
+}
+
+void SearchHandler::Shutdown() {
+ strings_provider_ = nullptr;
+ index_ = nullptr;
+ receivers_.Clear();
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.h
new file mode 100644
index 00000000000..36df7ed4bb2
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.h
@@ -0,0 +1,77 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_HANDLER_H_
+
+#include <vector>
+
+#include "base/optional.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/search.mojom.h"
+#include "chrome/services/local_search_service/index_impl.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
+#include "mojo/public/cpp/bindings/remote.h"
+
+namespace local_search_service {
+class LocalSearchServiceImpl;
+} // namespace local_search_service
+
+namespace chromeos {
+namespace settings {
+
+class OsSettingsLocalizedStringsProvider;
+
+// Handles search queries for Chrome OS settings. Search() is expected to be
+// invoked by the settings UI as well as the the Launcher search UI. Search
+// results are obtained by matching the provided query against search tags
+// indexed in the LocalSearchService and cross-referencing results with
+// OsSettingsLocalizedStringsProvider.
+//
+// SearchHandler returns at most |kNumMaxResults| results; searches which do not
+// provide any matches result in an empty results array.
+class SearchHandler : public mojom::SearchHandler, public KeyedService {
+ public:
+ // Maximum number of results returned by a Search() call.
+ static const size_t kNumMaxResults;
+
+ SearchHandler(
+ OsSettingsLocalizedStringsProvider* strings_provider,
+ local_search_service::LocalSearchServiceImpl* local_search_service);
+ ~SearchHandler() override;
+
+ SearchHandler(const SearchHandler& other) = delete;
+ SearchHandler& operator=(const SearchHandler& other) = delete;
+
+ void BindInterface(
+ mojo::PendingReceiver<mojom::SearchHandler> pending_receiver);
+
+ // Synchronous search implementation (for in-process clients).
+ std::vector<mojom::SearchResultPtr> Search(const base::string16& query);
+
+ // mojom::SearchHandler:
+ void Search(const base::string16& query, SearchCallback callback) override;
+
+ private:
+ // KeyedService:
+ void Shutdown() override;
+
+ std::vector<mojom::SearchResultPtr> GenerateSearchResultsArray(
+ const std::vector<local_search_service::Result>&
+ local_search_service_results);
+ mojom::SearchResultPtr ResultToSearchResult(
+ const local_search_service::Result& result);
+
+ OsSettingsLocalizedStringsProvider* strings_provider_;
+ local_search_service::IndexImpl* index_;
+
+ // Note: Expected to have multiple clients, so a ReceiverSet is used.
+ mojo::ReceiverSet<mojom::SearchHandler> receivers_;
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_factory.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_factory.cc
new file mode 100644
index 00000000000..fba87783738
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_factory.cc
@@ -0,0 +1,61 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/search/search_handler_factory.h"
+
+#include "chrome/browser/local_search_service/local_search_service_proxy.h"
+#include "chrome/browser/local_search_service/local_search_service_proxy_factory.h"
+#include "chrome/browser/profiles/incognito_helpers.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider_factory.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/search_handler.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+
+namespace chromeos {
+namespace settings {
+
+// static
+SearchHandler* SearchHandlerFactory::GetForProfile(Profile* profile) {
+ return static_cast<SearchHandler*>(
+ SearchHandlerFactory::GetInstance()->GetServiceForBrowserContext(
+ profile, /*create=*/true));
+}
+
+// static
+SearchHandlerFactory* SearchHandlerFactory::GetInstance() {
+ return base::Singleton<SearchHandlerFactory>::get();
+}
+
+SearchHandlerFactory::SearchHandlerFactory()
+ : BrowserContextKeyedServiceFactory(
+ "SearchHandler",
+ BrowserContextDependencyManager::GetInstance()) {
+ DependsOn(
+ local_search_service::LocalSearchServiceProxyFactory::GetInstance());
+ DependsOn(OsSettingsLocalizedStringsProviderFactory::GetInstance());
+}
+
+SearchHandlerFactory::~SearchHandlerFactory() = default;
+
+KeyedService* SearchHandlerFactory::BuildServiceInstanceFor(
+ content::BrowserContext* context) const {
+ Profile* profile = Profile::FromBrowserContext(context);
+ return new SearchHandler(
+ OsSettingsLocalizedStringsProviderFactory::GetForProfile(profile),
+ local_search_service::LocalSearchServiceProxyFactory::GetForProfile(
+ Profile::FromBrowserContext(profile))
+ ->GetLocalSearchServiceImpl());
+}
+
+bool SearchHandlerFactory::ServiceIsNULLWhileTesting() const {
+ return true;
+}
+
+content::BrowserContext* SearchHandlerFactory::GetBrowserContextToUse(
+ content::BrowserContext* context) const {
+ return chrome::GetBrowserContextOwnInstanceInIncognito(context);
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_factory.h b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_factory.h
new file mode 100644
index 00000000000..9b69e5f161c
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_factory.h
@@ -0,0 +1,45 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_HANDLER_FACTORY_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_HANDLER_FACTORY_H_
+
+#include "base/memory/singleton.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+
+class Profile;
+
+namespace chromeos {
+namespace settings {
+
+class SearchHandler;
+
+// Factory for SearchHandler; available for incognito and multi-profile cases to
+// support settings search in those contexts.
+class SearchHandlerFactory : public BrowserContextKeyedServiceFactory {
+ public:
+ static SearchHandler* GetForProfile(Profile* profile);
+ static SearchHandlerFactory* GetInstance();
+
+ private:
+ friend struct base::DefaultSingletonTraits<SearchHandlerFactory>;
+
+ SearchHandlerFactory();
+ ~SearchHandlerFactory() override;
+
+ SearchHandlerFactory(const SearchHandlerFactory&) = delete;
+ SearchHandlerFactory& operator=(const SearchHandlerFactory&) = delete;
+
+ // BrowserContextKeyedServiceFactory:
+ KeyedService* BuildServiceInstanceFor(
+ content::BrowserContext* context) const override;
+ bool ServiceIsNULLWhileTesting() const override;
+ content::BrowserContext* GetBrowserContextToUse(
+ content::BrowserContext* context) const override;
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SEARCH_HANDLER_FACTORY_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc
new file mode 100644
index 00000000000..cc04fb87193
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc
@@ -0,0 +1,78 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/search/search_handler.h"
+
+#include "base/run_loop.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/ui/webui/settings/chromeos/os_settings_localized_strings_provider.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/search.mojom-test-utils.h"
+#include "chrome/common/webui_url_constants.h"
+#include "chrome/services/local_search_service/local_search_service_impl.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "chrome/test/base/testing_profile.h"
+#include "chrome/test/base/testing_profile_manager.h"
+#include "chromeos/services/network_config/public/cpp/cros_network_config_test_helper.h"
+#include "content/public/test/browser_task_environment.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+namespace settings {
+
+class SearchHandlerTest : public testing::Test {
+ protected:
+ SearchHandlerTest() : profile_manager_(TestingBrowserProcess::GetGlobal()) {}
+ ~SearchHandlerTest() override = default;
+
+ // testing::Test:
+ void SetUp() override {
+ ASSERT_TRUE(profile_manager_.SetUp());
+
+ provider_ = std::make_unique<OsSettingsLocalizedStringsProvider>(
+ profile_manager_.CreateTestingProfile("TestingProfile"),
+ &local_search_service_);
+
+ handler_ = std::make_unique<SearchHandler>(provider_.get(),
+ &local_search_service_);
+ handler_->BindInterface(handler_remote_.BindNewPipeAndPassReceiver());
+
+ // Allow asynchronous networking code to complete; specifically, let code
+ // which adds Wi-Fi to the system run so that Wi-Fi search tags can be
+ // queried below.
+ base::RunLoop().RunUntilIdle();
+ }
+
+ content::BrowserTaskEnvironment task_environment_;
+ TestingProfileManager profile_manager_;
+ chromeos::network_config::CrosNetworkConfigTestHelper network_config_helper_;
+ mojo::Remote<mojom::SearchHandler> handler_remote_;
+ local_search_service::LocalSearchServiceImpl local_search_service_;
+ std::unique_ptr<OsSettingsLocalizedStringsProvider> provider_;
+ std::unique_ptr<SearchHandler> handler_;
+};
+
+TEST_F(SearchHandlerTest, Success) {
+ // Search for "Wi-Fi".
+ std::vector<mojom::SearchResultPtr> search_results;
+ mojom::SearchHandlerAsyncWaiter(handler_remote_.get())
+ .Search(base::ASCIIToUTF16("Wi-Fi"), &search_results);
+
+ // Multiple results should be available, and they should have Wi-Fi metadata.
+ EXPECT_GT(search_results.size(), 0u);
+ for (const auto& result : search_results) {
+ EXPECT_EQ(chrome::kWiFiSettingsSubPage, result->url_path_with_parameters);
+ EXPECT_EQ(mojom::SearchResultIcon::kWifi, result->icon);
+ }
+}
+
+TEST_F(SearchHandlerTest, NoResults) {
+ std::vector<mojom::SearchResultPtr> search_results;
+ mojom::SearchHandlerAsyncWaiter(handler_remote_.get())
+ .Search(base::ASCIIToUTF16("QueryWithNoResults"), &search_results);
+ EXPECT_TRUE(search_results.empty());
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_result_icon.mojom b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_result_icon.mojom
new file mode 100644
index 00000000000..ea4605ed09f
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_result_icon.mojom
@@ -0,0 +1,14 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module chromeos.settings.mojom;
+
+// Icon types associated with a settings search result.
+enum SearchResultIcon {
+ kCellular,
+ kEthernet,
+ // Note: Wi-Fi icon is used by default for networking tasks which may not be
+ // specifically tied to Wi-Fi.
+ kWifi
+}; \ No newline at end of file
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker.cc
new file mode 100644
index 00000000000..49b774039a7
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker.cc
@@ -0,0 +1,131 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker.h"
+
+#include "base/metrics/histogram_functions.h"
+
+namespace chromeos {
+namespace settings {
+
+namespace {
+
+// The maximum amount of time that the settings window can be blurred to be
+// considered short enough for the "first change" metric.
+constexpr base::TimeDelta kShortBlurTimeLimit = base::TimeDelta::FromMinutes(1);
+
+// The minimum amount of time between a setting change and a subsequent setting
+// change. If two changes occur les than this amount of time from each other,
+// they are ignored by metrics. See https://crbug.com/1073714 for details.
+constexpr base::TimeDelta kMinSubsequentChange =
+ base::TimeDelta::FromMilliseconds(200);
+
+// Min/max values for the duration metrics. Note that these values are tied to
+// the metrics defined below; if these ever change, the metric names must also
+// be updated.
+constexpr base::TimeDelta kMinDurationMetric =
+ base::TimeDelta::FromMilliseconds(100);
+constexpr base::TimeDelta kMaxDurationMetric = base::TimeDelta::FromMinutes(10);
+
+void LogDurationMetric(const char* metric_name, base::TimeDelta duration) {
+ base::UmaHistogramCustomTimes(metric_name, duration, kMinDurationMetric,
+ kMaxDurationMetric, /*buckets=*/50);
+}
+
+} // namespace
+
+SettingsUserActionTracker::SettingsUserActionTracker(
+ mojo::PendingReceiver<mojom::UserActionRecorder> pending_receiver)
+ : SettingsUserActionTracker() {
+ receiver_.Bind(std::move(pending_receiver));
+}
+
+SettingsUserActionTracker::SettingsUserActionTracker()
+ : metric_start_time_(base::TimeTicks::Now()) {}
+
+SettingsUserActionTracker::~SettingsUserActionTracker() = default;
+
+void SettingsUserActionTracker::RecordPageFocus() {
+ if (last_blur_timestamp_.is_null())
+ return;
+
+ // Log the duration of being blurred.
+ const base::TimeDelta blurred_duration =
+ base::TimeTicks::Now() - last_blur_timestamp_;
+ LogDurationMetric("ChromeOS.Settings.BlurredWindowDuration",
+ blurred_duration);
+
+ // If the window was blurred for more than |kShortBlurTimeLimit|,
+ // the user was away from the window for long enough that we consider the
+ // user coming back to the window a new session for the purpose of metrics.
+ if (blurred_duration >= kShortBlurTimeLimit) {
+ ResetMetricsCountersAndTimestamp();
+ last_record_setting_changed_timestamp_ = base::TimeTicks();
+ }
+}
+
+void SettingsUserActionTracker::RecordPageBlur() {
+ last_blur_timestamp_ = base::TimeTicks::Now();
+}
+
+void SettingsUserActionTracker::RecordClick() {
+ ++num_clicks_since_start_time_;
+}
+
+void SettingsUserActionTracker::RecordNavigation() {
+ ++num_navigations_since_start_time_;
+}
+
+void SettingsUserActionTracker::RecordSearch() {
+ ++num_searches_since_start_time_;
+}
+
+void SettingsUserActionTracker::RecordSettingChange() {
+ base::TimeTicks now = base::TimeTicks::Now();
+
+ if (!last_record_setting_changed_timestamp_.is_null()) {
+ // If it has been less than |kMinSubsequentChange| since the last recorded
+ // setting change, this change is discarded. See https://crbug.com/1073714
+ // for details.
+ if (now - last_record_setting_changed_timestamp_ < kMinSubsequentChange)
+ return;
+
+ base::UmaHistogramCounts1000(
+ "ChromeOS.Settings.NumClicksUntilChange.SubsequentChange",
+ num_clicks_since_start_time_);
+ base::UmaHistogramCounts1000(
+ "ChromeOS.Settings.NumNavigationsUntilChange.SubsequentChange",
+ num_navigations_since_start_time_);
+ base::UmaHistogramCounts1000(
+ "ChromeOS.Settings.NumSearchesUntilChange.SubsequentChange",
+ num_searches_since_start_time_);
+ LogDurationMetric("ChromeOS.Settings.TimeUntilChange.SubsequentChange",
+ now - metric_start_time_);
+ } else {
+ base::UmaHistogramCounts1000(
+ "ChromeOS.Settings.NumClicksUntilChange.FirstChange",
+ num_clicks_since_start_time_);
+ base::UmaHistogramCounts1000(
+ "ChromeOS.Settings.NumNavigationsUntilChange.FirstChange",
+ num_navigations_since_start_time_);
+ base::UmaHistogramCounts1000(
+ "ChromeOS.Settings.NumSearchesUntilChange.FirstChange",
+ num_searches_since_start_time_);
+ LogDurationMetric("ChromeOS.Settings.TimeUntilChange.FirstChange",
+ now - metric_start_time_);
+ }
+
+ ResetMetricsCountersAndTimestamp();
+ last_record_setting_changed_timestamp_ = now;
+}
+
+void SettingsUserActionTracker::ResetMetricsCountersAndTimestamp() {
+ metric_start_time_ = base::TimeTicks::Now();
+ num_clicks_since_start_time_ = 0u;
+ num_navigations_since_start_time_ = 0u;
+ num_searches_since_start_time_ = 0u;
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker.h b/chromium/chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker.h
new file mode 100644
index 00000000000..f355bcd524e
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker.h
@@ -0,0 +1,74 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SETTINGS_USER_ACTION_TRACKER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SETTINGS_USER_ACTION_TRACKER_H_
+
+#include "base/time/time.h"
+#include "chrome/browser/ui/webui/settings/chromeos/search/user_action_recorder.mojom.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+
+namespace chromeos {
+namespace settings {
+
+// Records user actions which measure the effort required to change a setting.
+// This class is only meant to track actions from an individual settings
+// session; if the settings window is closed and reopened again, a new instance
+// should be created for that new session.
+class SettingsUserActionTracker : public mojom::UserActionRecorder {
+ public:
+ explicit SettingsUserActionTracker(
+ mojo::PendingReceiver<mojom::UserActionRecorder> pending_receiver);
+ SettingsUserActionTracker(const SettingsUserActionTracker& other) = delete;
+ SettingsUserActionTracker& operator=(const SettingsUserActionTracker& other) =
+ delete;
+ ~SettingsUserActionTracker() override;
+
+ // mojom::UserActionRecorder:
+ void RecordPageFocus() override;
+ void RecordPageBlur() override;
+ void RecordClick() override;
+ void RecordNavigation() override;
+ void RecordSearch() override;
+ void RecordSettingChange() override;
+
+ private:
+ friend class SettingsUserActionTrackerTest;
+
+ // For unit tests.
+ SettingsUserActionTracker();
+
+ void ResetMetricsCountersAndTimestamp();
+
+ // Time at which the last setting change metric was recorded since the window
+ // has been focused, or null if no setting change has been recorded since the
+ // window has been focused. Note that if the user blurs the window then
+ // refocuses it in less than a minute, this value remains non-null; i.e., it
+ // flips back to null only when the user has blurred the window for over a
+ // minute.
+ base::TimeTicks last_record_setting_changed_timestamp_;
+
+ // Time at which recording the current metric has started. If
+ // |has_changed_setting_| is true, we're currently measuring the "subsequent
+ // setting change" metric; otherwise, we're measuring the "first setting
+ // change" metric.
+ base::TimeTicks metric_start_time_;
+
+ // Counters associated with the current metric.
+ size_t num_clicks_since_start_time_ = 0u;
+ size_t num_navigations_since_start_time_ = 0u;
+ size_t num_searches_since_start_time_ = 0u;
+
+ // The last time at which a page blur event was received; if no blur events
+ // have been received, this field is_null().
+ base::TimeTicks last_blur_timestamp_;
+
+ mojo::Receiver<mojom::UserActionRecorder> receiver_{this};
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SEARCH_SETTINGS_USER_ACTION_TRACKER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker_unittest.cc
new file mode 100644
index 00000000000..74a0c9cb0b2
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker_unittest.cc
@@ -0,0 +1,176 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/search/settings_user_action_tracker.h"
+
+#include "base/test/metrics/histogram_tester.h"
+#include "base/test/task_environment.h"
+#include "base/time/time.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+namespace settings {
+
+class SettingsUserActionTrackerTest : public testing::Test {
+ protected:
+ SettingsUserActionTrackerTest() = default;
+ ~SettingsUserActionTrackerTest() override = default;
+
+ base::test::TaskEnvironment task_environment_{
+ base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+ base::HistogramTester histogram_tester_;
+ SettingsUserActionTracker tracker_;
+};
+
+TEST_F(SettingsUserActionTrackerTest, TestRecordMetrics) {
+ // Focus the page, perform some tasks, and change a setting.
+ tracker_.RecordPageFocus();
+ tracker_.RecordClick();
+ tracker_.RecordNavigation();
+ tracker_.RecordSearch();
+ task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(10));
+ tracker_.RecordSettingChange();
+
+ // The "first change" metrics should have been logged.
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumClicksUntilChange.FirstChange",
+ /*count=*/1);
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumNavigationsUntilChange.FirstChange",
+ /*count=*/1);
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumSearchesUntilChange.FirstChange",
+ /*count=*/1);
+ histogram_tester_.ExpectTimeBucketCount(
+ "ChromeOS.Settings.TimeUntilChange.FirstChange",
+ /*sample=*/base::TimeDelta::FromSeconds(10),
+ /*count=*/1);
+
+ // Without leaving the page, perform some more tasks, and change another
+ // setting.
+ tracker_.RecordClick();
+ tracker_.RecordNavigation();
+ tracker_.RecordSearch();
+ task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(10));
+ tracker_.RecordSettingChange();
+
+ // The "subsequent change" metrics should have been logged.
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumClicksUntilChange.SubsequentChange",
+ /*count=*/1);
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumNavigationsUntilChange.SubsequentChange",
+ /*count=*/1);
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumSearchesUntilChange.SubsequentChange",
+ /*count=*/1);
+ histogram_tester_.ExpectTimeBucketCount(
+ "ChromeOS.Settings.TimeUntilChange.SubsequentChange",
+ /*sample=*/base::TimeDelta::FromSeconds(10),
+ /*count=*/1);
+
+ // Repeat this, but only after 100ms. This is lower than the minimum value
+ // required for this metric, so it should be ignored.
+ tracker_.RecordClick();
+ tracker_.RecordNavigation();
+ tracker_.RecordSearch();
+ task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(100));
+ tracker_.RecordSettingChange();
+
+ // No additional logging should have occurred, so make the same verifications
+ // as above.
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumClicksUntilChange.SubsequentChange",
+ /*count=*/1);
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumNavigationsUntilChange.SubsequentChange",
+ /*count=*/1);
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumSearchesUntilChange.SubsequentChange",
+ /*count=*/1);
+ histogram_tester_.ExpectTimeBucketCount(
+ "ChromeOS.Settings.TimeUntilChange.SubsequentChange",
+ /*sample=*/base::TimeDelta::FromSeconds(10),
+ /*count=*/1);
+
+ // Repeat this once more, and verify that the counts increased.
+ tracker_.RecordClick();
+ tracker_.RecordNavigation();
+ tracker_.RecordSearch();
+ task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(10));
+ tracker_.RecordSettingChange();
+
+ // The "subsequent change" metrics should have been logged.
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumClicksUntilChange.SubsequentChange",
+ /*count=*/2);
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumNavigationsUntilChange.SubsequentChange",
+ /*count=*/2);
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumSearchesUntilChange.SubsequentChange",
+ /*count=*/2);
+ histogram_tester_.ExpectTimeBucketCount(
+ "ChromeOS.Settings.TimeUntilChange.SubsequentChange",
+ /*sample=*/base::TimeDelta::FromSeconds(10),
+ /*count=*/2);
+}
+
+TEST_F(SettingsUserActionTrackerTest, TestBlurAndFocus) {
+ // Focus the page, click, and change a setting.
+ tracker_.RecordPageFocus();
+ tracker_.RecordClick();
+ task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1));
+ tracker_.RecordSettingChange();
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumClicksUntilChange.FirstChange",
+ /*count=*/1);
+ histogram_tester_.ExpectTimeBucketCount(
+ "ChromeOS.Settings.TimeUntilChange.FirstChange",
+ /*sample=*/base::TimeDelta::FromSeconds(1),
+ /*count=*/1);
+
+ // Blur for 59 seconds (not quite a minute), click, and change a setting.
+ // Since the blur was under a minute, this should count for the "subsequent
+ // change" metrics.
+ tracker_.RecordPageBlur();
+ task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(59));
+ tracker_.RecordPageFocus();
+ tracker_.RecordClick();
+ tracker_.RecordSettingChange();
+ histogram_tester_.ExpectTimeBucketCount(
+ "ChromeOS.Settings.BlurredWindowDuration",
+ /*sample=*/base::TimeDelta::FromSeconds(59),
+ /*count=*/1);
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumClicksUntilChange.SubsequentChange",
+ /*count=*/1);
+ histogram_tester_.ExpectTimeBucketCount(
+ "ChromeOS.Settings.TimeUntilChange.SubsequentChange",
+ /*sample=*/base::TimeDelta::FromSeconds(59),
+ /*count=*/1);
+
+ // Now, blur for a full minute, click, and change a setting. Since the blur
+ // was a full minute, this should count for the "first change" metrics.
+ tracker_.RecordPageBlur();
+ task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
+ tracker_.RecordPageFocus();
+ task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(5));
+ tracker_.RecordClick();
+ tracker_.RecordSettingChange();
+ histogram_tester_.ExpectTimeBucketCount(
+ "ChromeOS.Settings.BlurredWindowDuration",
+ /*sample=*/base::TimeDelta::FromMinutes(1),
+ /*count=*/2);
+ histogram_tester_.ExpectTotalCount(
+ "ChromeOS.Settings.NumClicksUntilChange.FirstChange",
+ /*count=*/2);
+ histogram_tester_.ExpectTimeBucketCount(
+ "ChromeOS.Settings.TimeUntilChange.FirstChange",
+ /*sample=*/base::TimeDelta::FromSeconds(5),
+ /*count=*/1);
+}
+
+} // namespace settings.
+} // namespace chromeos.
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/user_action_recorder.mojom b/chromium/chrome/browser/ui/webui/settings/chromeos/search/user_action_recorder.mojom
new file mode 100644
index 00000000000..1f151fc028d
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/user_action_recorder.mojom
@@ -0,0 +1,28 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module chromeos.settings.mojom;
+
+// Records user actions within OS settings. Implemented in the browser process;
+// intended to be called from settings JS.
+interface UserActionRecorder {
+ // Records that the settings window has been focused.
+ RecordPageFocus();
+
+ // Records that the settings window has been blurred (i.e., no longer
+ // focused).
+ RecordPageBlur();
+
+ // Records that the user has clicked within the settings page.
+ RecordClick();
+
+ // Records that the user has navigated to a settings subpage.
+ RecordNavigation();
+
+ // Records that the user has completed a search attempt.
+ RecordSearch();
+
+ // Records that the user has changed a setting.
+ RecordSettingChange();
+};
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/server_printer_url_util.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/server_printer_url_util.cc
new file mode 100644
index 00000000000..005d006a42c
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/server_printer_url_util.cc
@@ -0,0 +1,73 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/server_printer_url_util.h"
+
+#include "url/gurl.h"
+
+namespace {
+
+// Returns an updated |gurl| with the specified components from the params. If
+// |scheme| is not empty, returns an updated GURL with the specified scheme. If
+// |replace_port| is true, returns an updated GURL with 631 as the port. 631 is
+// the default port for IPP.
+GURL UpdateServerPrinterGURL(const GURL& gurl,
+ const std::string& scheme,
+ bool replace_ipp_port) {
+ GURL::Replacements replacement;
+ if (!scheme.empty())
+ replacement.SetSchemeStr(scheme);
+ if (replace_ipp_port)
+ replacement.SetPortStr("631");
+ return gurl.ReplaceComponents(replacement);
+}
+
+} // namespace
+
+namespace chromeos {
+namespace settings {
+
+bool HasValidServerPrinterScheme(const GURL& gurl) {
+ return gurl.SchemeIsHTTPOrHTTPS() || gurl.SchemeIs("ipp") ||
+ gurl.SchemeIs("ipps");
+}
+
+base::Optional<GURL> GenerateServerPrinterUrlWithValidScheme(
+ const std::string& url) {
+ base::Optional<GURL> gurl = base::make_optional(GURL(url));
+ if (!HasValidServerPrinterScheme(*gurl)) {
+ // If we're missing a valid scheme, try querying with IPPS first.
+ gurl = GURL("ipps://" + url);
+ }
+
+ if (!gurl->is_valid())
+ return base::nullopt;
+
+ // Replaces IPP/IPPS by HTTP/HTTPS. IPP standard describes protocol built
+ // on top of HTTP, so both types of addresses have the same meaning in the
+ // context of IPP interface. Moreover, the URL must have HTTP/HTTPS scheme
+ // to pass IsStandard() test from GURL library (see "Validation of the URL
+ // address" below).
+ if (gurl->SchemeIs("ipp")) {
+ gurl = UpdateServerPrinterGURL(*gurl, "http",
+ /*replace_ipp_port=*/false);
+ // The default port for IPP is 631. If the schema IPP is replaced by HTTP
+ // and the port is not explicitly defined in the URL, we have to overwrite
+ // the default HTTP port with the default IPP port. For IPPS we do nothing
+ // because implementers use the same port for IPPS and HTTPS.
+ if (gurl->IntPort() == url::PORT_UNSPECIFIED) {
+ gurl = UpdateServerPrinterGURL(*gurl, /*scheme=*/"",
+ /*replace_ipp_port=*/true);
+ }
+ } else if (gurl->SchemeIs("ipps")) {
+ gurl = UpdateServerPrinterGURL(*gurl, "https",
+ /*replace_ipp_port=*/false);
+ }
+
+ // Check validation of the URL address and return |gurl| if valid.
+ return gurl->IsStandard() ? gurl : base::nullopt;
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/server_printer_url_util.h b/chromium/chrome/browser/ui/webui/settings/chromeos/server_printer_url_util.h
new file mode 100644
index 00000000000..ad118c14f4b
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/server_printer_url_util.h
@@ -0,0 +1,30 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SERVER_PRINTER_URL_UTIL_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SERVER_PRINTER_URL_UTIL_H_
+
+#include <string>
+
+#include "base/optional.h"
+
+class GURL;
+
+namespace chromeos {
+namespace settings {
+
+// Returns true if |gurl| has any the following scheme: HTTP, HTTPS, IPP, or
+// IPPS. Returns false for an empty or any other scheme.
+bool HasValidServerPrinterScheme(const GURL& gurl);
+
+// Returns a GURL from the input |url|. Returns base::nullopt if
+// either |url| is invalid or constructing the GURL failed. This will also
+// default the server printer URI to use HTTPS if it detects a missing scheme.
+base::Optional<GURL> GenerateServerPrinterUrlWithValidScheme(
+ const std::string& url);
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SERVER_PRINTER_URL_UTIL_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/server_printer_url_util_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/server_printer_url_util_unittest.cc
new file mode 100644
index 00000000000..26e2ec17433
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/server_printer_url_util_unittest.cc
@@ -0,0 +1,89 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/server_printer_url_util.h"
+
+#include <string>
+
+#include "base/optional.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace chromeos {
+namespace settings {
+
+class ServerPrinterUrlUtilTest : public testing::Test {
+ public:
+ ServerPrinterUrlUtilTest() = default;
+ ~ServerPrinterUrlUtilTest() override = default;
+};
+
+TEST_F(ServerPrinterUrlUtilTest, IsValidScheme) {
+ GURL gurl1("ipp://123.123.11.11:123");
+ ASSERT_TRUE(HasValidServerPrinterScheme(gurl1));
+
+ GURL gurl2("http://123.123.11.11:123");
+ ASSERT_TRUE(HasValidServerPrinterScheme(gurl2));
+
+ GURL gurl3("ipps://123.123.11.11:123");
+ ASSERT_TRUE(HasValidServerPrinterScheme(gurl3));
+
+ GURL gurl4("https://123.123.11.11:123");
+ ASSERT_TRUE(HasValidServerPrinterScheme(gurl4));
+
+ // Missing scheme.
+ GURL gurl5("123.123.11.11:123");
+ ASSERT_FALSE(HasValidServerPrinterScheme(gurl5));
+
+ // Invalid scheme.
+ GURL gurl6("test://123.123.11.11:123");
+ ASSERT_FALSE(HasValidServerPrinterScheme(gurl6));
+}
+
+TEST_F(ServerPrinterUrlUtilTest, ConvertToGURL) {
+ // Test that a GURL is created with |gurl1| as its source.
+ std::string url1("http://123.123.11.11:631");
+ base::Optional<GURL> gurl1 = GenerateServerPrinterUrlWithValidScheme(url1);
+ DCHECK(gurl1);
+ ASSERT_EQ("http://123.123.11.11:631/", gurl1->spec());
+ ASSERT_EQ("http", gurl1->scheme());
+ ASSERT_EQ("631", gurl1->port());
+
+ // Test that HTTPS is the default scheme if a scheme is not provided.
+ std::string url2("123.123.11.11:631");
+ base::Optional<GURL> gurl2 = GenerateServerPrinterUrlWithValidScheme(url2);
+ DCHECK(gurl2);
+ ASSERT_EQ("https", gurl2->scheme());
+ ASSERT_EQ("https://123.123.11.11:631/", gurl2->spec());
+
+ // Test that if a URL has IPP as its scheme, it will create a new GURL with
+ // HTTP as its scheme and 631 as its port.
+ std::string url3("ipp://123.123.11.11");
+ base::Optional<GURL> gurl3 = GenerateServerPrinterUrlWithValidScheme(url3);
+ DCHECK(gurl3);
+ ASSERT_EQ("http", gurl3->scheme());
+ ASSERT_EQ("631", gurl3->port());
+ ASSERT_EQ("http://123.123.11.11:631/", gurl3->spec());
+
+ // Test that if a URL has IPP as its scheme and a specified port, it will
+ // create a new GURL with HTTP as the scheme and keeps the same port.
+ std::string url4("ipp://123.123.11.11:321");
+ base::Optional<GURL> gurl4 = GenerateServerPrinterUrlWithValidScheme(url4);
+ DCHECK(gurl4);
+ ASSERT_EQ("http", gurl4->scheme());
+ ASSERT_EQ("321", gurl4->port());
+ ASSERT_EQ("http://123.123.11.11:321/", gurl4->spec());
+
+ // Test that if a URL has IPPS as its scheme and a specified port, a new GURL
+ // is created with the scheme as HTTPS and keeps the same port.
+ std::string url5("ipps://123.123.11.11:555");
+ base::Optional<GURL> gurl5 = GenerateServerPrinterUrlWithValidScheme(url5);
+ DCHECK(gurl5);
+ ASSERT_EQ("https", gurl5->scheme());
+ ASSERT_EQ("555", gurl5->port());
+ ASSERT_EQ("https://123.123.11.11:555/", gurl5->spec());
+}
+
+} // namespace settings
+} // namespace chromeos