diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-29 10:46:47 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-11-02 12:02:10 +0000 |
commit | 99677208ff3b216fdfec551fbe548da5520cd6fb (patch) | |
tree | 476a4865c10320249360e859d8fdd3e01833b03a /chromium/chrome/browser/ui/webui/settings | |
parent | c30a6232df03e1efbd9f3b226777b07e087a1122 (diff) |
BASELINE: Update Chromium to 86.0.4240.124
Change-Id: Ide0ff151e94cd665ae6521a446995d34a9d1d644
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/chrome/browser/ui/webui/settings')
96 files changed, 3083 insertions, 1985 deletions
diff --git a/chromium/chrome/browser/ui/webui/settings/OWNERS b/chromium/chrome/browser/ui/webui/settings/OWNERS index b0196fa4aa9..5b2350082b3 100644 --- a/chromium/chrome/browser/ui/webui/settings/OWNERS +++ b/chromium/chrome/browser/ui/webui/settings/OWNERS @@ -1,6 +1,7 @@ file://chrome/browser/resources/settings/OWNERS -per-file people_handler*=tangltom@chromium.org +per-file people_handler*=msalama@chromium.org +per-file people_handler*=treib@chromium.org per-file *site_settings*=msramek@chromium.org per-file *site_settings*=sauski@google.com diff --git a/chromium/chrome/browser/ui/webui/settings/about_handler.cc b/chromium/chrome/browser/ui/webui/settings/about_handler.cc index a1bb190d093..549152c3ee1 100644 --- a/chromium/chrome/browser/ui/webui/settings/about_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/about_handler.cc @@ -27,7 +27,6 @@ #include "build/branding_buildflags.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/chrome_content_browser_client.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" @@ -54,7 +53,6 @@ #include "chrome/browser/chromeos/arc/arc_util.h" #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h" #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h" -#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/chromeos/tpm_firmware_update.h" @@ -63,6 +61,7 @@ #include "chrome/browser/ui/webui/chromeos/image_source.h" #include "chrome/browser/ui/webui/help/help_utils_chromeos.h" #include "chrome/browser/ui/webui/help/version_updater_chromeos.h" +#include "chrome/browser/ui/webui/webui_util.h" #include "chromeos/constants/chromeos_features.h" #include "chromeos/constants/chromeos_switches.h" #include "chromeos/dbus/power/power_manager_client.h" @@ -117,16 +116,9 @@ base::string16 GetAllowedConnectionTypesMessage() { } } -// Returns true if the device is enterprise managed, false otherwise. -bool IsEnterpriseManaged() { - policy::BrowserPolicyConnectorChromeOS* connector = - g_browser_process->platform_part()->browser_policy_connector_chromeos(); - return connector->IsEnterpriseManaged(); -} - // Returns true if current user can change channel, false otherwise. bool CanChangeChannel(Profile* profile) { - if (IsEnterpriseManaged()) { + if (webui::IsEnterpriseManaged()) { bool value = false; // On a managed machine we delegate this setting to the affiliated users // only if the policy value is true. @@ -259,7 +251,8 @@ std::string UpdateStatusToString(VersionUpdater::Status status) { namespace settings { -AboutHandler::AboutHandler() : apply_changes_from_upgrade_observer_(false) { +AboutHandler::AboutHandler(Profile* profile) + : profile_(profile), apply_changes_from_upgrade_observer_(false) { UpgradeDetector::GetInstance()->AddObserver(this); } @@ -331,7 +324,7 @@ void AboutHandler::RegisterMessages() { base::BindRepeating(&AboutHandler::HandleCheckInternetConnection, base::Unretained(this))); #endif -#if defined(OS_MACOSX) +#if defined(OS_MAC) web_ui()->RegisterMessageCallback( "promoteUpdater", base::BindRepeating(&AboutHandler::PromoteUpdater, base::Unretained(this))); @@ -339,7 +332,7 @@ void AboutHandler::RegisterMessages() { #if defined(OS_CHROMEOS) // Handler for the product label image, which will be shown if available. - content::URLDataSource::Add(Profile::FromWebUI(web_ui()), + content::URLDataSource::Add(profile_, std::make_unique<chromeos::ImageSource>()); #endif } @@ -406,7 +399,7 @@ void AboutHandler::RefreshUpdateStatus() { #endif } -#if defined(OS_MACOSX) +#if defined(OS_MAC) void AboutHandler::PromoteUpdater(const base::ListValue* args) { version_updater_->PromoteUpdater(); } @@ -452,6 +445,18 @@ void AboutHandler::HandleCheckInternetConnection(const base::ListValue* args) { void AboutHandler::HandleLaunchReleaseNotes(const base::ListValue* args) { DCHECK(args->empty()); + // If the flag is enabled, we can always show the release notes since the Help + // app caches it, or can show an appropriate error state (e.g. No internet + // connection). + if (base::FeatureList::IsEnabled(chromeos::features::kHelpAppReleaseNotes)) { + base::RecordAction( + base::UserMetricsAction("ReleaseNotes.LaunchedAboutPage")); + chrome::LaunchReleaseNotes(profile_, + apps::mojom::LaunchSource::kFromOtherApp); + return; + } + + // If the flag is disabled, we need connectivity to load the PWA. chromeos::NetworkStateHandler* network_state_handler = chromeos::NetworkHandler::Get()->network_state_handler(); const chromeos::NetworkState* network = @@ -459,7 +464,8 @@ void AboutHandler::HandleLaunchReleaseNotes(const base::ListValue* args) { if (network && network->IsOnline()) { base::RecordAction( base::UserMetricsAction("ReleaseNotes.LaunchedAboutPage")); - chrome::LaunchReleaseNotes(Profile::FromWebUI(web_ui())); + chrome::LaunchReleaseNotes(profile_, + apps::mojom::LaunchSource::kFromOtherApp); } } @@ -473,7 +479,7 @@ void AboutHandler::HandleOpenOsHelpPage(const base::ListValue* args) { void AboutHandler::HandleSetChannel(const base::ListValue* args) { DCHECK(args->GetSize() == 2); - if (!CanChangeChannel(Profile::FromWebUI(web_ui()))) { + if (!CanChangeChannel(profile_)) { LOG(WARNING) << "Non-owner tried to change release track."; return; } @@ -539,9 +545,8 @@ void AboutHandler::HandleCanChangeChannel(const base::ListValue* args) { CHECK_EQ(1U, args->GetSize()); std::string callback_id; CHECK(args->GetString(0, &callback_id)); - ResolveJavascriptCallback( - base::Value(callback_id), - base::Value(CanChangeChannel(Profile::FromWebUI(web_ui())))); + ResolveJavascriptCallback(base::Value(callback_id), + base::Value(CanChangeChannel(profile_))); } void AboutHandler::OnGetCurrentChannel(std::string callback_id, @@ -560,6 +565,13 @@ void AboutHandler::OnGetTargetChannel(std::string callback_id, channel_info->SetString("currentChannel", current_channel); channel_info->SetString("targetChannel", target_channel); + // For the LTS pilot simply check whether the device policy is set and ignore + // its value. + std::string value; + bool is_lts = chromeos::CrosSettings::Get()->GetString( + chromeos::kReleaseLtsTag, &value); + channel_info->SetBoolean("isLts", is_lts); + ResolveJavascriptCallback(base::Value(callback_id), *channel_info); } @@ -618,15 +630,17 @@ void AboutHandler::OnGetEndOfLifeInfo( chromeos::UpdateEngineClient::EolInfo eol_info) { base::Value response(base::Value::Type::DICTIONARY); if (!eol_info.eol_date.is_null()) { - response.SetBoolKey("hasEndOfLife", eol_info.eol_date <= base::Time::Now()); - int eol_string_id = eol_info.eol_date <= base::Time::Now() - ? IDS_SETTINGS_ABOUT_PAGE_END_OF_LIFE_MESSAGE_PAST - : IDS_SETTINGS_ABOUT_PAGE_END_OF_LIFE_MESSAGE_FUTURE; + bool has_eol_passed = eol_info.eol_date <= base::Time::Now(); + response.SetBoolKey("hasEndOfLife", has_eol_passed); + int eol_string_id = + has_eol_passed ? IDS_SETTINGS_ABOUT_PAGE_END_OF_LIFE_MESSAGE_PAST + : IDS_SETTINGS_ABOUT_PAGE_END_OF_LIFE_MESSAGE_FUTURE; response.SetStringKey( - "aboutPageEndOfLifeMessage", - l10n_util::GetStringFUTF16( - eol_string_id, base::TimeFormatMonthAndYear(eol_info.eol_date), - base::ASCIIToUTF16(chrome::kEolNotificationURL))); + "aboutPageEndOfLifeMessage", + l10n_util::GetStringFUTF16( + eol_string_id, base::TimeFormatMonthAndYear(eol_info.eol_date), + base::ASCIIToUTF16(has_eol_passed ? chrome::kEolNotificationURL + : chrome::kAutoUpdatePolicyURL))); } else { response.SetBoolKey("hasEndOfLife", false); response.SetStringKey("aboutPageEndOfLifeMessage", ""); @@ -639,11 +653,11 @@ void AboutHandler::OnGetEndOfLifeInfo( void AboutHandler::RequestUpdate() { version_updater_->CheckForUpdate( base::Bind(&AboutHandler::SetUpdateStatus, base::Unretained(this)), -#if defined(OS_MACOSX) +#if defined(OS_MAC) base::Bind(&AboutHandler::SetPromotionState, base::Unretained(this))); #else VersionUpdater::PromoteCallback()); -#endif // OS_MACOSX +#endif // OS_MAC } void AboutHandler::SetUpdateStatus(VersionUpdater::Status status, @@ -681,7 +695,7 @@ void AboutHandler::SetUpdateStatus(VersionUpdater::Status status, FireWebUIListener("update-status-changed", *event); } -#if defined(OS_MACOSX) +#if defined(OS_MAC) void AboutHandler::SetPromotionState(VersionUpdater::PromotionState state) { // Worth noting: PROMOTE_DISABLED indicates that promotion is possible, // there's just something else going on right now (e.g. checking for update). @@ -707,7 +721,7 @@ void AboutHandler::SetPromotionState(VersionUpdater::PromotionState state) { FireWebUIListener("promotion-state-changed", promo_state); } -#endif // defined(OS_MACOSX) +#endif // defined(OS_MAC) #if defined(OS_CHROMEOS) void AboutHandler::OnRegulatoryLabelDirFound( diff --git a/chromium/chrome/browser/ui/webui/settings/about_handler.h b/chromium/chrome/browser/ui/webui/settings/about_handler.h index bc71e2da278..9f1fcb630b2 100644 --- a/chromium/chrome/browser/ui/webui/settings/about_handler.h +++ b/chromium/chrome/browser/ui/webui/settings/about_handler.h @@ -30,13 +30,15 @@ class FilePath; class ListValue; } // namespace base +class Profile; + namespace settings { // WebUI message handler for the help page. class AboutHandler : public settings::SettingsPageUIHandler, public UpgradeObserver { public: - AboutHandler(); + explicit AboutHandler(Profile* profile); ~AboutHandler() override; // WebUIMessageHandler implementation. @@ -64,7 +66,7 @@ class AboutHandler : public settings::SettingsPageUIHandler, void HandleRefreshUpdateStatus(const base::ListValue* args); void RefreshUpdateStatus(); -#if defined(OS_MACOSX) +#if defined(OS_MAC) // Promotes the updater for all users. void PromoteUpdater(const base::ListValue* args); #endif @@ -140,7 +142,7 @@ class AboutHandler : public settings::SettingsPageUIHandler, int64_t size, const base::string16& fail_message); -#if defined(OS_MACOSX) +#if defined(OS_MAC) // Callback method which forwards promotion state to the page. void SetPromotionState(VersionUpdater::PromotionState state); #endif @@ -169,6 +171,8 @@ class AboutHandler : public settings::SettingsPageUIHandler, chromeos::UpdateEngineClient::EolInfo eol_info); #endif + Profile* profile_; + // Specialized instance of the VersionUpdater used to update the browser. std::unique_ptr<VersionUpdater> version_updater_; diff --git a/chromium/chrome/browser/ui/webui/settings/about_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/about_handler_unittest.cc new file mode 100644 index 00000000000..bdfcdf6e8de --- /dev/null +++ b/chromium/chrome/browser/ui/webui/settings/about_handler_unittest.cc @@ -0,0 +1,118 @@ +// 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/about_handler.h" + +#include "chrome/test/base/testing_browser_process.h" +#include "chrome/test/base/testing_profile.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/fake_update_engine_client.h" +#include "content/public/test/browser_task_environment.h" +#include "content/public/test/test_web_ui.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromeos { +namespace settings { + +namespace { + +class TestAboutHandler : public ::settings::AboutHandler { + public: + explicit TestAboutHandler(Profile* profile) : AboutHandler(profile) {} + ~TestAboutHandler() override = default; + + // Make public for testing. + using AboutHandler::set_web_ui; +}; + +class AboutHandlerTest : public testing::Test { + public: + AboutHandlerTest() = default; + ~AboutHandlerTest() override = default; + AboutHandlerTest(const AboutHandlerTest&) = delete; + AboutHandlerTest& operator=(const AboutHandlerTest&) = delete; + + void SetUp() override { + fake_update_engine_client_ = new FakeUpdateEngineClient(); + DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient( + base::WrapUnique<UpdateEngineClient>(fake_update_engine_client_)); + DBusThreadManager::Initialize(); + + handler_ = std::make_unique<TestAboutHandler>(&profile_); + handler_->set_web_ui(&web_ui_); + handler_->RegisterMessages(); + handler_->AllowJavascriptForTesting(); + } + + void TearDown() override { + handler_.reset(); + TestingBrowserProcess::GetGlobal()->SetLocalState(nullptr); + } + + const content::TestWebUI::CallData& CallDataAtIndex(size_t index) { + return *web_ui_.call_data()[index]; + } + + std::string CallGetEndOfLifeInfoAndReturnString(bool has_eol_passed) { + size_t call_data_count_before_call = web_ui_.call_data().size(); + + base::ListValue args; + args.AppendString("handlerFunctionName"); + web_ui_.HandleReceivedMessage("getEndOfLifeInfo", &args); + task_environment_.RunUntilIdle(); + + EXPECT_EQ(call_data_count_before_call + 1u, web_ui_.call_data().size()); + + const content::TestWebUI::CallData& call_data = + CallDataAtIndex(call_data_count_before_call); + EXPECT_EQ("cr.webUIResponse", call_data.function_name()); + EXPECT_EQ("handlerFunctionName", call_data.arg1()->GetString()); + EXPECT_EQ(has_eol_passed, + call_data.arg3()->FindKey("hasEndOfLife")->GetBool()); + return call_data.arg3()->FindKey("aboutPageEndOfLifeMessage")->GetString(); + } + + protected: + content::BrowserTaskEnvironment task_environment_; + TestingProfile profile_; + content::TestWebUI web_ui_; + std::unique_ptr<TestAboutHandler> handler_; + FakeUpdateEngineClient* fake_update_engine_client_; +}; + +// Deterministic fail on CHROMEOS, crbug.com/1122584. +#if defined(OS_CHROMEOS) +#define MAYBE_EndOfLifeMessageInAboutDetailsSubpage \ + DISABLED_EndOfLifeMessageInAboutDetailsSubpage +#else +#define MAYBE_EndOfLifeMessageInAboutDetailsSubpage \ + EndOfLifeMessageInAboutDetailsSubpage +#endif +TEST_F(AboutHandlerTest, MAYBE_EndOfLifeMessageInAboutDetailsSubpage) { + const base::Time eol_passed_date = + base::Time::Now() - base::TimeDelta::FromDays(1000); + fake_update_engine_client_->set_eol_date(eol_passed_date); + EXPECT_EQ( + "This device stopped getting automatic software and security " + "updates in November 2017. <a target=\"_blank\" href=\"https:" + "//www.google.com/chromebook/older/\">Learn more</a>", + CallGetEndOfLifeInfoAndReturnString(true /*=has_eol_passed*/)); + + const base::Time eol_future_date = + base::Time::Now() + base::TimeDelta::FromDays(1000); + fake_update_engine_client_->set_eol_date(eol_future_date); + EXPECT_EQ( + "This device will get automatic software and security updates " + "until May 2023. <a target=\"_blank\" href=\"http://support.google" + ".com/chrome/a?p=auto-update-policy\">Learn more</a>", + CallGetEndOfLifeInfoAndReturnString(false /*=has_eol_passed*/)); + + const base::Time null_time = base::Time(); + fake_update_engine_client_->set_eol_date(null_time); + EXPECT_EQ("", CallGetEndOfLifeInfoAndReturnString(false /*=has_eol_passed*/)); +} + +} // namespace + +} // namespace settings +} // namespace chromeos diff --git a/chromium/chrome/browser/ui/webui/settings/accessibility_main_handler.cc b/chromium/chrome/browser/ui/webui/settings/accessibility_main_handler.cc index 7727acbd938..9f4901c4563 100644 --- a/chromium/chrome/browser/ui/webui/settings/accessibility_main_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/accessibility_main_handler.cc @@ -4,6 +4,9 @@ #include "chrome/browser/ui/webui/settings/accessibility_main_handler.h" +#include <utility> +#include <vector> + #include "base/bind.h" #include "base/values.h" #include "chrome/browser/accessibility/accessibility_state_utils.h" @@ -15,20 +18,49 @@ #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" + #if !defined(OS_CHROMEOS) +#include "base/check_op.h" +#include "base/numerics/ranges.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/component_updater/soda_component_installer.h" +#include "chrome/common/pref_names.h" +#include "chrome/grit/chromium_strings.h" +#include "chrome/grit/generated_resources.h" +#include "components/prefs/pref_service.h" +#include "components/update_client/crx_update_item.h" #include "content/public/browser/browser_accessibility_state.h" +#include "ui/base/l10n/l10n_util.h" + +namespace { + +int GetDownloadProgress(int64_t downloaded_bytes, int64_t total_bytes) { + if (downloaded_bytes == -1 || total_bytes == -1 || total_bytes == 0) + return -1; + DCHECK_LE(downloaded_bytes, total_bytes); + return 100 * + base::ClampToRange(double{downloaded_bytes} / total_bytes, 0.0, 1.0); +} + +} // namespace + #endif // !defined(OS_CHROMEOS) namespace settings { +#if defined(OS_CHROMEOS) AccessibilityMainHandler::AccessibilityMainHandler() = default; +#else +AccessibilityMainHandler::AccessibilityMainHandler(PrefService* prefs) + : prefs_(prefs) {} +#endif // defined(OS_CHROMEOS) AccessibilityMainHandler::~AccessibilityMainHandler() = default; void AccessibilityMainHandler::RegisterMessages() { web_ui()->RegisterMessageCallback( - "getScreenReaderState", - base::BindRepeating(&AccessibilityMainHandler::HandleGetScreenReaderState, + "a11yPageReady", + base::BindRepeating(&AccessibilityMainHandler::HandleA11yPageReady, base::Unretained(this))); web_ui()->RegisterMessageCallback( "confirmA11yImageLabels", @@ -44,16 +76,20 @@ void AccessibilityMainHandler::OnJavascriptAllowed() { base::BindRepeating( &AccessibilityMainHandler::OnAccessibilityStatusChanged, base::Unretained(this))); +#else + component_updater_observer_.Add(g_browser_process->component_updater()); #endif // defined(OS_CHROMEOS) } void AccessibilityMainHandler::OnJavascriptDisallowed() { #if defined(OS_CHROMEOS) accessibility_subscription_.reset(); +#else + component_updater_observer_.RemoveAll(); #endif // defined(OS_CHROMEOS) } -void AccessibilityMainHandler::HandleGetScreenReaderState( +void AccessibilityMainHandler::HandleA11yPageReady( const base::ListValue* args) { AllowJavascript(); SendScreenReaderStateChanged(); @@ -87,6 +123,50 @@ void AccessibilityMainHandler::OnAccessibilityStatusChanged( SendScreenReaderStateChanged(); } } +#else +void AccessibilityMainHandler::OnEvent(Events event, const std::string& id) { + if (id != component_updater::SODAComponentInstallerPolicy::GetExtensionId()) + return; + + switch (event) { + case Events::COMPONENT_UPDATE_FOUND: + case Events::COMPONENT_UPDATE_READY: + case Events::COMPONENT_WAIT: + case Events::COMPONENT_UPDATE_DOWNLOADING: + case Events::COMPONENT_UPDATE_UPDATING: { + update_client::CrxUpdateItem item; + g_browser_process->component_updater()->GetComponentDetails(id, &item); + const int progress = + GetDownloadProgress(item.downloaded_bytes, item.total_bytes); + // When GetDownloadProgress returns -1, do nothing. It returns -1 when the + // downloaded or total bytes is unknown. + if (progress != -1) { + FireWebUIListener( + "enable-live-caption-subtitle-changed", + base::Value(l10n_util::GetStringFUTF16Int( + IDS_SETTINGS_CAPTIONS_LIVE_CAPTION_DOWNLOAD_PROGRESS, + progress))); + } + } break; + case Events::COMPONENT_UPDATED: + case Events::COMPONENT_NOT_UPDATED: + FireWebUIListener( + "enable-live-caption-subtitle-changed", + base::Value(l10n_util::GetStringUTF16( + IDS_SETTINGS_CAPTIONS_LIVE_CAPTION_DOWNLOAD_COMPLETE))); + break; + case Events::COMPONENT_UPDATE_ERROR: + prefs_->SetBoolean(prefs::kLiveCaptionEnabled, false); + FireWebUIListener( + "enable-live-caption-subtitle-changed", + base::Value(l10n_util::GetStringUTF16( + IDS_SETTINGS_CAPTIONS_LIVE_CAPTION_DOWNLOAD_ERROR))); + break; + case Events::COMPONENT_CHECKING_FOR_UPDATES: + // Do nothing. + break; + } +} #endif // defined(OS_CHROMEOS) } // namespace settings diff --git a/chromium/chrome/browser/ui/webui/settings/accessibility_main_handler.h b/chromium/chrome/browser/ui/webui/settings/accessibility_main_handler.h index c37f966672f..9824c7980a1 100644 --- a/chromium/chrome/browser/ui/webui/settings/accessibility_main_handler.h +++ b/chromium/chrome/browser/ui/webui/settings/accessibility_main_handler.h @@ -5,23 +5,42 @@ #ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_ACCESSIBILITY_MAIN_HANDLER_H_ #define CHROME_BROWSER_UI_WEBUI_SETTINGS_ACCESSIBILITY_MAIN_HANDLER_H_ +#include <memory> +#include <string> + #include "base/macros.h" #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" + #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" +#else +#include "base/scoped_observer.h" +#include "components/component_updater/component_updater_service.h" #endif // defined(OS_CHROMEOS) namespace base { class ListValue; } +class PrefService; + namespace settings { // Settings handler for the main accessibility settings page, // chrome://settings/accessibility. +// TODO(1055150) Implement the SODA download progress handling on ChromeOS and +// remove the ChromeOS-only class declaration. +#if defined(OS_CHROMEOS) class AccessibilityMainHandler : public ::settings::SettingsPageUIHandler { public: AccessibilityMainHandler(); +#else +class AccessibilityMainHandler : public ::settings::SettingsPageUIHandler, + public component_updater::ServiceObserver { + public: + explicit AccessibilityMainHandler(PrefService* prefs); +#endif // defined(OS_CHROMEOS) + ~AccessibilityMainHandler() override; // SettingsPageUIHandler implementation. @@ -29,7 +48,7 @@ class AccessibilityMainHandler : public ::settings::SettingsPageUIHandler { void OnJavascriptAllowed() override; void OnJavascriptDisallowed() override; - void HandleGetScreenReaderState(const base::ListValue* args); + void HandleA11yPageReady(const base::ListValue* args); void HandleCheckAccessibilityImageLabels(const base::ListValue* args); private: @@ -42,7 +61,13 @@ class AccessibilityMainHandler : public ::settings::SettingsPageUIHandler { std::unique_ptr<chromeos::AccessibilityStatusSubscription> accessibility_subscription_; #else + // component_updater::ServiceObserver: + void OnEvent(Events event, const std::string& id) override; + PrefService* prefs_; + ScopedObserver<component_updater::ComponentUpdateService, + component_updater::ComponentUpdateService::Observer> + component_updater_observer_{this}; #endif // defined(OS_CHROMEOS) DISALLOW_COPY_AND_ASSIGN(AccessibilityMainHandler); diff --git a/chromium/chrome/browser/ui/webui/settings/browser_lifetime_handler.cc b/chromium/chrome/browser/ui/webui/settings/browser_lifetime_handler.cc index 8a02491acd6..cf33d9cb641 100644 --- a/chromium/chrome/browser/ui/webui/settings/browser_lifetime_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/browser_lifetime_handler.cc @@ -11,9 +11,8 @@ #if defined(OS_CHROMEOS) #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/tpm_firmware_update.h" +#include "chrome/browser/ui/webui/webui_util.h" #include "chrome/common/pref_names.h" #include "components/prefs/pref_service.h" #include "components/user_manager/user_manager.h" @@ -104,10 +103,8 @@ void BrowserLifetimeHandler::HandleFactoryReset( } // TODO(crbug.com/891905): Centralize powerwash restriction checks. - policy::BrowserPolicyConnectorChromeOS* connector = - g_browser_process->platform_part()->browser_policy_connector_chromeos(); bool allow_powerwash = - !connector->IsEnterpriseManaged() && + !webui::IsEnterpriseManaged() && !user_manager::UserManager::Get()->IsLoggedInAsGuest() && !user_manager::UserManager::Get()->IsLoggedInAsSupervisedUser() && !user_manager::UserManager::Get()->IsLoggedInAsChildUser(); diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/BUILD.gn b/chromium/chrome/browser/ui/webui/settings/chromeos/BUILD.gn index e920c48a39b..7452b0526a7 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/BUILD.gn +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/BUILD.gn @@ -7,5 +7,6 @@ group("mojom_js") { "constants:mojom_js", "search:mojo_bindings_js", "//chrome/browser/ui/webui/app_management:mojo_bindings_js", + "//chrome/browser/ui/webui/nearby_share/public/mojom:mojom_js", ] } diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/about_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/about_section.cc index a90a99bfebb..c32688e2457 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/about_section.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/about_section.cc @@ -4,19 +4,19 @@ #include "chrome/browser/ui/webui/settings/chromeos/about_section.h" +#include "base/command_line.h" #include "base/feature_list.h" #include "base/i18n/message_formatter.h" #include "base/no_destructor.h" +#include "base/strings/string_split.h" #include "base/strings/utf_string_conversions.h" #include "base/system/sys_info.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/chromeos/arc/arc_util.h" -#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/obsolete_system/obsolete_system.h" #include "chrome/browser/ui/webui/management_ui.h" #include "chrome/browser/ui/webui/settings/about_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" +#include "chrome/browser/ui/webui/version_ui.h" #include "chrome/browser/ui/webui/webui_util.h" #include "chrome/common/channel_info.h" #include "chrome/common/pref_names.h" @@ -139,19 +139,6 @@ std::string GetSafetyInfoLink() { return std::string(); } -// Returns true if the device is enterprise managed, false otherwise. -bool IsEnterpriseManaged() { - policy::BrowserPolicyConnectorChromeOS* connector = - g_browser_process->platform_part()->browser_policy_connector_chromeos(); - return connector->IsEnterpriseManaged(); -} - -bool IsDeviceManaged() { - policy::BrowserPolicyConnectorChromeOS* connector = - g_browser_process->platform_part()->browser_policy_connector_chromeos(); - return connector->IsEnterpriseManaged(); -} - } // namespace #if BUILDFLAG(GOOGLE_CHROME_BRANDING) @@ -246,6 +233,8 @@ void AboutSection::AddLoadTimeData(content::WebUIDataSource* html_source) { {"aboutChannelDev", IDS_SETTINGS_ABOUT_PAGE_CURRENT_CHANNEL_DEV}, {"aboutChannelLabel", IDS_SETTINGS_ABOUT_PAGE_CHANNEL}, {"aboutChannelStable", IDS_SETTINGS_ABOUT_PAGE_CURRENT_CHANNEL_STABLE}, + {"aboutChannelLongTermStable", + IDS_SETTINGS_ABOUT_PAGE_CURRENT_CHANNEL_STABLE_TT}, {"aboutCheckForUpdates", IDS_SETTINGS_ABOUT_PAGE_CHECK_FOR_UPDATES}, {"aboutCurrentlyOnChannel", IDS_SETTINGS_ABOUT_PAGE_CURRENT_CHANNEL}, {"aboutDetailedBuildInfo", IDS_SETTINGS_ABOUT_PAGE_DETAILED_BUILD_INFO}, @@ -277,7 +266,7 @@ void AboutSection::AddLoadTimeData(content::WebUIDataSource* html_source) { if (user_manager::UserManager::IsInitialized()) { user_manager::UserManager* user_manager = user_manager::UserManager::Get(); - if (!IsDeviceManaged() && !user_manager->IsCurrentUserOwner()) { + if (!webui::IsEnterpriseManaged() && !user_manager->IsCurrentUserOwner()) { html_source->AddString("ownerEmail", user_manager->GetOwnerAccountId().GetUserEmail()); } @@ -292,9 +281,7 @@ void AboutSection::AddLoadTimeData(content::WebUIDataSource* html_source) { ? IDS_VERSION_UI_OFFICIAL : IDS_VERSION_UI_UNOFFICIAL), base::UTF8ToUTF16(chrome::GetChannelName()), - l10n_util::GetStringUTF16(sizeof(void*) == 8 - ? IDS_VERSION_UI_64BIT - : IDS_VERSION_UI_32BIT))); + l10n_util::GetStringUTF16(VersionUI::VersionProcessorVariation()))); html_source->AddString( "aboutProductCopyright", base::i18n::MessageFormatter::FormatWithNumberedArgs( @@ -316,7 +303,8 @@ void AboutSection::AddLoadTimeData(content::WebUIDataSource* html_source) { base::ASCIIToUTF16(chrome::kChromeUICrostiniCreditsURL)); html_source->AddString("aboutProductOsWithLinuxLicense", os_with_linux_license); - html_source->AddBoolean("aboutEnterpriseManaged", IsEnterpriseManaged()); + html_source->AddBoolean("aboutEnterpriseManaged", + webui::IsEnterpriseManaged()); html_source->AddBoolean("aboutIsArcEnabled", arc::IsArcPlayStoreEnabledForProfile(profile())); html_source->AddBoolean("aboutIsDeveloperMode", @@ -345,7 +333,8 @@ void AboutSection::AddLoadTimeData(content::WebUIDataSource* html_source) { } void AboutSection::AddHandlers(content::WebUI* web_ui) { - web_ui->AddMessageHandler(std::make_unique<::settings::AboutHandler>()); + web_ui->AddMessageHandler( + std::make_unique<::settings::AboutHandler>(profile())); } int AboutSection::GetSectionNameMessageId() const { 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 c1e27295f71..52e12fd314a 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc @@ -4,7 +4,6 @@ #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" @@ -29,10 +28,6 @@ void RecordShowShelfNavigationButtonsValueChange(bool enabled) { enabled); } -bool IsTabletModeEnabled() { - return ash::TabletMode::Get() && ash::TabletMode::Get()->InTabletMode(); -} - } // namespace AccessibilityHandler::AccessibilityHandler(Profile* profile) @@ -71,16 +66,6 @@ void AccessibilityHandler::RegisterMessages() { base::Unretained(this))); } -void AccessibilityHandler::OnJavascriptAllowed() { - if (ash::TabletMode::Get()) { - tablet_mode_observer_.Add(ash::TabletMode::Get()); - } -} - -void AccessibilityHandler::OnJavascriptDisallowed() { - tablet_mode_observer_.RemoveAll(); -} - void AccessibilityHandler::HandleShowChromeVoxSettings( const base::ListValue* args) { OpenExtensionOptionsPage(extension_misc::kChromeVoxExtensionId); @@ -116,16 +101,7 @@ void AccessibilityHandler::HandleManageA11yPageReady( FireWebUIListener( "initial-data-ready", - base::Value(AccessibilityManager::Get()->GetStartupSoundEnabled()), - base::Value(IsTabletModeEnabled())); -} - -void AccessibilityHandler::OnTabletModeStarted() { - FireWebUIListener("tablet-mode-changed", base::Value(IsTabletModeEnabled())); -} - -void AccessibilityHandler::OnTabletModeEnded() { - FireWebUIListener("tablet-mode-changed", base::Value(IsTabletModeEnabled())); + base::Value(AccessibilityManager::Get()->GetStartupSoundEnabled())); } 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 6949f7606c8..99d6c40bd35 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h @@ -5,10 +5,7 @@ #ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_ACCESSIBILITY_HANDLER_H_ #define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_ACCESSIBILITY_HANDLER_H_ -#include "ash/public/cpp/tablet_mode.h" -#include "ash/public/cpp/tablet_mode_observer.h" #include "base/macros.h" -#include "base/scoped_observer.h" #include "base/timer/timer.h" #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" @@ -21,25 +18,19 @@ class Profile; namespace chromeos { namespace settings { -class AccessibilityHandler : public ::settings::SettingsPageUIHandler, - public ash::TabletModeObserver { +class AccessibilityHandler : public ::settings::SettingsPageUIHandler { public: explicit AccessibilityHandler(Profile* profile); ~AccessibilityHandler() override; // SettingsPageUIHandler implementation. void RegisterMessages() override; - void OnJavascriptAllowed() override; - void OnJavascriptDisallowed() override; + void OnJavascriptAllowed() override {} + void OnJavascriptDisallowed() override {} - // Callback which updates if startup sound is enabled and if tablet - // mode is supported. Visible for testing. + // Callback which updates if startup sound is enabled. Visible for testing. void HandleManageA11yPageReady(const base::ListValue* args); - // ash::TabletModeObserver: - void OnTabletModeStarted() override; - void OnTabletModeEnded() override; - private: // Callback for the messages to show settings for ChromeVox or // Select To Speak. @@ -51,9 +42,6 @@ class AccessibilityHandler : public ::settings::SettingsPageUIHandler, void OpenExtensionOptionsPage(const char extension_id[]); - ScopedObserver<ash::TabletMode, ash::TabletModeObserver> - tablet_mode_observer_{this}; - Profile* profile_; // Weak pointer. // Timer to record user changed value for the accessibility setting to turn 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 deleted file mode 100644 index c250285176a..00000000000 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler_unittest.cc +++ /dev/null @@ -1,77 +0,0 @@ -// 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 "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(); - test_tablet_mode_ = std::make_unique<ash::TestTabletMode>(); - handler_ = std::make_unique<TestingAccessibilityHandler>(&web_ui_); - } - - void TearDown() override { - handler_.reset(); - test_tablet_mode_.reset(); - 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 disabled, the correct data is returned by -// HandleManageA11yPageReady(). -TEST_F(AccessibilityHandlerTest, ManageA11yPageReadyTabletModeDisabled) { - test_tablet_mode_->SetEnabledForTest(false); - handler_->HandleManageA11yPageReady(/* args */ nullptr); - - const content::TestWebUI::CallData& call_data = *web_ui_.call_data().back(); - - // Ensure tablet mode is returned as disabled. - 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 enabled. - EXPECT_TRUE(call_data.arg3()->GetBool()); -} - -} // namespace settings -} // namespace chromeos diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc index a38be955b4e..587ac2b55a7 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_section.cc @@ -6,6 +6,7 @@ #include "ash/public/cpp/ash_features.h" #include "ash/public/cpp/ash_pref_names.h" +#include "ash/public/cpp/tablet_mode.h" #include "base/command_line.h" #include "base/feature_list.h" #include "base/no_destructor.h" @@ -74,12 +75,6 @@ const std::vector<SearchConcept>& GetA11ySearchConcepts() { mojom::SearchResultType::kSetting, {.setting = mojom::Setting::kChromeVox}, {IDS_OS_SETTINGS_TAG_A11y_CHROMEVOX_ALT1, SearchConcept::kAltTagEnd}}, - {IDS_OS_SETTINGS_TAG_A11Y_TABLET_NAVIGATION_BUTTONS, - mojom::kManageAccessibilitySubpagePath, - mojom::SearchResultIcon::kA11y, - mojom::SearchResultDefaultRank::kMedium, - mojom::SearchResultType::kSetting, - {.setting = mojom::Setting::kTabletNavigationButtons}}, {IDS_OS_SETTINGS_TAG_A11Y_MONO_AUDIO, mojom::kManageAccessibilitySubpagePath, mojom::SearchResultIcon::kA11y, @@ -217,6 +212,19 @@ const std::vector<SearchConcept>& GetA11ySwitchAccessSearchConcepts() { return *tags; } +const std::vector<SearchConcept>& +GetA11yTabletNavigationButtonSearchConcepts() { + static const base::NoDestructor<std::vector<SearchConcept>> tags({ + {IDS_OS_SETTINGS_TAG_A11Y_TABLET_NAVIGATION_BUTTONS, + mojom::kManageAccessibilitySubpagePath, + mojom::SearchResultIcon::kA11y, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSetting, + {.setting = mojom::Setting::kTabletNavigationButtons}}, + }); + return *tags; +} + const std::vector<SearchConcept>& GetA11ySwitchAccessOnSearchConcepts() { static const base::NoDestructor<std::vector<SearchConcept>> tags({ {IDS_OS_SETTINGS_TAG_A11Y_SWITCH_ACCESS_ASSIGNMENT, @@ -312,6 +320,11 @@ bool IsSwitchAccessTextAllowed() { ::switches::kEnableExperimentalAccessibilitySwitchAccessText); } +bool AreTabletNavigationButtonsAllowed() { + return ash::features::IsHideShelfControlsInTabletModeEnabled() && + ash::TabletMode::IsBoardTypeMarkedAsTabletCapable(); +} + } // namespace AccessibilitySection::AccessibilitySection( @@ -323,6 +336,9 @@ AccessibilitySection::AccessibilitySection( SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate(); updater.AddSearchTags(GetA11ySearchConcepts()); + if (AreTabletNavigationButtonsAllowed()) + updater.AddSearchTags(GetA11yTabletNavigationButtonSearchConcepts()); + pref_change_registrar_.Init(pref_service_); pref_change_registrar_.Add( ash::prefs::kAccessibilitySwitchAccessEnabled, @@ -359,13 +375,15 @@ void AccessibilitySection::AddLoadTimeData( IDS_SETTINGS_LARGE_MOUSE_CURSOR_SIZE_DEFAULT_LABEL}, {"largeMouseCursorSizeLargeLabel", IDS_SETTINGS_LARGE_MOUSE_CURSOR_SIZE_LARGE_LABEL}, - {"cursorColorEnabledLabel", IDS_SETTINGS_CURSOR_COLOR_ENABLED_LABEL}, {"cursorColorOptionsLabel", IDS_SETTINGS_CURSOR_COLOR_OPTIONS_LABEL}, + {"cursorColorBlack", IDS_SETTINGS_CURSOR_COLOR_BLACK}, {"cursorColorRed", IDS_SETTINGS_CURSOR_COLOR_RED}, - {"cursorColorOrange", IDS_SETTINGS_CURSOR_COLOR_ORANGE}, + {"cursorColorYellow", IDS_SETTINGS_CURSOR_COLOR_YELLOW}, {"cursorColorGreen", IDS_SETTINGS_CURSOR_COLOR_GREEN}, + {"cursorColorCyan", IDS_SETTINGS_CURSOR_COLOR_CYAN}, {"cursorColorBlue", IDS_SETTINGS_CURSOR_COLOR_BLUE}, - {"cursorColorPurple", IDS_SETTINGS_CURSOR_COLOR_PURPLE}, + {"cursorColorMagenta", IDS_SETTINGS_CURSOR_COLOR_MAGENTA}, + {"cursorColorPink", IDS_SETTINGS_CURSOR_COLOR_PINK}, {"highContrastLabel", IDS_SETTINGS_HIGH_CONTRAST_LABEL}, {"stickyKeysLabel", IDS_SETTINGS_STICKY_KEYS_LABEL}, {"chromeVoxLabel", IDS_SETTINGS_CHROMEVOX_LABEL}, @@ -438,6 +456,8 @@ void AccessibilitySection::AddLoadTimeData( {"manageSwitchAccessSettings", IDS_SETTINGS_MANAGE_SWITCH_ACCESS_SETTINGS}, {"switchAssignmentHeading", IDS_SETTINGS_SWITCH_ASSIGNMENT_HEADING}, + {"switchAssignOptionPlaceholder", + IDS_SETTINGS_SWITCH_ASSIGN_OPTION_PLACEHOLDER}, {"switchAssignOptionNone", IDS_SETTINGS_SWITCH_ASSIGN_OPTION_NONE}, {"switchAssignOptionSpace", IDS_SETTINGS_SWITCH_ASSIGN_OPTION_SPACE}, {"switchAssignOptionEnter", IDS_SETTINGS_SWITCH_ASSIGN_OPTION_ENTER}, @@ -520,6 +540,8 @@ void AccessibilitySection::AddLoadTimeData( IDS_SETTINGS_CAPTIONS_ENABLE_LIVE_CAPTION_TITLE}, {"captionsEnableLiveCaptionSubtitle", IDS_SETTINGS_CAPTIONS_ENABLE_LIVE_CAPTION_SUBTITLE}, + {"caretBrowsingTitle", IDS_SETTINGS_ENABLE_CARET_BROWSING_TITLE}, + {"caretBrowsingSubtitle", IDS_SETTINGS_ENABLE_CARET_BROWSING_SUBTITLE}, }; AddLocalizedStringsBulk(html_source, kLocalizedStrings); @@ -535,9 +557,8 @@ void AccessibilitySection::AddLoadTimeData( html_source->AddBoolean("showExperimentalA11yLabels", AreExperimentalA11yLabelsAllowed()); - html_source->AddBoolean( - "showTabletModeShelfNavigationButtonsSettings", - ash::features::IsHideShelfControlsInTabletModeEnabled()); + html_source->AddBoolean("showTabletModeShelfNavigationButtonsSettings", + AreTabletNavigationButtonsAllowed()); html_source->AddString("tabletModeShelfNavigationButtonsLearnMoreUrl", chrome::kTabletModeGesturesLearnMoreURL); diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.cc index fd4f14a6d09..c1c3fdedf65 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.cc @@ -4,12 +4,31 @@ #include "chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.h" +#include <algorithm> +#include <string> +#include <utility> + #include "ash/public/cpp/ambient/ambient_backend_controller.h" #include "ash/public/cpp/ambient/common/ambient_settings.h" +#include "ash/public/cpp/image_downloader.h" #include "base/bind.h" +#include "base/callback.h" +#include "base/logging.h" +#include "base/memory/ref_counted_memory.h" #include "base/stl_util.h" +#include "base/strings/string16.h" #include "base/strings/string_number_conversions.h" #include "base/values.h" +#include "chrome/grit/generated_resources.h" +#include "chromeos/constants/chromeos_features.h" +#include "net/traffic_annotation/network_traffic_annotation.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/webui/web_ui_util.h" +#include "ui/gfx/codec/png_codec.h" +#include "ui/gfx/geometry/size.h" +#include "ui/gfx/image/image_skia.h" +#include "url/gurl.h" namespace chromeos { namespace settings { @@ -17,19 +36,76 @@ namespace settings { namespace { // Width and height of the preview image for personal album. -constexpr int kBannerWidth = 512; -constexpr int kBannderHeight = 512; +constexpr int kBannerWidthPx = 160; +constexpr int kBannerHeightPx = 160; -ash::AmbientModeTopicSource ExtractTopicSource(const base::ListValue* args) { - CHECK_EQ(args->GetSize(), 1U); +// Strings for converting to and from AmbientModeTemperatureUnit enum. +constexpr char kCelsius[] = "celsius"; +constexpr char kFahrenheit[] = "fahrenheit"; + +ash::AmbientModeTemperatureUnit ExtractTemperatureUnit( + const base::ListValue* args) { + auto temperature_unit = args->GetList()[0].GetString(); + if (temperature_unit == kCelsius) { + return ash::AmbientModeTemperatureUnit::kCelsius; + } else if (temperature_unit == kFahrenheit) { + return ash::AmbientModeTemperatureUnit::kFahrenheit; + } + NOTREACHED() << "Unknown temperature unit"; + return ash::AmbientModeTemperatureUnit::kFahrenheit; +} + +std::string TemperatureUnitToString( + ash::AmbientModeTemperatureUnit temperature_unit) { + switch (temperature_unit) { + case ash::AmbientModeTemperatureUnit::kFahrenheit: + return kFahrenheit; + case ash::AmbientModeTemperatureUnit::kCelsius: + return kCelsius; + } +} + +ash::AmbientModeTopicSource ExtractTopicSource(const base::Value& value) { ash::AmbientModeTopicSource topic_source = - static_cast<ash::AmbientModeTopicSource>(args->GetList()[0].GetInt()); + static_cast<ash::AmbientModeTopicSource>(value.GetInt()); // Check the |topic_source| has valid value. CHECK_GE(topic_source, ash::AmbientModeTopicSource::kMinValue); CHECK_LE(topic_source, ash::AmbientModeTopicSource::kMaxValue); return topic_source; } +ash::AmbientModeTopicSource ExtractTopicSource(const base::ListValue* args) { + CHECK_EQ(args->GetSize(), 1U); + return ExtractTopicSource(args->GetList()[0]); +} + +void EncodeImage(const gfx::ImageSkia& image, + std::vector<unsigned char>* output) { + if (!gfx::PNGCodec::EncodeBGRASkBitmap(*image.bitmap(), + /*discard_transparency=*/false, + output)) { + VLOG(1) << "Failed to encode image to png"; + output->clear(); + } +} + +base::string16 GetAlbumDescription(const ash::PersonalAlbum& album) { + if (album.album_id == ash::kAmbientModeRecentHighlightsAlbumId) { + return l10n_util::GetStringUTF16( + IDS_OS_SETTINGS_AMBIENT_MODE_ALBUMS_SUBPAGE_RECENT_DESC); + } + + if (album.number_of_photos <= 1) { + return l10n_util::GetStringFUTF16Int( + IDS_OS_SETTINGS_AMBIENT_MODE_ALBUMS_SUBPAGE_PHOTOS_NUM_SINGULAR, + album.number_of_photos); + } + + return l10n_util::GetStringFUTF16Int( + IDS_OS_SETTINGS_AMBIENT_MODE_ALBUMS_SUBPAGE_PHOTOS_NUM_PLURAL, + album.number_of_photos); +} + } // namespace AmbientModeHandler::AmbientModeHandler() = default; @@ -38,161 +114,194 @@ AmbientModeHandler::~AmbientModeHandler() = default; void AmbientModeHandler::RegisterMessages() { web_ui()->RegisterMessageCallback( - "onAmbientModePageReady", - base::BindRepeating(&AmbientModeHandler::HandleInitialized, + "requestSettings", + base::BindRepeating(&AmbientModeHandler::HandleRequestSettings, base::Unretained(this))); web_ui()->RegisterMessageCallback( - "setSelectedTopicSource", - base::BindRepeating(&AmbientModeHandler::HandleSetSelectedTopicSource, + "requestAlbums", + base::BindRepeating(&AmbientModeHandler::HandleRequestAlbums, base::Unretained(this))); web_ui()->RegisterMessageCallback( - "requestPhotosContainers", - base::BindRepeating(&AmbientModeHandler::RequestPhotosContainers, + "setSelectedTemperatureUnit", + base::BindRepeating(&AmbientModeHandler::HandleSetSelectedTemperatureUnit, base::Unretained(this))); web_ui()->RegisterMessageCallback( - "setSelectedPhotosContainers", - base::BindRepeating( - &AmbientModeHandler::HandleSetSelectedPhotosContainers, - base::Unretained(this))); -} - -void AmbientModeHandler::OnJavascriptAllowed() { - GetSettings(); - - // Prefetch albums. - FetchPersonalAlbums(); + "setSelectedAlbums", + base::BindRepeating(&AmbientModeHandler::HandleSetSelectedAlbums, + base::Unretained(this))); } void AmbientModeHandler::OnJavascriptDisallowed() { - weak_factory_.InvalidateWeakPtrs(); + backend_weak_factory_.InvalidateWeakPtrs(); + ui_update_weak_factory_.InvalidateWeakPtrs(); } -void AmbientModeHandler::HandleInitialized(const base::ListValue* args) { +void AmbientModeHandler::HandleRequestSettings(const base::ListValue* args) { CHECK(args); CHECK(args->empty()); - init_from_ambient_mode_page_ = true; AllowJavascript(); + + // Settings subpages may have changed from ambientMode/photos to ambientMode + // since the last time requesting the data. Abort any request in progress to + // avoid unnecessary updating invisible subpage. + ui_update_weak_factory_.InvalidateWeakPtrs(); + RequestSettingsAndAlbums( + base::BindOnce(&AmbientModeHandler::OnSettingsAndAlbumsFetched, + ui_update_weak_factory_.GetWeakPtr(), + /*topic_source=*/base::nullopt)); } -void AmbientModeHandler::RequestPhotosContainers(const base::ListValue* args) { - // TODO(b/159747583): Handle deep linking to ambientMode/photos page. - // For now it will not load the page contents if visited directly. - if (!init_from_ambient_mode_page_) - return; +void AmbientModeHandler::HandleRequestAlbums(const base::ListValue* args) { + CHECK(args); + CHECK_EQ(args->GetSize(), 1U); - ash::AmbientModeTopicSource topic_source = ExtractTopicSource(args); - DCHECK_EQ(topic_source, settings_->topic_source); + AllowJavascript(); - if (topic_source == ash::AmbientModeTopicSource::kGooglePhotos) { - FetchPersonalAlbums(); - } - SendPhotosContainers(); + // ambientMode/photos subpages may have changed, e.g. from displaying Google + // Photos to Art gallery, since the last time requesting the data. + // Abort any request in progress to avoid updating incorrect contents. + ui_update_weak_factory_.InvalidateWeakPtrs(); + RequestSettingsAndAlbums(base::BindOnce( + &AmbientModeHandler::OnSettingsAndAlbumsFetched, + ui_update_weak_factory_.GetWeakPtr(), ExtractTopicSource(args))); } -void AmbientModeHandler::HandleSetSelectedTopicSource( +void AmbientModeHandler::HandleSetSelectedTemperatureUnit( const base::ListValue* args) { - ash::AmbientModeTopicSource topic_source = ExtractTopicSource(args); - settings_->topic_source = topic_source; + DCHECK(settings_); + CHECK_EQ(1U, args->GetSize()); + + settings_->temperature_unit = ExtractTemperatureUnit(args); UpdateSettings(); } -void AmbientModeHandler::HandleSetSelectedPhotosContainers( - const base::ListValue* args) { - switch (settings_->topic_source) { +void AmbientModeHandler::HandleSetSelectedAlbums(const base::ListValue* args) { + const base::DictionaryValue* dictionary = nullptr; + CHECK(!args->GetList().empty()); + args->GetList()[0].GetAsDictionary(&dictionary); + CHECK(dictionary); + + const base::Value* topic_source_value = dictionary->FindKey("topicSource"); + CHECK(topic_source_value); + ash::AmbientModeTopicSource topic_source = + ExtractTopicSource(*topic_source_value); + const base::Value* albums = dictionary->FindKey("albums"); + CHECK(albums); + switch (topic_source) { case ash::AmbientModeTopicSource::kGooglePhotos: // For Google Photos, we will populate the |selected_album_ids| with IDs // of selected albums. settings_->selected_album_ids.clear(); - for (const auto& value : args->GetList()) { - std::string name = value.GetString(); - auto it = std::find_if( - personal_albums_.albums.begin(), personal_albums_.albums.end(), - [name](const auto& album) { return album.album_name == name; }); - CHECK(it != personal_albums_.albums.end()); - settings_->selected_album_ids.emplace_back(it->album_id); + for (const auto& album : albums->GetList()) { + const base::Value* album_id = album.FindKey("albumId"); + const std::string& id = album_id->GetString(); + ash::PersonalAlbum* personal_album = FindPersonalAlbumById(id); + DCHECK(personal_album); + settings_->selected_album_ids.emplace_back(personal_album->album_id); } + + // Update topic source based on selections. + if (settings_->selected_album_ids.empty()) + settings_->topic_source = ash::AmbientModeTopicSource::kArtGallery; + else + settings_->topic_source = ash::AmbientModeTopicSource::kGooglePhotos; break; case ash::AmbientModeTopicSource::kArtGallery: // For Art gallery, we set the corresponding setting to be enabled or not // based on the selections. for (auto& art_setting : settings_->art_settings) { - std::string title = art_setting.title; + const std::string& album_id = art_setting.album_id; auto it = std::find_if( - args->GetList().begin(), args->GetList().end(), - [title](const auto& value) { return value.GetString() == title; }); - const bool checked = it != args->GetList().end(); + albums->GetList().begin(), albums->GetList().end(), + [&album_id](const auto& album) { + return album.FindKey("albumId")->GetString() == album_id; + }); + const bool checked = it != albums->GetList().end(); art_setting.enabled = checked; } break; } UpdateSettings(); + // TODO(wutao): Undate the UI when success in OnUpdateSettings. + SendTopicSource(); } -void AmbientModeHandler::GetSettings() { - ash::AmbientBackendController::Get()->GetSettings(base::BindOnce( - &AmbientModeHandler::OnGetSettings, weak_factory_.GetWeakPtr())); -} - -void AmbientModeHandler::OnGetSettings( - const base::Optional<ash::AmbientSettings>& settings) { - if (!settings) { - // TODO(b/152921891): Retry a small fixed number of times, then only retry - // when user confirms in the error message dialog. - return; - } - - settings_ = settings; - SendTopicSource(); +void AmbientModeHandler::SendTemperatureUnit() { + DCHECK(settings_); + FireWebUIListener( + "temperature-unit-changed", + base::Value(TemperatureUnitToString(settings_->temperature_unit))); } void AmbientModeHandler::SendTopicSource() { DCHECK(settings_); + base::Value topic_source(base::Value::Type::DICTIONARY); + topic_source.SetKey("hasGooglePhotosAlbums", + base::Value(!personal_albums_.albums.empty())); + topic_source.SetKey("topicSource", + base::Value(static_cast<int>(settings_->topic_source))); FireWebUIListener("topic-source-changed", - base::Value(static_cast<int>(settings_->topic_source))); + base::Value(std::move(topic_source))); } -void AmbientModeHandler::SendPhotosContainers() { +void AmbientModeHandler::SendAlbums(ash::AmbientModeTopicSource topic_source) { DCHECK(settings_); base::Value dictionary(base::Value::Type::DICTIONARY); - base::Value containers(base::Value::Type::LIST); - switch (settings_->topic_source) { + base::Value albums(base::Value::Type::LIST); + switch (topic_source) { case ash::AmbientModeTopicSource::kGooglePhotos: for (const auto& album : personal_albums_.albums) { base::Value value(base::Value::Type::DICTIONARY); + value.SetKey("albumId", base::Value(album.album_id)); + value.SetKey("checked", base::Value(album.selected)); + value.SetKey("description", base::Value(GetAlbumDescription(album))); value.SetKey("title", base::Value(album.album_name)); - value.SetKey("checked", - base::Value(base::Contains(settings_->selected_album_ids, - album.album_id))); - containers.Append(std::move(value)); + value.SetKey("url", base::Value(album.png_data_url)); + albums.Append(std::move(value)); } break; case ash::AmbientModeTopicSource::kArtGallery: for (const auto& setting : settings_->art_settings) { base::Value value(base::Value::Type::DICTIONARY); - value.SetKey("title", base::Value(setting.title)); + value.SetKey("albumId", base::Value(setting.album_id)); value.SetKey("checked", base::Value(setting.enabled)); - containers.Append(std::move(value)); + value.SetKey("description", base::Value(setting.description)); + value.SetKey("title", base::Value(setting.title)); + value.SetKey("url", base::Value(setting.png_data_url)); + albums.Append(std::move(value)); } break; } - dictionary.SetKey("topicSource", + dictionary.SetKey("topicSource", base::Value(static_cast<int>(topic_source))); + dictionary.SetKey("selectedTopicSource", base::Value(static_cast<int>(settings_->topic_source))); - dictionary.SetKey("topicContainers", std::move(containers)); - FireWebUIListener("photos-containers-changed", std::move(dictionary)); + dictionary.SetKey("albums", std::move(albums)); + FireWebUIListener("albums-changed", std::move(dictionary)); +} + +void AmbientModeHandler::SendAlbumPreview( + ash::AmbientModeTopicSource topic_source, + const std::string& album_id, + std::string&& png_data_url) { + base::Value album(base::Value::Type::DICTIONARY); + album.SetKey("albumId", base::Value(album_id)); + album.SetKey("topicSource", base::Value(static_cast<int>(topic_source))); + album.SetKey("url", base::Value(png_data_url)); + FireWebUIListener("album-preview-changed", std::move(album)); } void AmbientModeHandler::UpdateSettings() { DCHECK(settings_); ash::AmbientBackendController::Get()->UpdateSettings( *settings_, base::BindOnce(&AmbientModeHandler::OnUpdateSettings, - weak_factory_.GetWeakPtr())); + backend_weak_factory_.GetWeakPtr())); } void AmbientModeHandler::OnUpdateSettings(bool success) { @@ -203,30 +312,164 @@ void AmbientModeHandler::OnUpdateSettings(bool success) { // when user confirms in the error message dialog. } -void AmbientModeHandler::FetchPersonalAlbums() { - // TODO: Add a helper function to get all the albums. - ash::AmbientBackendController::Get()->FetchPersonalAlbums( - kBannerWidth, kBannderHeight, /*num_albums=*/100, /*resume_token=*/"", - base::BindOnce(&AmbientModeHandler::OnPersonalAlbumsFetched, - weak_factory_.GetWeakPtr())); +void AmbientModeHandler::RequestSettingsAndAlbums( + ash::AmbientBackendController::OnSettingsAndAlbumsFetchedCallback + callback) { + // TODO(b/161044021): Add a helper function to get all the albums. Currently + // only load 100 latest modified albums. + ash::AmbientBackendController::Get()->FetchSettingsAndAlbums( + kBannerWidthPx, kBannerHeightPx, /*num_albums=*/100, std::move(callback)); } -void AmbientModeHandler::OnPersonalAlbumsFetched( +void AmbientModeHandler::OnSettingsAndAlbumsFetched( + base::Optional<ash::AmbientModeTopicSource> topic_source, + const base::Optional<ash::AmbientSettings>& settings, ash::PersonalAlbums personal_albums) { + // TODO(b/152921891): Retry a small fixed number of times, then only retry + // when user confirms in the error message dialog. + if (!settings) + return; + + settings_ = settings; personal_albums_ = std::move(personal_albums); + SyncSettingsAndAlbums(); + + if (!topic_source) { + SendTopicSource(); + SendTemperatureUnit(); + return; + } + + if (chromeos::features::IsAmbientModePhotoPreviewEnabled()) + DownloadAlbumPreviewImage(*topic_source); + + UpdateTopicSource(*topic_source); + SendAlbums(*topic_source); +} + +void AmbientModeHandler::SyncSettingsAndAlbums() { + auto it = settings_->selected_album_ids.begin(); + while (it != settings_->selected_album_ids.end()) { + const std::string& album_id = *it; + ash::PersonalAlbum* album = FindPersonalAlbumById(album_id); + if (album) { + album->selected = true; + ++it; + } else { + // The selected album does not exist any more. + it = settings_->selected_album_ids.erase(it); + } + } - // If the |topic_source| is not |kGooglePhotos|, no need to refresh the - // photos subpage. - // |settings_| could be null because we call GetSettings() and - // FetchPersonalAlbums() in OnJavascriptAllowed(). |settings_| is populated by - // OnGetSettings(), which could be called later. The purpose to call - // FetchPersonalAlbums() is to prefetch albums, which takes several seconds, - // This improves the experience when we click into the ambientMode/photos page - // to show the albums list faster. - if (settings_ && - settings_->topic_source == ash::AmbientModeTopicSource::kGooglePhotos) { - SendPhotosContainers(); + if (settings_->selected_album_ids.empty()) + MaybeUpdateTopicSource(ash::AmbientModeTopicSource::kArtGallery); +} + +void AmbientModeHandler::UpdateTopicSource( + ash::AmbientModeTopicSource topic_source) { + // If this is an Art gallery album page, will select art gallery topic source. + if (topic_source == ash::AmbientModeTopicSource::kArtGallery) { + MaybeUpdateTopicSource(topic_source); + return; } + + // If this is a Google Photos album page, will + // 1. Select art gallery topic source if no albums or no album is selected. + if (settings_->selected_album_ids.empty()) { + MaybeUpdateTopicSource(ash::AmbientModeTopicSource::kArtGallery); + return; + } + + // 2. Select Google Photos topic source if at least one album is selected. + MaybeUpdateTopicSource(ash::AmbientModeTopicSource::kGooglePhotos); +} + +void AmbientModeHandler::MaybeUpdateTopicSource( + ash::AmbientModeTopicSource topic_source) { + // If the setting is the same, no need to update. + if (settings_->topic_source == topic_source) + return; + + settings_->topic_source = topic_source; + UpdateSettings(); + // TODO(wutao): Undate the UI when success in OnUpdateSettings. + SendTopicSource(); +} + +void AmbientModeHandler::DownloadAlbumPreviewImage( + ash::AmbientModeTopicSource topic_source) { + switch (topic_source) { + case ash::AmbientModeTopicSource::kGooglePhotos: + // TODO(b/163413738): Slow down the downloading when there are too many + // albums. + for (const auto& album : personal_albums_.albums) { + ash::ImageDownloader::Get()->Download( + GURL(album.banner_image_url), NO_TRAFFIC_ANNOTATION_YET, + base::BindOnce(&AmbientModeHandler::OnAlbumPreviewImageDownloaded, + backend_weak_factory_.GetWeakPtr(), topic_source, + album.album_id)); + } + break; + case ash::AmbientModeTopicSource::kArtGallery: + for (const auto& album : settings_->art_settings) { + ash::ImageDownloader::Get()->Download( + GURL(album.preview_image_url), NO_TRAFFIC_ANNOTATION_YET, + base::BindOnce(&AmbientModeHandler::OnAlbumPreviewImageDownloaded, + backend_weak_factory_.GetWeakPtr(), topic_source, + album.album_id)); + } + break; + } +} + +void AmbientModeHandler::OnAlbumPreviewImageDownloaded( + ash::AmbientModeTopicSource topic_source, + const std::string& album_id, + const gfx::ImageSkia& image) { + switch (topic_source) { + case ash::AmbientModeTopicSource::kGooglePhotos: + // Album does not exist any more. + if (!FindPersonalAlbumById(album_id)) + return; + break; + case ash::AmbientModeTopicSource::kArtGallery: + if (!FindArtAlbumById(album_id)) + return; + break; + } + + std::vector<unsigned char> encoded_image_bytes; + EncodeImage(image, &encoded_image_bytes); + if (encoded_image_bytes.empty()) + return; + + SendAlbumPreview(topic_source, album_id, + webui::GetPngDataUrl(&encoded_image_bytes.front(), + encoded_image_bytes.size())); +} + +ash::PersonalAlbum* AmbientModeHandler::FindPersonalAlbumById( + const std::string& album_id) { + auto it = std::find_if( + personal_albums_.albums.begin(), personal_albums_.albums.end(), + [&album_id](const auto& album) { return album.album_id == album_id; }); + + if (it == personal_albums_.albums.end()) + return nullptr; + + return &(*it); +} + +ash::ArtSetting* AmbientModeHandler::FindArtAlbumById( + const std::string& album_id) { + auto it = std::find_if( + settings_->art_settings.begin(), settings_->art_settings.end(), + [&album_id](const auto& album) { return album.album_id == album_id; }); + // Album does not exist any more. + if (it == settings_->art_settings.end()) + return nullptr; + + return &(*it); } } // namespace settings diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.h index ac0c6441433..78232435062 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.h +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.h @@ -8,6 +8,7 @@ #include <vector> #include "ash/public/cpp/ambient/ambient_backend_controller.h" +#include "base/callback_forward.h" #include "base/memory/weak_ptr.h" #include "base/optional.h" #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" @@ -20,6 +21,10 @@ namespace base { class ListValue; } // namespace base +namespace gfx { +class ImageSkia; +} // namespace gfx + namespace chromeos { namespace settings { @@ -34,36 +39,40 @@ class AmbientModeHandler : public ::settings::SettingsPageUIHandler { // settings::SettingsPageUIHandler: void RegisterMessages() override; - void OnJavascriptAllowed() override; + void OnJavascriptAllowed() override {} void OnJavascriptDisallowed() override; private: - // WebUI call to signal js side is ready. - void HandleInitialized(const base::ListValue* args); + friend class AmbientModeHandlerTest; - // WebUI call to request photos containers, e.g. personal albums or art - // categories. - void RequestPhotosContainers(const base::ListValue* args); + // WebUI call to request topic source and temperature unit related data. + void HandleRequestSettings(const base::ListValue* args); - // WebUI call to sync topic source with server. - void HandleSetSelectedTopicSource(const base::ListValue* args); + // WebUI call to request albums related data. + void HandleRequestAlbums(const base::ListValue* args); - // WebUI call to sync photos containers with server. - void HandleSetSelectedPhotosContainers(const base::ListValue* args); + // WebUI call to sync temperature unit with server. + void HandleSetSelectedTemperatureUnit(const base::ListValue* args); - // Retrieve the initial settings from server. - void GetSettings(); + // WebUI call to sync albums with server. + void HandleSetSelectedAlbums(const base::ListValue* args); - // Called when the initial settings is retrieved. - void OnGetSettings(const base::Optional<ash::AmbientSettings>& settings); + // Send the "temperature-unit-changed" WebUIListener event to update the + // WebUI. + void SendTemperatureUnit(); - // Send the "topic-source-changed" WebUIListener event when the initial - // settings is retrieved. + // Send the "topic-source-changed" WebUIListener event to update the WebUI. void SendTopicSource(); - // Send the "photos-containers-changed" WebUIListener event when the personal - // albums are retrieved. - void SendPhotosContainers(); + // Send the "albums-changed" WebUIListener event with albums info + // in the |topic_source|. + void SendAlbums(ash::AmbientModeTopicSource topic_source); + + // Send the "album-preview-changed" WebUIListener event with album preview + // in the |topic_source|. + void SendAlbumPreview(ash::AmbientModeTopicSource topic_source, + const std::string& album_id, + std::string&& png_data_url); // Update the local |settings_| to server. void UpdateSettings(); @@ -71,18 +80,43 @@ class AmbientModeHandler : public ::settings::SettingsPageUIHandler { // Called when the settings is updated. void OnUpdateSettings(bool success); - void FetchPersonalAlbums(); + void RequestSettingsAndAlbums( + ash::AmbientBackendController::OnSettingsAndAlbumsFetchedCallback + callback); + + // |topic_source| is what the |settings_| and |personal_albums_| were + // requested for the ambientMode/photos subpage. It is base::nullopt if they + // were requested by the ambientMode subpage. + void OnSettingsAndAlbumsFetched( + base::Optional<ash::AmbientModeTopicSource> topic_source, + const base::Optional<ash::AmbientSettings>& settings, + ash::PersonalAlbums personal_albums); + + // The |settings_| could be stale when the albums in Google Photos changes. + // Prune the |selected_album_id| which does not exist any more. + // Populate albums with selected info which will be shown on Settings UI. + void SyncSettingsAndAlbums(); + + // Update topic source if needed. + void UpdateTopicSource(ash::AmbientModeTopicSource topic_source); + void MaybeUpdateTopicSource(ash::AmbientModeTopicSource topic_source); + + void DownloadAlbumPreviewImage(ash::AmbientModeTopicSource topic_source); + + void OnAlbumPreviewImageDownloaded(ash::AmbientModeTopicSource topic_source, + const std::string& album_id, + const gfx::ImageSkia& image); - void OnPersonalAlbumsFetched(ash::PersonalAlbums personal_albums); + ash::PersonalAlbum* FindPersonalAlbumById(const std::string& album_id); - // Whether the Javascript is inited from the ambientMode page. - bool init_from_ambient_mode_page_ = false; + ash::ArtSetting* FindArtAlbumById(const std::string& album_id); base::Optional<ash::AmbientSettings> settings_; ash::PersonalAlbums personal_albums_; - base::WeakPtrFactory<AmbientModeHandler> weak_factory_{this}; + base::WeakPtrFactory<AmbientModeHandler> backend_weak_factory_{this}; + base::WeakPtrFactory<AmbientModeHandler> ui_update_weak_factory_{this}; }; } // namespace settings diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler_unittest.cc new file mode 100644 index 00000000000..cf0ea9e11c9 --- /dev/null +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler_unittest.cc @@ -0,0 +1,199 @@ +// 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 <memory> + +#include "ash/public/cpp/ambient/common/ambient_settings.h" +#include "ash/public/cpp/ambient/fake_ambient_backend_controller_impl.h" +#include "ash/public/cpp/test/test_image_downloader.h" +#include "chrome/test/base/browser_with_test_window_test.h" +#include "content/public/test/test_web_ui.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromeos { + +namespace settings { + +namespace { + +const char kWebCallbackFunctionName[] = "cr.webUIListenerCallback"; + +class TestAmbientModeHandler : public AmbientModeHandler { + public: + TestAmbientModeHandler() = default; + ~TestAmbientModeHandler() override = default; + + // Make public for testing. + using AmbientModeHandler::AllowJavascript; + using AmbientModeHandler::RegisterMessages; + using AmbientModeHandler::set_web_ui; +}; + +} // namespace + +class AmbientModeHandlerTest : public testing::Test { + public: + AmbientModeHandlerTest() = default; + ~AmbientModeHandlerTest() override = default; + + void SetUp() override { + web_ui_ = std::make_unique<content::TestWebUI>(); + handler_ = std::make_unique<TestAmbientModeHandler>(); + handler_->set_web_ui(web_ui_.get()); + handler_->RegisterMessages(); + handler_->AllowJavascript(); + fake_backend_controller_ = + std::make_unique<ash::FakeAmbientBackendControllerImpl>(); + image_downloader_ = std::make_unique<ash::TestImageDownloader>(); + } + + void RequestSettings() { + base::ListValue args; + handler_->HandleRequestSettings(&args); + } + + void RequestAlbums(ash::AmbientModeTopicSource topic_source) { + base::ListValue args; + args.Append(static_cast<int>(topic_source)); + handler_->HandleRequestAlbums(&args); + } + + std::string BoolToString(bool x) { return x ? "true" : "false"; } + + void VerifySettingsSent(base::RunLoop* run_loop) { + EXPECT_EQ(2U, web_ui_->call_data().size()); + + // The call is structured such that the function name is the "web callback" + // name and the first argument is the name of the message being sent. + const auto& topic_source_call_data = *web_ui_->call_data().front(); + const auto& temperature_unit_call_data = *web_ui_->call_data().back(); + + // Topic Source + EXPECT_EQ(kWebCallbackFunctionName, topic_source_call_data.function_name()); + EXPECT_EQ("topic-source-changed", + topic_source_call_data.arg1()->GetString()); + // In FakeAmbientBackendControllerImpl, the |topic_source| is + // kGooglePhotos. + const base::DictionaryValue* dictionary = nullptr; + topic_source_call_data.arg2()->GetAsDictionary(&dictionary); + const base::Value* topic_source_value = dictionary->FindKey("topicSource"); + EXPECT_EQ(0, topic_source_value->GetInt()); + + // Temperature Unit + EXPECT_EQ(kWebCallbackFunctionName, + temperature_unit_call_data.function_name()); + EXPECT_EQ("temperature-unit-changed", + temperature_unit_call_data.arg1()->GetString()); + // In FakeAmbientBackendControllerImpl, the |temperature_unit| is kCelsius. + EXPECT_EQ("celsius", temperature_unit_call_data.arg2()->GetString()); + + run_loop->Quit(); + } + + void VerifyAlbumsSent(ash::AmbientModeTopicSource topic_source, + base::RunLoop* run_loop) { + // Art gallery has an extra call to update the topic source to Art gallery. + std::vector<std::unique_ptr<content::TestWebUI::CallData>>::size_type call_size = + topic_source == ash::AmbientModeTopicSource::kGooglePhotos ? 1U : 2U; + EXPECT_EQ(call_size, web_ui_->call_data().size()); + + if (topic_source == ash::AmbientModeTopicSource::kArtGallery) { + const auto& topic_source_call_data = *web_ui_->call_data().front(); + const base::DictionaryValue* dictionary = nullptr; + topic_source_call_data.arg2()->GetAsDictionary(&dictionary); + const base::Value* topic_source_value = + dictionary->FindKey("topicSource"); + EXPECT_EQ(static_cast<int>(topic_source), topic_source_value->GetInt()); + } + + const content::TestWebUI::CallData& call_data = + *web_ui_->call_data().back(); + + // The call is structured such that the function name is the "web callback" + // name and the first argument is the name of the message being sent. + EXPECT_EQ(kWebCallbackFunctionName, call_data.function_name()); + EXPECT_EQ("albums-changed", call_data.arg1()->GetString()); + + // The test data is set in FakeAmbientBackendControllerImpl. + const base::DictionaryValue* dictionary = nullptr; + call_data.arg2()->GetAsDictionary(&dictionary); + + const base::Value* topic_source_value = dictionary->FindKey("topicSource"); + EXPECT_EQ(static_cast<int>(topic_source), topic_source_value->GetInt()); + + const base::Value* albums = dictionary->FindKey("albums"); + EXPECT_EQ(2U, albums->GetList().size()); + + const base::DictionaryValue* album0; + albums->GetList()[0].GetAsDictionary(&album0); + EXPECT_EQ("0", album0->FindKey("albumId")->GetString()); + + const base::DictionaryValue* album1; + albums->GetList()[1].GetAsDictionary(&album1); + EXPECT_EQ("1", album1->FindKey("albumId")->GetString()); + + if (topic_source == ash::AmbientModeTopicSource::kGooglePhotos) { + EXPECT_EQ(false, album0->FindKey("checked")->GetBool()); + EXPECT_EQ("album0", album0->FindKey("title")->GetString()); + + EXPECT_EQ(true, album1->FindKey("checked")->GetBool()); + EXPECT_EQ("album1", album1->FindKey("title")->GetString()); + } else { + EXPECT_EQ(true, album0->FindKey("checked")->GetBool()); + EXPECT_EQ("art0", album0->FindKey("title")->GetString()); + + EXPECT_EQ(false, album1->FindKey("checked")->GetBool()); + EXPECT_EQ("art1", album1->FindKey("title")->GetString()); + } + run_loop->Quit(); + } + + private: + base::test::TaskEnvironment task_environment_; + std::unique_ptr<content::TestWebUI> web_ui_; + std::unique_ptr<ash::AmbientBackendController> fake_backend_controller_; + std::unique_ptr<ash::TestImageDownloader> image_downloader_; + std::unique_ptr<TestAmbientModeHandler> handler_; +}; + +TEST_F(AmbientModeHandlerTest, TestSendTemperatureUnitAndTopicSource) { + RequestSettings(); + + base::RunLoop run_loop; + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(&AmbientModeHandlerTest::VerifySettingsSent, + base::Unretained(this), &run_loop)); + run_loop.Run(); +} + +TEST_F(AmbientModeHandlerTest, TestSendAlbumsForGooglePhotos) { + ash::AmbientModeTopicSource topic_source = + ash::AmbientModeTopicSource::kGooglePhotos; + RequestAlbums(topic_source); + + base::RunLoop run_loop; + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(&AmbientModeHandlerTest::VerifyAlbumsSent, + base::Unretained(this), topic_source, &run_loop)); + run_loop.Run(); +} + +TEST_F(AmbientModeHandlerTest, TestSendAlbumsForArtGallery) { + ash::AmbientModeTopicSource topic_source = + ash::AmbientModeTopicSource::kArtGallery; + RequestAlbums(topic_source); + + base::RunLoop run_loop; + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(&AmbientModeHandlerTest::VerifyAlbumsSent, + base::Unretained(this), topic_source, &run_loop)); + run_loop.Run(); +} + +} // namespace settings +} // namespace chromeos diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.h index db3d37534d2..f6b0242c4a2 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.h +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.h @@ -12,6 +12,7 @@ #include "base/memory/weak_ptr.h" #include "base/scoped_observer.h" #include "chrome/browser/chromeos/arc/session/arc_session_manager.h" +#include "chrome/browser/chromeos/arc/session/arc_session_manager_observer.h" #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" @@ -26,7 +27,7 @@ namespace settings { class AndroidAppsHandler : public ::settings::SettingsPageUIHandler, public ArcAppListPrefs::Observer, - public arc::ArcSessionManager::Observer { + public arc::ArcSessionManagerObserver { public: explicit AndroidAppsHandler(Profile* profile); ~AndroidAppsHandler() override; @@ -43,7 +44,7 @@ class AndroidAppsHandler : public ::settings::SettingsPageUIHandler, const ArcAppListPrefs::AppInfo& app_info) override; void OnAppRemoved(const std::string& app_id) override; - // arc::ArcSessionManager::Observer: + // arc::ArcSessionManagerObserver: void OnArcPlayStoreEnabledChanged(bool enabled) override; private: @@ -57,7 +58,7 @@ class AndroidAppsHandler : public ::settings::SettingsPageUIHandler, ScopedObserver<ArcAppListPrefs, ArcAppListPrefs::Observer> arc_prefs_observer_; - ScopedObserver<arc::ArcSessionManager, arc::ArcSessionManager::Observer> + ScopedObserver<arc::ArcSessionManager, arc::ArcSessionManagerObserver> arc_session_manager_observer_; Profile* profile_; // unowned base::WeakPtrFactory<AndroidAppsHandler> weak_ptr_factory_{this}; diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/apps_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/apps_section.cc index 6d8ebbc5421..ef09fb75b2e 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/apps_section.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/apps_section.cc @@ -6,6 +6,7 @@ #include "base/feature_list.h" #include "base/no_destructor.h" +#include "base/strings/utf_string_conversions.h" #include "chrome/browser/chromeos/arc/arc_util.h" #include "chrome/browser/chromeos/plugin_vm/plugin_vm_pref_names.h" #include "chrome/browser/chromeos/plugin_vm/plugin_vm_util.h" @@ -75,7 +76,9 @@ const std::vector<SearchConcept>& GetAndroidSettingsSearchConcepts() { mojom::SearchResultIcon::kGooglePlay, mojom::SearchResultDefaultRank::kMedium, mojom::SearchResultType::kSetting, - {.setting = mojom::Setting::kManageAndroidPreferences}}, + {.setting = mojom::Setting::kManageAndroidPreferences}, + {IDS_OS_SETTINGS_TAG_ANDROID_SETTINGS_WITH_PLAY_STORE_ALT1, + SearchConcept::kAltTagEnd}}, }); return *tags; } @@ -87,7 +90,8 @@ const std::vector<SearchConcept>& GetAndroidNoPlayStoreSearchConcepts() { mojom::SearchResultIcon::kAndroid, mojom::SearchResultDefaultRank::kMedium, mojom::SearchResultType::kSetting, - {.setting = mojom::Setting::kManageAndroidPreferences}}, + {.setting = mojom::Setting::kManageAndroidPreferences}, + {IDS_OS_SETTINGS_TAG_ANDROID_SETTINGS_ALT1, SearchConcept::kAltTagEnd}}, }); return *tags; } @@ -325,6 +329,11 @@ void AppsSection::AddPluginVmLoadTimeData( html_source->AddBoolean("showPluginVm", ShowPluginVm(profile(), *pref_service_)); + html_source->AddString( + "pluginVmSharedPathsInstructionsLocate", + l10n_util::GetStringFUTF16( + IDS_SETTINGS_APPS_PLUGIN_VM_SHARED_PATHS_INSTRUCTIONS_LOCATE, + base::UTF8ToUTF16(plugin_vm::kChromeOSBaseDirectoryDisplayText))); html_source->AddBoolean( "showPluginVmCameraPermissions", base::FeatureList::IsEnabled( diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.cc index 5fd2a36e803..7c8d870bb91 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.cc @@ -17,7 +17,6 @@ #include "chrome/browser/profiles/profile.h" #include "chromeos/cryptohome/cryptohome_util.h" #include "chromeos/dbus/cryptohome/cryptohome_client.h" -#include "chromeos/dbus/dlcservice/dlcservice_client.h" #include "components/arc/arc_service_manager.h" #include "components/arc/session/arc_bridge_service.h" #include "components/arc/storage_manager/arc_storage_manager.h" @@ -393,32 +392,6 @@ void OtherUsersSizeCalculator::OnGetOtherUserSize( NotifySizeCalculated(other_users_total_bytes); } -DlcsSizeCalculator::DlcsSizeCalculator() - : SizeCalculator(CalculationType::kDlcs) {} - -DlcsSizeCalculator::~DlcsSizeCalculator() = default; - -void DlcsSizeCalculator::PerformCalculation() { - DlcserviceClient::Get()->GetExistingDlcs(base::BindOnce( - &DlcsSizeCalculator::OnGetExistingDlcs, weak_ptr_factory_.GetWeakPtr())); -} - -void DlcsSizeCalculator::OnGetExistingDlcs( - const std::string& err, - const dlcservice::DlcsWithContent& dlcs_with_content) { - if (err != dlcservice::kErrorNone) { - NotifySizeCalculated(0); - return; - } - base::ListValue dlc_metadata_list; - int64_t dlc_total_size_in_bytes = 0; - for (int i = 0; i < dlcs_with_content.dlc_infos_size(); i++) { - const auto& dlc_info = dlcs_with_content.dlc_infos(i); - dlc_total_size_in_bytes += dlc_info.used_bytes_on_disk(); - } - NotifySizeCalculated(dlc_total_size_in_bytes); -} - } // namespace calculator } // namespace settings } // namespace chromeos diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.h b/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.h index 23fc718f6f6..8f483f50b95 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.h +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator.h @@ -25,10 +25,6 @@ class Profile; -namespace dlcservice { -class DlcsWithContent; -} // namespace dlcservice - namespace chromeos { namespace settings { namespace calculator { @@ -46,8 +42,7 @@ class SizeCalculator { kAppsExtensions, kCrostini, kOtherUsers, - kDlcs, - kLast = kDlcs, + kLast = kOtherUsers, kSystem, }; @@ -294,27 +289,6 @@ class OtherUsersSizeCalculator : public SizeCalculator { base::WeakPtrFactory<OtherUsersSizeCalculator> weak_ptr_factory_{this}; }; -// Class handling the calculation of all DLC size. -class DlcsSizeCalculator : public SizeCalculator { - public: - DlcsSizeCalculator(); - ~DlcsSizeCalculator() override; - - DlcsSizeCalculator(const DlcsSizeCalculator&) = delete; - DlcsSizeCalculator& operator=(const DlcsSizeCalculator&) = delete; - - private: - friend class DlcsSizeTestAPI; - - void PerformCalculation() override; - - // Callback to update the total size of existing DLCs. - void OnGetExistingDlcs(const std::string& err, - const dlcservice::DlcsWithContent& dlcs_with_content); - - base::WeakPtrFactory<DlcsSizeCalculator> weak_ptr_factory_{this}; -}; - } // namespace calculator } // namespace settings } // namespace chromeos diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator_test_api.h b/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator_test_api.h index 4a15d946c26..2e0850df244 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator_test_api.h +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/calculator/size_calculator_test_api.h @@ -149,25 +149,6 @@ class OtherUsersSizeTestAPI { OtherUsersSizeCalculator* other_users_size_calculator_; }; -class DlcsSizeTestAPI { - public: - explicit DlcsSizeTestAPI(StorageHandler* handler, - DlcsSizeCalculator* dlcs_size_calculator) { - dlcs_size_calculator_ = dlcs_size_calculator; - dlcs_size_calculator_->AddObserver(handler); - } - - void StartCalculation() { dlcs_size_calculator_->StartCalculation(); } - - void SimulateOnGetExistingDlcs( - const std::string& err, - const dlcservice::DlcsWithContent& dlcs_with_content) { - dlcs_size_calculator_->OnGetExistingDlcs(err, dlcs_with_content); - } - - private: - DlcsSizeCalculator* dlcs_size_calculator_; -}; } // namespace calculator } // namespace settings } // namespace chromeos diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc index 4bd641f16e6..075ce796d0d 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 @@ -184,7 +184,7 @@ void ChangePictureHandler::HandlePhotoTaken(const base::ListValue* args) { base::StringPiece url(image_url); const char kDataUrlPrefix[] = "data:image/png;base64,"; const size_t kDataUrlPrefixLength = base::size(kDataUrlPrefix) - 1; - if (!url.starts_with(kDataUrlPrefix) || + if (!base::StartsWith(url, kDataUrlPrefix) || !base::Base64Decode(url.substr(kDataUrlPrefixLength), &raw_data)) { LOG(WARNING) << "Invalid image URL"; return; @@ -323,9 +323,6 @@ void ChangePictureHandler::HandleSelectImage(const base::ListValue* args) { } user_image_manager->SaveUserImage(std::move(user_image)); - UMA_HISTOGRAM_EXACT_LINEAR("UserImage.ChangeChoice", - default_user_image::kHistogramImageOld, - default_user_image::kHistogramImagesCount); VLOG(1) << "Selected old user image"; } else if (image_type == "default") { int image_index = user_manager::User::USER_IMAGE_INVALID; @@ -333,10 +330,6 @@ void ChangePictureHandler::HandleSelectImage(const base::ListValue* args) { // One of the default user images. user_image_manager->SaveUserDefaultImageIndex(image_index); - UMA_HISTOGRAM_EXACT_LINEAR( - "UserImage.ChangeChoice", - default_user_image::GetDefaultImageHistogramValue(image_index), - default_user_image::kHistogramImagesCount); VLOG(1) << "Selected default user image: " << image_index; } else { LOG(WARNING) << "Invalid image_url for default image type: " << image_url; @@ -352,18 +345,6 @@ void ChangePictureHandler::HandleSelectImage(const base::ListValue* args) { } else if (image_type == "profile") { // Profile image selected. Could be previous (old) user image. user_image_manager->SaveUserImageFromProfileImage(); - - if (previous_image_index_ == user_manager::User::USER_IMAGE_PROFILE) { - UMA_HISTOGRAM_EXACT_LINEAR("UserImage.ChangeChoice", - default_user_image::kHistogramImageOld, - default_user_image::kHistogramImagesCount); - VLOG(1) << "Selected old (profile) user image"; - } else { - UMA_HISTOGRAM_EXACT_LINEAR("UserImage.ChangeChoice", - default_user_image::kHistogramImageFromProfile, - default_user_image::kHistogramImagesCount); - VLOG(1) << "Selected profile image"; - } } else { NOTREACHED() << "Unexpected image type: " << image_type; } @@ -384,9 +365,6 @@ void ChangePictureHandler::FileSelected(const base::FilePath& path, ChromeUserManager::Get() ->GetUserImageManager(GetUser()->GetAccountId()) ->SaveUserImageFromFile(path); - UMA_HISTOGRAM_EXACT_LINEAR("UserImage.ChangeChoice", - default_user_image::kHistogramImageFromFile, - default_user_image::kHistogramImagesCount); VLOG(1) << "Selected image from file"; } @@ -400,9 +378,6 @@ void ChangePictureHandler::SetImageFromCamera( ChromeUserManager::Get() ->GetUserImageManager(GetUser()->GetAccountId()) ->SaveUserImage(std::move(user_image)); - UMA_HISTOGRAM_EXACT_LINEAR("UserImage.ChangeChoice", - default_user_image::kHistogramImageFromCamera, - default_user_image::kHistogramImagesCount); VLOG(1) << "Selected camera photo"; } diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom b/chromium/chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom index ecb574c87e6..b66f2ae934b 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom @@ -68,13 +68,16 @@ enum Subpage { kDisplay = 403, kStorage = 404, kExternalStorage = 405, - kDlc = 406, + // Note: Value 406 was for deprecated DLC Subpage - see + // https://crbug.com/1108093. Do not reuse. kPower = 407, // Personalization section. kChangePicture = 500, kAmbientMode = 501, - kAmbientModePhotos= 502, + // Note: Value 502 was for deprecated kAmbientModePhotos. Do not reuse. + kAmbientModeGooglePhotosAlbum = 503, + kAmbientModeArtGalleryAlbum = 504, // Search and Assistant section. kAssistant = 600, @@ -105,6 +108,8 @@ enum Subpage { kManageInputMethods = 1201, kSmartInputs = 1202, kInputMethodOptions = 1203, + kLanguages = 1204, + kInput = 1205, // Files section. kNetworkFileShares = 1300, @@ -165,14 +170,16 @@ const string kStylusSubpagePath = "stylus"; const string kDisplaySubpagePath = "display"; const string kStorageSubpagePath = "storage"; const string kExternalStorageSubpagePath = "storage/externalStoragePreferences"; -const string kDlcSubpagePath = "storage/downloadedContent"; const string kPowerSubpagePath = "power"; // Personalization section. const string kPersonalizationSectionPath = "personalization"; const string kChangePictureSubpagePath = "changePicture"; const string kAmbientModeSubpagePath = "ambientMode"; -const string kAmbientModePhotosSubpagePath = "ambientMode/photos"; +const string kAmbientModeGooglePhotosAlbumSubpagePath = + "ambientMode/photos?topicSource=0"; +const string kAmbientModeArtGalleryAlbumSubpagePath = + "ambientMode/photos?topicSource=1"; // Search and Assistant section. const string kSearchAndAssistantSectionPath = "osSearch"; @@ -208,6 +215,8 @@ const string kLanguagesAndInputDetailsSubpagePath = "osLanguages/details"; const string kManageInputMethodsSubpagePath = "osLanguages/inputMethods"; const string kSmartInputsSubpagePath = "osLanguages/smartInputs"; const string kInputMethodOptionsSubpagePath = "osLanguages/inputMethodOptions"; +const string kLanguagesSubpagePath = "osLanguages/languages"; +const string kInputSubpagePath = "osLanguages/input"; // Files section. const string kFilesSectionPath = "files"; diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/constants/routes_util.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/constants/routes_util.cc index d2fa7499076..c3a88225b57 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/constants/routes_util.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/constants/routes_util.cc @@ -56,7 +56,6 @@ bool IsOSSettingsSubPage(const std::string& sub_page) { chromeos::settings::mojom::kDisplaySubpagePath, chromeos::settings::mojom::kStorageSubpagePath, chromeos::settings::mojom::kExternalStorageSubpagePath, - chromeos::settings::mojom::kDlcSubpagePath, chromeos::settings::mojom::kPowerSubpagePath, // Personalization section. @@ -97,6 +96,8 @@ bool IsOSSettingsSubPage(const std::string& sub_page) { chromeos::settings::mojom::kManageInputMethodsSubpagePath, chromeos::settings::mojom::kSmartInputsSubpagePath, chromeos::settings::mojom::kInputMethodOptionsSubpagePath, + chromeos::settings::mojom::kLanguagesSubpagePath, + chromeos::settings::mojom::kInputSubpagePath, // Files section. chromeos::settings::mojom::kFilesSectionPath, diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom b/chromium/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom index 19339269f3b..d5186c090d1 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom @@ -34,6 +34,7 @@ enum Setting { kDisconnectTetherNetwork = 23, kWifiMetered = 24, kCellularMetered = 25, + kCellularAddNetwork = 26, // Bluetooth section. kBluetoothOnOff = 100, @@ -52,6 +53,10 @@ enum Setting { kMessagesOnOff = 206, kForgetPhone = 207, kNearbyShareOnOff = 208, + kPhoneHubOnOff = 209, + kPhoneHubNotificationsOnOff = 210, + kPhoneHubNotificationBadgeOnOff = 211, + kPhoneHubTaskContinuationOnOff = 212, // People section. kAddAccount = 300, @@ -103,7 +108,8 @@ enum Setting { kSleepWhenLaptopLidClosed = 424, kDisplayResolution = 425, kDisplayRefreshRate = 426, - kRemoveDlc = 427, + // Note: Value 427 was for deprecated Remove DLC - see + // https://crbug.com/1108093. Do not reuse. kDisplayMirroring = 428, kAllowWindowsToSpanDisplays = 429, kAmbientColors = 430, @@ -117,7 +123,8 @@ enum Setting { kAmbientModeOnOff = 501, kAmbientModeSource = 502, kChangeDeviceAccountImage = 503, - kAmbientModeUpdatePhotosContainers = 504, + // Note: Value 504 was for deprecated kAmbientModeUpdatePhotosContainers. + // Do not reuse. // Search and Assistant section. kPreferredSearchEngine = 600, @@ -152,7 +159,9 @@ enum Setting { // Privacy section. kVerifiedAccess = 1101, - kKeepWifiOnDuringSleep = 1102, + // Note: Value 1102 was for deprecated "Keep wi-fi on during sleep" setting - + // see https://bugs.chromium.org/p/chromium/issues/detail?id=1077126. + // Do not reuse. kUsageStatsAndCrashReports = 1103, // Languages and Input section. @@ -160,6 +169,10 @@ enum Setting { kShowInputOptionsInShelf = 1201, kShowPersonalInformationSuggestions = 1202, kShowEmojiSuggestions = 1203, + kChangeSystemLanguage = 1204, + kOfferTranslation = 1205, + kAddInputMethod = 1206, + kSpellCheck = 1207, // Files section. kGoogleDriveConnection = 1300, 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 5c934d15a17..72c9b26652d 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_handler.cc @@ -504,7 +504,7 @@ void CrostiniHandler::OnCanDisableArcAdbSideloading( void CrostiniHandler::LaunchTerminal() { crostini::LaunchCrostiniApp( - profile_, crostini::GetTerminalId(), + profile_, crostini::kCrostiniTerminalSystemAppId, display::Screen::GetScreen()->GetPrimaryDisplay().id()); } @@ -512,6 +512,7 @@ void CrostiniHandler::HandleRequestContainerUpgradeView( const base::ListValue* args) { CHECK_EQ(0U, args->GetList().size()); chromeos::CrostiniUpgraderDialog::Show( + profile_, base::BindOnce(&CrostiniHandler::LaunchTerminal, weak_ptr_factory_.GetWeakPtr()), // If the user cancels the upgrade, we won't need to restart Crostini and diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_section.cc index 546c2ff9270..84640a580d8 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_section.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/crostini_section.cc @@ -7,13 +7,10 @@ #include "base/feature_list.h" #include "base/no_destructor.h" #include "base/strings/utf_string_conversions.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_pref_names.h" #include "chrome/browser/chromeos/crostini/crostini_util.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" @@ -76,6 +73,14 @@ const std::vector<SearchConcept>& GetCrostiniOptedInSearchConcepts() { IDS_OS_SETTINGS_TAG_CROSTINI_SHARED_FOLDERS_ALT2, IDS_OS_SETTINGS_TAG_CROSTINI_SHARED_FOLDERS_ALT3, SearchConcept::kAltTagEnd}}, + {IDS_OS_SETTINGS_TAG_CROSTINI_MIC_ACCESS, + mojom::kCrostiniDetailsSubpagePath, + mojom::SearchResultIcon::kPenguin, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSetting, + {.setting = mojom::Setting::kCrostiniMicAccess}, + {IDS_OS_SETTINGS_TAG_CROSTINI_MIC_ACCESS_ALT1, + SearchConcept::kAltTagEnd}}, }); return *tags; } @@ -178,28 +183,12 @@ const std::vector<SearchConcept>& GetCrostiniDiskResizingSearchConcepts() { return *tags; } -const std::vector<SearchConcept>& GetCrostiniMicSearchConcepts() { - static const base::NoDestructor<std::vector<SearchConcept>> tags({ - {IDS_OS_SETTINGS_TAG_CROSTINI_MIC_ACCESS, - mojom::kCrostiniDetailsSubpagePath, - mojom::SearchResultIcon::kPenguin, - mojom::SearchResultDefaultRank::kMedium, - mojom::SearchResultType::kSetting, - {.setting = mojom::Setting::kCrostiniMicAccess}, - {IDS_OS_SETTINGS_TAG_CROSTINI_MIC_ACCESS_ALT1, - SearchConcept::kAltTagEnd}}, - }); - return *tags; -} - bool IsProfileManaged(Profile* profile) { return profile->GetProfilePolicyConnector()->IsManaged(); } bool IsDeviceManaged() { - policy::BrowserPolicyConnectorChromeOS* connector = - g_browser_process->platform_part()->browser_policy_connector_chromeos(); - return connector->IsEnterpriseManaged(); + return webui::IsEnterpriseManaged(); } bool IsAdbSideloadingAllowed() { @@ -210,10 +199,6 @@ bool IsDiskResizingAllowed() { return base::FeatureList::IsEnabled(features::kCrostiniDiskResizing); } -bool IsMicSettingAllowed() { - return base::FeatureList::IsEnabled(features::kCrostiniShowMicSetting); -} - } // namespace CrostiniSection::CrostiniSection(Profile* profile, @@ -438,7 +423,6 @@ void CrostiniSection::AddLoadTimeData(content::WebUIDataSource* html_source) { html_source->AddBoolean("showCrostiniContainerUpgrade", IsContainerUpgradeAllowed()); html_source->AddBoolean("showCrostiniDiskResize", IsDiskResizingAllowed()); - html_source->AddBoolean("showCrostiniMic", IsMicSettingAllowed()); } void CrostiniSection::AddHandlers(content::WebUI* web_ui) { @@ -558,7 +542,6 @@ void CrostiniSection::UpdateSearchTags() { updater.RemoveSearchTags(GetCrostiniPortForwardingSearchConcepts()); updater.RemoveSearchTags(GetCrostiniContainerUpgradeSearchConcepts()); updater.RemoveSearchTags(GetCrostiniDiskResizingSearchConcepts()); - updater.RemoveSearchTags(GetCrostiniMicSearchConcepts()); if (!IsCrostiniAllowed()) return; @@ -586,9 +569,6 @@ void CrostiniSection::UpdateSearchTags() { if (IsDiskResizingAllowed()) updater.AddSearchTags(GetCrostiniDiskResizingSearchConcepts()); - - if (IsMicSettingAllowed()) - updater.AddSearchTags(GetCrostiniMicSearchConcepts()); } } // namespace settings 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 74b1ac7cc36..95fc2fb126a 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 @@ -50,7 +50,7 @@ #include "chromeos/printing/printer_configuration.h" #include "chromeos/printing/printer_translator.h" #include "chromeos/printing/printing_constants.h" -#include "chromeos/printing/uri_components.h" +#include "chromeos/printing/uri.h" #include "components/device_event_log/device_event_log.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" @@ -59,7 +59,6 @@ #include "google_apis/google_api_keys.h" #include "net/base/filename_util.h" #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" @@ -97,21 +96,11 @@ void RecordIppQueryResult(const PrinterQueryResult& result) { } // Query an IPP printer to check for autoconf support where the printer is -// located at |printer_uri|. Results are reported through |callback|. It is an -// error to attempt this with a non-IPP printer. -void QueryAutoconf(const std::string& printer_uri, - PrinterInfoCallback callback) { - auto optional = ParseUri(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, - printing::PrinterStatus(), "", "", "", {}, false); - return; - } - - UriComponents uri = optional.value(); - QueryIppPrinter(uri.host(), uri.port(), uri.path(), uri.encrypted(), +// located at |printer_uri|. Results are reported through |callback|. The +// scheme of |printer_uri| must equal "ipp" or "ipps". +void QueryAutoconf(const Uri& uri, PrinterInfoCallback callback) { + QueryIppPrinter(uri.GetHostEncoded(), uri.GetPort(), + uri.GetPathEncodedAsString(), uri.GetScheme() == kIppsScheme, std::move(callback)); } @@ -130,23 +119,6 @@ base::Value BuildCupsPrintersList(const std::vector<Printer>& printers) { return response; } -// Extracts a sanitized value of printerQueue from |printer_dict|. Returns an -// empty string if the value was not present in the dictionary. -std::string GetPrinterQueue(const base::DictionaryValue& printer_dict) { - std::string queue; - if (!printer_dict.GetString("printerQueue", &queue)) { - return queue; - } - - if (!queue.empty() && queue[0] == '/') { - // Strip the leading backslash. It is expected that this results in an - // empty string if the input is just a backslash. - queue = queue.substr(1); - } - - return queue; -} - // Generates a Printer from |printer_dict| where |printer_dict| is a // CupsPrinterInfo representation. If any of the required fields are missing, // returns nullptr. @@ -174,13 +146,11 @@ std::unique_ptr<chromeos::Printer> DictToPrinter( return nullptr; } - std::string printer_queue = GetPrinterQueue(printer_dict); - - std::string printer_uri = - printer_protocol + url::kStandardSchemeSeparator + printer_address; - if (!printer_queue.empty()) { - printer_uri += "/" + printer_queue; - } + std::string printer_queue; + printer_dict.GetString("printerQueue", &printer_queue); + // Path must start from '/' character. + if (!printer_queue.empty() && printer_queue.front() != '/') + printer_queue = "/" + printer_queue; auto printer = std::make_unique<chromeos::Printer>(printer_id); printer->set_display_name(printer_name); @@ -188,9 +158,22 @@ std::unique_ptr<chromeos::Printer> DictToPrinter( printer->set_manufacturer(printer_manufacturer); 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); + Uri uri(printer_protocol + url::kStandardSchemeSeparator + printer_address + + printer_queue); + if (uri.GetLastParsingError().status != Uri::ParserStatus::kNoErrors) { + PRINTER_LOG(ERROR) << "Uri parse error: " + << static_cast<int>(uri.GetLastParsingError().status); + return nullptr; + } + + std::string message; + if (!printer->SetUri(uri, &message)) { + PRINTER_LOG(ERROR) << "Incorrect uri: " << message; + return nullptr; + } + return printer; } @@ -414,9 +397,9 @@ void CupsPrintersHandler::HandleUpdateCupsPrinter(const base::ListValue* args) { Printer printer(printer_id); printer.set_display_name(printer_name); - if (!profile_->GetPrefs()->GetBoolean(prefs::kUserNativePrintersAllowed)) { + if (!profile_->GetPrefs()->GetBoolean(prefs::kUserPrintersAllowed)) { PRINTER_LOG(DEBUG) << "HandleUpdateCupsPrinter() called when " - "kUserNativePrintersAllowed is set to false"; + "kUserPrintersAllowed is set to false"; OnAddedOrEditedPrinterCommon(printer, PrinterSetupResult::kNativePrintersNotAllowed, false /* is_automatic */); @@ -477,14 +460,11 @@ void CupsPrintersHandler::HandleGetPrinterInfo(const base::ListValue* args) { return; } - if (printer_address.empty()) { - // Run the failure callback. - OnAutoconfQueried(callback_id, PrinterQueryResult::UNKNOWN_FAILURE, - printing::PrinterStatus(), "", "", "", {}, false); - return; - } - - std::string printer_queue = GetPrinterQueue(*printer_dict); + std::string printer_queue; + printer_dict->GetString("printerQueue", &printer_queue); + // Path must start from '/' character. + if (!printer_queue.empty() && printer_queue.front() != '/') + printer_queue = "/" + printer_queue; std::string printer_protocol; if (!printer_dict->GetString("printerProtocol", &printer_protocol)) { @@ -494,13 +474,20 @@ void CupsPrintersHandler::HandleGetPrinterInfo(const base::ListValue* args) { DCHECK(printer_protocol == kIppScheme || printer_protocol == kIppsScheme) << "Printer info requests only supported for IPP and IPPS printers"; + + Uri uri(printer_protocol + url::kStandardSchemeSeparator + printer_address + + printer_queue); + if (uri.GetLastParsingError().status != Uri::ParserStatus::kNoErrors || + !IsValidPrinterUri(uri)) { + // Run the failure callback. + OnAutoconfQueried(callback_id, PrinterQueryResult::UNKNOWN_FAILURE, + printing::PrinterStatus(), "", "", "", {}, false); + return; + } + PRINTER_LOG(DEBUG) << "Querying printer info"; - std::string printer_uri = - base::StringPrintf("%s://%s/%s", printer_protocol.c_str(), - printer_address.c_str(), printer_queue.c_str()); - QueryAutoconf(printer_uri, - base::BindOnce(&CupsPrintersHandler::OnAutoconfQueried, - weak_factory_.GetWeakPtr(), callback_id)); + QueryAutoconf(uri, base::BindOnce(&CupsPrintersHandler::OnAutoconfQueried, + weak_factory_.GetWeakPtr(), callback_id)); } void CupsPrintersHandler::OnAutoconfQueriedDiscovered( @@ -652,9 +639,9 @@ void CupsPrintersHandler::AddOrReconfigurePrinter(const base::ListValue* args, return; } - if (!profile_->GetPrefs()->GetBoolean(prefs::kUserNativePrintersAllowed)) { + if (!profile_->GetPrefs()->GetBoolean(prefs::kUserPrintersAllowed)) { PRINTER_LOG(DEBUG) << "AddOrReconfigurePrinter() called when " - "kUserNativePrintersAllowed is set to false"; + "kUserPrintersAllowed is set to false"; OnAddedOrEditedPrinterCommon(*printer, PrinterSetupResult::kNativePrintersNotAllowed, false /* is_automatic */); @@ -664,14 +651,6 @@ void CupsPrintersHandler::AddOrReconfigurePrinter(const base::ListValue* args, return; } - if (!printer->GetUriComponents().has_value()) { - // If the returned optional does not contain a value then it means that the - // printer's uri was not able to be parsed successfully. - PRINTER_LOG(ERROR) << "Failed to parse printer URI"; - OnAddOrEditPrinterError(callback_id, PrinterSetupResult::kFatalError); - return; - } - // Grab the existing printer object and check that we are not making any // changes that will make |existing_printer_object| unusable. if (printer->id().empty()) { @@ -1091,7 +1070,7 @@ void CupsPrintersHandler::HandleAddDiscoveredPrinter( return; } - if (!printer->GetUriComponents().has_value()) { + if (!printer->HasUri()) { PRINTER_LOG(DEBUG) << "Could not parse uri"; // The printer uri was not parsed successfully. Fail the add. ResolveJavascriptCallback( @@ -1226,14 +1205,13 @@ void CupsPrintersHandler::OnIpResolved(const std::string& callback_id, } PRINTER_LOG(EVENT) << printer.make_and_model() << " IP Resolution succeeded"; - std::string resolved_uri = printer.ReplaceHostAndPort(endpoint); + const Uri uri = printer.ReplaceHostAndPort(endpoint); - if (IsIppUri(resolved_uri)) { + if (IsIppUri(uri)) { PRINTER_LOG(EVENT) << "Query printer for IPP attributes"; QueryAutoconf( - resolved_uri, - base::BindOnce(&CupsPrintersHandler::OnAutoconfQueriedDiscovered, - weak_factory_.GetWeakPtr(), callback_id, printer)); + uri, base::BindOnce(&CupsPrintersHandler::OnAutoconfQueriedDiscovered, + weak_factory_.GetWeakPtr(), callback_id, printer)); return; } @@ -1299,7 +1277,7 @@ void CupsPrintersHandler::OnQueryPrintServerCompleted( std::set<GURL> known_printers; for (const Printer& printer : saved_printers) { base::Optional<GURL> gurl = - GenerateServerPrinterUrlWithValidScheme(printer.uri()); + GenerateServerPrinterUrlWithValidScheme(printer.uri().GetNormalized()); if (gurl) known_printers.insert(gurl.value()); } @@ -1311,8 +1289,8 @@ void CupsPrintersHandler::OnQueryPrintServerCompleted( printers.reserve(returned_printers.size()); for (PrinterDetector::DetectedPrinter& printer : returned_printers) { printers.push_back(std::move(printer.printer)); - base::Optional<GURL> printer_gurl = - GenerateServerPrinterUrlWithValidScheme(printers.back().uri()); + base::Optional<GURL> printer_gurl = GenerateServerPrinterUrlWithValidScheme( + printers.back().uri().GetNormalized()); if (printer_gurl && known_printers.count(printer_gurl.value())) printers.pop_back(); } diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler_unittest.cc index 00cd8e56cb4..412742de497 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler_unittest.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler_unittest.cc @@ -267,16 +267,16 @@ TEST_F(CupsPrintersHandlerTest, VerifyPrintManagementAppEntryPointHistogram) { web_ui_.HandleReceivedMessage("openPrintManagementApp", &base::Value::AsListValue(args)); histogram_tester_.ExpectBucketCount( - "Printing.Cups.PrintManagementAppEntryPoint", + "Printing.CUPS.PrintManagementAppEntryPoint", PrintManagementAppEntryPoint::kSettings, 1); histogram_tester_.ExpectBucketCount( - "Printing.Cups.PrintManagementAppEntryPoint", + "Printing.CUPS.PrintManagementAppEntryPoint", PrintManagementAppEntryPoint::kNotification, 0); histogram_tester_.ExpectBucketCount( - "Printing.Cups.PrintManagementAppEntryPoint", + "Printing.CUPS.PrintManagementAppEntryPoint", PrintManagementAppEntryPoint::kLauncher, 0); histogram_tester_.ExpectBucketCount( - "Printing.Cups.PrintManagementAppEntryPoint", + "Printing.CUPS.PrintManagementAppEntryPoint", PrintManagementAppEntryPoint::kBrowser, 0); } diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_display_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_display_handler.cc index fdfe3d16bd6..e5e61172c6c 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_display_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_display_handler.cc @@ -26,10 +26,13 @@ DisplayHandler::~DisplayHandler() { void DisplayHandler::RegisterMessages() { web_ui()->RegisterMessageCallback( "highlightDisplay", - base::BindRepeating( - &DisplayHandler::HandleHighlightDisplay, - base::Unretained(this))); // base::Unretained(this) is acceptable - // here as |this| is owned by web_ui(). + base::BindRepeating(&DisplayHandler::HandleHighlightDisplay, + base::Unretained(this))); + + web_ui()->RegisterMessageCallback( + "dragDisplayDelta", + base::BindRepeating(&DisplayHandler::HandleDragDisplayDelta, + base::Unretained(this))); } void DisplayHandler::HandleHighlightDisplay(const base::ListValue* args) { @@ -47,5 +50,23 @@ void DisplayHandler::HandleHighlightDisplay(const base::ListValue* args) { cros_display_config_->HighlightDisplay(display_id); } +void DisplayHandler::HandleDragDisplayDelta(const base::ListValue* args) { + DCHECK_EQ(3U, args->GetSize()); + AllowJavascript(); + + const auto& args_list = args->GetList(); + const std::string& display_id_str = args_list[0].GetString(); + int32_t delta_x = static_cast<int32_t>(args_list[1].GetInt()); + int32_t delta_y = static_cast<int32_t>(args_list[2].GetInt()); + + int64_t display_id; + if (!base::StringToInt64(display_id_str, &display_id)) { + NOTREACHED() << "Unable to parse |display_id| for HandleDragDisplayDelta"; + return; + } + + cros_display_config_->DragDisplayDelta(display_id, delta_x, delta_y); +} + } // namespace settings } // namespace chromeos diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_display_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/device_display_handler.h index 62f3f402acb..0331b77fbb5 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_display_handler.h +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_display_handler.h @@ -32,6 +32,7 @@ class DisplayHandler : public ::settings::SettingsPageUIHandler { private: void HandleHighlightDisplay(const base::ListValue* args); + void HandleDragDisplayDelta(const base::ListValue* args); mojo::Remote<ash::mojom::CrosDisplayConfigController> cros_display_config_; }; diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_dlc_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_dlc_handler.cc deleted file mode 100644 index c90f34eff69..00000000000 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_dlc_handler.cc +++ /dev/null @@ -1,102 +0,0 @@ -// 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/device_dlc_handler.h" -#include "base/bind.h" -#include "base/values.h" -#include "ui/base/text/bytes_formatting.h" - -namespace chromeos { -namespace settings { -namespace { - -base::ListValue DlcsWithContentToListValue( - const dlcservice::DlcsWithContent& dlcs_with_content) { - base::ListValue dlc_metadata_list; - for (int i = 0; i < dlcs_with_content.dlc_infos_size(); i++) { - const auto& dlc_info = dlcs_with_content.dlc_infos(i); - base::Value dlc_metadata(base::Value::Type::DICTIONARY); - dlc_metadata.SetKey("id", base::Value(dlc_info.id())); - dlc_metadata.SetKey("name", base::Value(dlc_info.name())); - dlc_metadata.SetKey("description", base::Value(dlc_info.description())); - dlc_metadata.SetKey( - "diskUsageLabel", - base::Value(ui::FormatBytes(dlc_info.used_bytes_on_disk()))); - dlc_metadata_list.Append(std::move(dlc_metadata)); - } - return dlc_metadata_list; -} - -} // namespace - -DlcHandler::DlcHandler() = default; - -DlcHandler::~DlcHandler() = default; - -void DlcHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback( - "dlcSubpageReady", base::BindRepeating(&DlcHandler::HandleDlcSubpageReady, - base::Unretained(this))); - - web_ui()->RegisterMessageCallback( - "purgeDlc", - base::BindRepeating(&DlcHandler::HandlePurgeDlc, base::Unretained(this))); -} - -void DlcHandler::OnJavascriptAllowed() { - dlcservice_client_observer_.Add(DlcserviceClient::Get()); -} - -void DlcHandler::OnJavascriptDisallowed() { - dlcservice_client_observer_.RemoveAll(); - - // Ensure that pending callbacks do not complete and cause JS to be evaluated. - weak_ptr_factory_.InvalidateWeakPtrs(); -} - -void DlcHandler::OnDlcStateChanged(const dlcservice::DlcState& dlc_state) { - FetchDlcList(); -} - -void DlcHandler::HandleDlcSubpageReady(const base::ListValue* args) { - AllowJavascript(); - FetchDlcList(); -} - -void DlcHandler::HandlePurgeDlc(const base::ListValue* args) { - AllowJavascript(); - CHECK_EQ(2U, args->GetSize()); - const base::Value* callback_id; - CHECK(args->Get(0, &callback_id)); - std::string dlcId; - CHECK(args->GetString(1, &dlcId)); - - DlcserviceClient::Get()->Purge( - dlcId, - base::BindOnce(&DlcHandler::PurgeDlcCallback, - weak_ptr_factory_.GetWeakPtr(), callback_id->Clone())); -} - -void DlcHandler::FetchDlcList() { - DlcserviceClient::Get()->GetExistingDlcs( - base::BindOnce(&DlcHandler::SendDlcList, weak_ptr_factory_.GetWeakPtr())); -} - -void DlcHandler::SendDlcList( - const std::string& err, - const dlcservice::DlcsWithContent& dlcs_with_content) { - FireWebUIListener("dlc-list-changed", - err == dlcservice::kErrorNone - ? DlcsWithContentToListValue(dlcs_with_content) - : base::ListValue()); -} - -void DlcHandler::PurgeDlcCallback(const base::Value& callback_id, - const std::string& err) { - ResolveJavascriptCallback(callback_id, - base::Value(err == dlcservice::kErrorNone)); -} - -} // namespace settings -} // namespace chromeos diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_dlc_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/device_dlc_handler.h deleted file mode 100644 index cbd3f798c74..00000000000 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_dlc_handler.h +++ /dev/null @@ -1,63 +0,0 @@ -// 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_DEVICE_DLC_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_DLC_HANDLER_H_ - -#include "base/memory/weak_ptr.h" -#include "base/scoped_observer.h" -#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" -#include "chromeos/dbus/dlcservice/dlcservice_client.h" - -namespace base { -class ListValue; -} // namespace base - -namespace chromeos { -namespace settings { - -// Chrome OS Downloaded Content settings page UI handler. -class DlcHandler : public ::settings::SettingsPageUIHandler, - public DlcserviceClient::Observer { - public: - DlcHandler(); - DlcHandler(const DlcHandler&) = delete; - DlcHandler& operator=(const DlcHandler&) = delete; - ~DlcHandler() override; - - // SettingsPageUIHandler: - void RegisterMessages() override; - void OnJavascriptAllowed() override; - void OnJavascriptDisallowed() override; - - // DlcserviceClient::Observer: - void OnDlcStateChanged(const dlcservice::DlcState& dlc_state) override; - - private: - // Handler called when DLC subpage is attached. - void HandleDlcSubpageReady(const base::ListValue* args); - - // Handler to purge a DLC. - void HandlePurgeDlc(const base::ListValue* args); - - // Fetches the latest DLC list from DlcserviceClient, passing SendDlcList() as - // the callback. - void FetchDlcList(); - - // Sends DLC list to web UIs listening in on 'dlc-list-changed' events. - void SendDlcList(const std::string& err, - const dlcservice::DlcsWithContent& dlcs_with_content); - - void PurgeDlcCallback(const base::Value& callback_id, const std::string& err); - - ScopedObserver<DlcserviceClient, DlcserviceClient::Observer> - dlcservice_client_observer_{this}; - - base::WeakPtrFactory<DlcHandler> weak_ptr_factory_{this}; -}; - -} // namespace settings -} // namespace chromeos - -#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_DLC_HANDLER_H_ diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_dlc_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_dlc_handler_unittest.cc deleted file mode 100644 index b99ed70fcde..00000000000 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_dlc_handler_unittest.cc +++ /dev/null @@ -1,191 +0,0 @@ -// 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/device_dlc_handler.h" -#include "base/strings/string_number_conversions.h" -#include "chromeos/dbus/dlcservice/fake_dlcservice_client.h" -#include "content/public/test/browser_task_environment.h" -#include "content/public/test/test_web_ui.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace chromeos { -namespace settings { - -namespace { - -dlcservice::DlcsWithContent CreateDlcModuleListOfSize(size_t numDlcs) { - dlcservice::DlcsWithContent dlc_module_list; - dlcservice::DlcsWithContent_DlcInfo* dlc_module_info; - for (size_t i = 0; i < numDlcs; i++) { - dlc_module_info = dlc_module_list.add_dlc_infos(); - } - return dlc_module_list; -} - -class TestDlcHandler : public DlcHandler { - public: - TestDlcHandler() = default; - ~TestDlcHandler() override = default; - - // Make public for testing. - using DlcHandler::AllowJavascript; - using DlcHandler::set_web_ui; -}; - -class DlcHandlerTest : public testing::Test { - public: - DlcHandlerTest() = default; - ~DlcHandlerTest() override = default; - DlcHandlerTest(const DlcHandlerTest&) = delete; - DlcHandlerTest& operator=(const DlcHandlerTest&) = delete; - - void SetUp() override { - test_web_ui_ = std::make_unique<content::TestWebUI>(); - - chromeos::DlcserviceClient::InitializeFake(); - fake_dlcservice_client_ = static_cast<chromeos::FakeDlcserviceClient*>( - chromeos::DlcserviceClient::Get()); - - handler_ = std::make_unique<TestDlcHandler>(); - handler_->set_web_ui(test_web_ui_.get()); - handler_->RegisterMessages(); - handler_->AllowJavascriptForTesting(); - } - - void TearDown() override { - handler_.reset(); - test_web_ui_.reset(); - chromeos::DlcserviceClient::Shutdown(); - } - - content::TestWebUI* test_web_ui() { return test_web_ui_.get(); } - - protected: - chromeos::FakeDlcserviceClient* fake_dlcservice_client_; - std::unique_ptr<TestDlcHandler> handler_; - std::unique_ptr<content::TestWebUI> test_web_ui_; - content::BrowserTaskEnvironment task_environment_; - - const content::TestWebUI::CallData& CallDataAtIndex(size_t index) { - return *test_web_ui_->call_data()[index]; - } - - base::Value::ConstListView NotifyDlcSubpageReadyAndReturnDlcList() { - size_t call_data_count_before_call = test_web_ui()->call_data().size(); - - base::ListValue args; - args.AppendString("handlerFunctionName"); - test_web_ui()->HandleReceivedMessage("dlcSubpageReady", &args); - task_environment_.RunUntilIdle(); - - EXPECT_EQ(call_data_count_before_call + 1u, - test_web_ui()->call_data().size()); - - const content::TestWebUI::CallData& call_data = - CallDataAtIndex(call_data_count_before_call); - EXPECT_EQ("cr.webUIListenerCallback", call_data.function_name()); - EXPECT_EQ("dlc-list-changed", call_data.arg1()->GetString()); - return call_data.arg2()->GetList(); - } - - bool CallPurgeDlcAndReturnSuccess() { - size_t call_data_count_before_call = test_web_ui()->call_data().size(); - - base::ListValue args; - args.AppendString("handlerFunctionName"); - args.AppendString("dlcId"); - test_web_ui()->HandleReceivedMessage("purgeDlc", &args); - task_environment_.RunUntilIdle(); - - EXPECT_EQ(call_data_count_before_call + 1u, - test_web_ui()->call_data().size()); - - const content::TestWebUI::CallData& call_data = - CallDataAtIndex(call_data_count_before_call); - EXPECT_EQ("cr.webUIResponse", call_data.function_name()); - EXPECT_EQ("handlerFunctionName", call_data.arg1()->GetString()); - return call_data.arg3()->GetBool(); - } -}; - -TEST_F(DlcHandlerTest, SendDlcListOnDlcStatusChange) { - size_t call_data_count_before_call = test_web_ui()->call_data().size(); - fake_dlcservice_client_->set_dlcs_with_content(CreateDlcModuleListOfSize(2u)); - - dlcservice::DlcState dlc_state; - dlc_state.set_state(dlcservice::DlcState::INSTALLING); - fake_dlcservice_client_->NotifyObserversForTest(dlc_state); - task_environment_.RunUntilIdle(); - - EXPECT_EQ(call_data_count_before_call + 1u, - test_web_ui()->call_data().size()); - - const content::TestWebUI::CallData& call_data = - CallDataAtIndex(call_data_count_before_call); - EXPECT_EQ("cr.webUIListenerCallback", call_data.function_name()); - EXPECT_EQ("dlc-list-changed", call_data.arg1()->GetString()); - EXPECT_EQ(call_data.arg2()->GetList().size(), 2u); -} - -TEST_F(DlcHandlerTest, CorrectlyReturnsDlcMetadataListOnSubpageReady) { - fake_dlcservice_client_->set_dlcs_with_content(CreateDlcModuleListOfSize(2u)); - - fake_dlcservice_client_->SetGetExistingDlcsError(dlcservice::kErrorInternal); - EXPECT_EQ(NotifyDlcSubpageReadyAndReturnDlcList().size(), 0u); - - fake_dlcservice_client_->SetGetExistingDlcsError( - dlcservice::kErrorNeedReboot); - EXPECT_EQ(NotifyDlcSubpageReadyAndReturnDlcList().size(), 0u); - - fake_dlcservice_client_->SetGetExistingDlcsError( - dlcservice::kErrorInvalidDlc); - EXPECT_EQ(NotifyDlcSubpageReadyAndReturnDlcList().size(), 0u); - - fake_dlcservice_client_->SetGetExistingDlcsError( - dlcservice::kErrorAllocation); - EXPECT_EQ(NotifyDlcSubpageReadyAndReturnDlcList().size(), 0u); - - fake_dlcservice_client_->SetGetExistingDlcsError(dlcservice::kErrorNone); - EXPECT_EQ(NotifyDlcSubpageReadyAndReturnDlcList().size(), 2u); -} - -TEST_F(DlcHandlerTest, PurgeDlc) { - fake_dlcservice_client_->SetPurgeError(dlcservice::kErrorInternal); - EXPECT_FALSE(CallPurgeDlcAndReturnSuccess()); - - fake_dlcservice_client_->SetPurgeError(dlcservice::kErrorNeedReboot); - EXPECT_FALSE(CallPurgeDlcAndReturnSuccess()); - - fake_dlcservice_client_->SetPurgeError(dlcservice::kErrorInvalidDlc); - EXPECT_FALSE(CallPurgeDlcAndReturnSuccess()); - - fake_dlcservice_client_->SetPurgeError(dlcservice::kErrorAllocation); - EXPECT_FALSE(CallPurgeDlcAndReturnSuccess()); - - fake_dlcservice_client_->SetPurgeError(dlcservice::kErrorNone); - EXPECT_TRUE(CallPurgeDlcAndReturnSuccess()); -} - -TEST_F(DlcHandlerTest, FormattedCorrectly) { - dlcservice::DlcsWithContent dlcs_with_content; - auto* dlc_info = dlcs_with_content.add_dlc_infos(); - dlc_info->set_id("fake id"); - dlc_info->set_name("fake name"); - dlc_info->set_description("fake description"); - dlc_info->set_used_bytes_on_disk(100000); - - fake_dlcservice_client_->set_dlcs_with_content(dlcs_with_content); - - auto result_list = NotifyDlcSubpageReadyAndReturnDlcList(); - EXPECT_EQ(1UL, result_list.size()); - EXPECT_EQ("fake id", result_list[0].FindKey("id")->GetString()); - EXPECT_EQ("fake name", result_list[0].FindKey("name")->GetString()); - EXPECT_EQ("fake description", - result_list[0].FindKey("description")->GetString()); - EXPECT_EQ("97.7 KB", result_list[0].FindKey("diskUsageLabel")->GetString()); -} - -} // namespace - -} // namespace settings -} // namespace chromeos 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 5bba9dae1c8..efa5d926d6a 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 @@ -199,8 +199,9 @@ TEST_F(KeyboardHandlerTest, ExternalKeyboard) { 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(), {}, - {}); + fake_udev->AddFakeDevice(internal_kbd.name, internal_kbd.sys_path.value(), + /*subsystem=*/"input", /*sysattrs=*/{}, + /*properties=*/{}); // Generic external USB keyboard. const ui::InputDevice external_generic_kbd( 2, ui::INPUT_DEVICE_USB, "Logitech USB Keyboard", "", @@ -209,7 +210,9 @@ TEST_F(KeyboardHandlerTest, ExternalKeyboard) { "input/input2"), 0x046d, 0xc31c, 0x0111); fake_udev->AddFakeDevice(external_generic_kbd.name, - external_generic_kbd.sys_path.value(), {}, {}); + external_generic_kbd.sys_path.value(), + /*subsystem=*/"input", /*sysattrs=*/{}, + /*properties=*/{}); // Apple keyboard. const ui::InputDevice external_apple_kbd( 3, ui::INPUT_DEVICE_USB, "Apple Inc. Apple Keyboard", "", @@ -217,16 +220,19 @@ TEST_F(KeyboardHandlerTest, ExternalKeyboard) { "0003:05AC:026C.000A/input/input3"), 0x05ac, 0x026c, 0x0111); fake_udev->AddFakeDevice(external_apple_kbd.name, - external_apple_kbd.sys_path.value(), {}, {}); + external_apple_kbd.sys_path.value(), + /*subsystem=*/"input", /*sysattrs=*/{}, + /*properties=*/{}); // 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"}}); + fake_udev->AddFakeDevice( + external_chromeos_kbd.name, external_chromeos_kbd.sys_path.value(), + /*subsystem=*/"input", /*sysattrs=*/{}, + /*properties=*/{{"CROS_KEYBOARD_TOP_ROW_LAYOUT", "1"}}); // An internal keyboard shouldn't change the defaults. base::CommandLine::ForCurrentProcess()->AppendSwitch( 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 d301f7a917b..36aee6213e2 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 @@ -176,7 +176,7 @@ class PowerHandlerTest : public InProcessBrowserTest { // Sets a policy update which will cause power pref managed change. void SetPolicyForPolicyKey(policy::PolicyMap* policy_map, const std::string& policy_key, - std::unique_ptr<base::Value> value) { + base::Value value) { policy_map->Set(policy_key, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD, std::move(value), nullptr); @@ -224,21 +224,20 @@ IN_PROC_BROWSER_TEST_F(PowerHandlerTest, SendSettingsForControlledPrefs) { // 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)); + base::Value(10000)); 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)); + 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)); + SetPolicyForPolicyKey(&policy_map, policy::key::kLidCloseAction, + base::Value(PowerPolicyController::ACTION_SUSPEND)); settings.lid_closed_controlled = true; EXPECT_EQ(ToString(settings), GetLastSettingsChangedMessage()); } @@ -288,9 +287,9 @@ IN_PROC_BROWSER_TEST_F(PowerHandlerTest, SendManagedIdleSettingForPrefChanges) { // 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)); + SetPolicyForPolicyKey( + &policy_map, policy::key::kIdleActionAC, + base::Value(chromeos::PowerPolicyController::ACTION_SUSPEND)); DevicePowerSettings settings; std::set<PowerHandler::IdleBehavior> behaviors; behaviors.insert(PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP); @@ -301,9 +300,9 @@ IN_PROC_BROWSER_TEST_F(PowerHandlerTest, SendManagedIdleSettingForPrefChanges) { // 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)); + SetPolicyForPolicyKey( + &policy_map, policy::key::kIdleActionBattery, + base::Value(chromeos::PowerPolicyController::ACTION_SHUT_DOWN)); behaviors.clear(); behaviors.insert(PowerHandler::IdleBehavior::OTHER); settings.possible_battery_behaviors = behaviors; @@ -317,8 +316,7 @@ IN_PROC_BROWSER_TEST_F(PowerHandlerTest, SendManagedIdleSettingForPrefChanges) { // 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)); + base::Value(chromeos::PowerPolicyController::ACTION_DO_NOTHING)); behaviors.clear(); behaviors.insert(PowerHandler::IdleBehavior::DISPLAY_OFF); behaviors.insert(PowerHandler::IdleBehavior::DISPLAY_ON); @@ -330,7 +328,7 @@ IN_PROC_BROWSER_TEST_F(PowerHandlerTest, SendManagedIdleSettingForPrefChanges) { // 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)); + base::Value(10000)); behaviors.clear(); behaviors.insert(PowerHandler::IdleBehavior::DISPLAY_OFF); settings.possible_battery_behaviors = behaviors; diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_section.cc index 7921e8838dd..0cd19dec090 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_section.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_section.cc @@ -15,7 +15,6 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/chromeos/login/demo_mode/demo_session.h" #include "chrome/browser/ui/webui/settings/chromeos/device_display_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/device_dlc_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" @@ -399,30 +398,6 @@ const std::vector<SearchConcept>& GetDisplayNightLightOnSearchConcepts() { return *tags; } -const std::vector<SearchConcept>& GetDlcSearchConcepts() { - static const base::NoDestructor<std::vector<SearchConcept>> tags({ - {IDS_OS_SETTINGS_TAG_DOWNLOADED_CONTENT, - mojom::kDlcSubpagePath, - mojom::SearchResultIcon::kHardDrive, - mojom::SearchResultDefaultRank::kMedium, - mojom::SearchResultType::kSubpage, - {.subpage = mojom::Subpage::kDlc}, - {IDS_OS_SETTINGS_TAG_DOWNLOADED_CONTENT_ALT1, - SearchConcept::kAltTagEnd}}, - {IDS_OS_SETTINGS_TAG_REMOVE_DOWNLOADED_CONTENT, - mojom::kDlcSubpagePath, - mojom::SearchResultIcon::kHardDrive, - mojom::SearchResultDefaultRank::kMedium, - mojom::SearchResultType::kSetting, - {.setting = mojom::Setting::kRemoveDlc}, - {IDS_OS_SETTINGS_TAG_REMOVE_DOWNLOADED_CONTENT_ALT1, - IDS_OS_SETTINGS_TAG_REMOVE_DOWNLOADED_CONTENT_ALT2, - IDS_OS_SETTINGS_TAG_REMOVE_DOWNLOADED_CONTENT_ALT3, - SearchConcept::kAltTagEnd}}, - }); - return *tags; -} - const std::vector<SearchConcept>& GetExternalStorageSearchConcepts() { static const base::NoDestructor<std::vector<SearchConcept>> tags({ {IDS_OS_SETTINGS_TAG_EXTERNAL_STORAGE, @@ -654,6 +629,10 @@ void AddDeviceDisplayStrings(content::WebUIDataSource* html_source) { html_source->AddString("invalidDisplayId", base::NumberToString(display::kInvalidDisplayId)); + + html_source->AddBoolean( + "allowDisplayAlignmentApi", + base::FeatureList::IsEnabled(ash::features::kDisplayAlignAssist)); } void AddDeviceStorageStrings(content::WebUIDataSource* html_source, @@ -687,10 +666,7 @@ void AddDeviceStorageStrings(content::WebUIDataSource* html_source, IDS_SETTINGS_STORAGE_EXTERNAL_STORAGE_EMPTY_LIST_HEADER}, {"storageExternalStorageListHeader", IDS_SETTINGS_STORAGE_EXTERNAL_STORAGE_LIST_HEADER}, - {"storageManageDownloadedContentRowTitle", - IDS_SETTINGS_STORAGE_MANAGE_DOWNLOADED_CONTENT_ROW_TITLE}, - {"storageOverviewAriaLabel", IDS_SETTINGS_STORAGE_OVERVIEW_ARIA_LABEL}, - }; + {"storageOverviewAriaLabel", IDS_SETTINGS_STORAGE_OVERVIEW_ARIA_LABEL}}; AddLocalizedStringsBulk(html_source, kStorageStrings); html_source->AddBoolean("androidEnabled", is_external_storage_page_available); @@ -702,17 +678,6 @@ void AddDeviceStorageStrings(content::WebUIDataSource* html_source, base::ASCIIToUTF16(chrome::kArcExternalStorageLearnMoreURL))); } -void AddDeviceDlcSubpageStrings(content::WebUIDataSource* html_source) { - static constexpr webui::LocalizedString kDlcSubpageStrings[] = { - {"dlcSubpageTitle", IDS_SETTINGS_DLC_SUBPAGE_TITLE}, - {"dlcSubpageDescription", IDS_SETTINGS_DLC_SUBPAGE_DESCRIPTION}, - {"removeDlc", IDS_SETTINGS_DLC_REMOVE}, - }; - AddLocalizedStringsBulk(html_source, kDlcSubpageStrings); - - html_source->AddBoolean("allowDlcSubpage", features::ShouldShowDlcSettings()); -} - void AddDevicePowerStrings(content::WebUIDataSource* html_source) { static constexpr webui::LocalizedString kPowerStrings[] = { {"powerTitle", IDS_SETTINGS_POWER_TITLE}, @@ -795,14 +760,6 @@ DeviceSection::DeviceSection(Profile* profile, OnNightLightEnabledChanged( ash::NightLightController::GetInstance()->GetEnabled()); } - - // DLC settings search tags are added/removed dynamically. - DlcserviceClient* dlcservice_client = DlcserviceClient::Get(); - if (features::ShouldShowDlcSettings() && dlcservice_client) { - dlcservice_client->AddObserver(this); - dlcservice_client->GetExistingDlcs(base::BindOnce( - &DeviceSection::OnGetExistingDlcs, weak_ptr_factory_.GetWeakPtr())); - } } DeviceSection::~DeviceSection() { @@ -817,10 +774,6 @@ DeviceSection::~DeviceSection() { ash::NightLightController::GetInstance(); if (night_light_controller) night_light_controller->RemoveObserver(this); - - DlcserviceClient* dlcservice_client = DlcserviceClient::Get(); - if (features::ShouldShowDlcSettings() && dlcservice_client) - dlcservice_client->RemoveObserver(this); } void DeviceSection::AddLoadTimeData(content::WebUIDataSource* html_source) { @@ -841,20 +794,15 @@ void DeviceSection::AddLoadTimeData(content::WebUIDataSource* html_source) { AddDeviceStorageStrings( html_source, features::ShouldShowExternalStorageSettings(profile())); AddDevicePowerStrings(html_source); - AddDeviceDlcSubpageStrings(html_source); } void DeviceSection::AddHandlers(content::WebUI* web_ui) { - if (ash::features::IsDisplayIdentificationEnabled()) { + if (ash::features::IsDisplayIdentificationEnabled() || + ash::features::IsDisplayAlignmentAssistanceEnabled()) { web_ui->AddMessageHandler( std::make_unique<chromeos::settings::DisplayHandler>()); } - if (features::ShouldShowDlcSettings()) { - web_ui->AddMessageHandler( - std::make_unique<chromeos::settings::DlcHandler>()); - } - web_ui->AddMessageHandler( std::make_unique<chromeos::settings::KeyboardHandler>()); web_ui->AddMessageHandler( @@ -962,12 +910,6 @@ void DeviceSection::RegisterHierarchy(HierarchyGenerator* generator) const { mojom::Subpage::kStorage, mojom::SearchResultIcon::kHardDrive, mojom::SearchResultDefaultRank::kMedium, mojom::kExternalStorageSubpagePath); - generator->RegisterNestedSubpage( - IDS_SETTINGS_DLC_SUBPAGE_TITLE, mojom::Subpage::kDlc, - mojom::Subpage::kStorage, mojom::SearchResultIcon::kHardDrive, - mojom::SearchResultDefaultRank::kMedium, mojom::kDlcSubpagePath); - generator->RegisterNestedSetting(mojom::Setting::kRemoveDlc, - mojom::Subpage::kDlc); // Power. generator->RegisterTopLevelSubpage( @@ -1026,24 +968,6 @@ void DeviceSection::PowerChanged( } } -void DeviceSection::OnGetExistingDlcs( - const std::string& err, - const dlcservice::DlcsWithContent& dlcs_with_content) { - SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate(); - - if (err != dlcservice::kErrorNone || - dlcs_with_content.dlc_infos_size() == 0) { - updater.RemoveSearchTags(GetDlcSearchConcepts()); - return; - } - updater.AddSearchTags(GetDlcSearchConcepts()); -} - -void DeviceSection::OnDlcStateChanged(const dlcservice::DlcState& dlc_state) { - DlcserviceClient::Get()->GetExistingDlcs(base::BindOnce( - &DeviceSection::OnGetExistingDlcs, weak_ptr_factory_.GetWeakPtr())); -} - void DeviceSection::OnGetDisplayUnitInfoList( std::vector<ash::mojom::DisplayUnitInfoPtr> display_unit_info_list) { cros_display_config_->GetDisplayLayoutInfo(base::BindOnce( diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_section.h b/chromium/chrome/browser/ui/webui/settings/chromeos/device_section.h index 541b8dbaafc..c3e7070b9dd 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_section.h +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_section.h @@ -13,7 +13,6 @@ #include "base/optional.h" #include "chrome/browser/chromeos/system/pointer_device_observer.h" #include "chrome/browser/ui/webui/settings/chromeos/os_settings_section.h" -#include "chromeos/dbus/dlcservice/dlcservice_client.h" #include "chromeos/dbus/power/power_manager_client.h" #include "mojo/public/cpp/bindings/associated_receiver.h" #include "mojo/public/cpp/bindings/remote.h" @@ -25,10 +24,6 @@ namespace content { class WebUIDataSource; } // namespace content -namespace dlcservice { -class DlcsWithContent; -} // namespace dlcservice - namespace chromeos { namespace settings { @@ -40,8 +35,7 @@ class DeviceSection : public OsSettingsSection, public ui::InputDeviceEventObserver, public ash::NightLightController::Observer, public ash::mojom::CrosDisplayConfigObserver, - public PowerManagerClient::Observer, - public DlcserviceClient::Observer { + public PowerManagerClient::Observer { public: DeviceSection(Profile* profile, SearchTagRegistry* search_tag_registry, @@ -74,9 +68,6 @@ class DeviceSection : public OsSettingsSection, // PowerManagerClient::Observer: void PowerChanged(const power_manager::PowerSupplyProperties& proto) override; - // DlcserviceClient::Observer: - void OnDlcStateChanged(const dlcservice::DlcState& dlc_state) override; - void OnGotSwitchStates( base::Optional<PowerManagerClient::SwitchStates> result); @@ -88,9 +79,6 @@ class DeviceSection : public OsSettingsSection, std::vector<ash::mojom::DisplayUnitInfoPtr> display_unit_info_list, ash::mojom::DisplayLayoutInfoPtr display_layout_info); - void OnGetExistingDlcs(const std::string& err, - const dlcservice::DlcsWithContent& dlcs_with_content); - void AddDevicePointersStrings(content::WebUIDataSource* html_source); PrefService* pref_service_; diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc index e3961f58389..c299a2bdea4 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc @@ -48,8 +48,6 @@ const char* CalculationTypeToEventName( return "storage-crostini-size-changed"; case calculator::SizeCalculator::CalculationType::kOtherUsers: return "storage-other-users-size-changed"; - case calculator::SizeCalculator::CalculationType::kDlcs: - return "storage-dlcs-size-changed"; } NOTREACHED(); return ""; @@ -65,7 +63,6 @@ StorageHandler::StorageHandler(Profile* profile, apps_size_calculator_(profile), crostini_size_calculator_(profile), other_users_size_calculator_(), - dlcs_size_calculator_(), profile_(profile), source_name_(html_source->GetSource()), arc_observer_(this), @@ -118,7 +115,6 @@ void StorageHandler::OnJavascriptAllowed() { apps_size_calculator_.AddObserver(this); crostini_size_calculator_.AddObserver(this); other_users_size_calculator_.AddObserver(this); - dlcs_size_calculator_.AddObserver(this); } void StorageHandler::OnJavascriptDisallowed() { @@ -171,7 +167,6 @@ void StorageHandler::HandleUpdateStorageInfo(const base::ListValue* args) { apps_size_calculator_.StartCalculation(); crostini_size_calculator_.StartCalculation(); other_users_size_calculator_.StartCalculation(); - dlcs_size_calculator_.StartCalculation(); } void StorageHandler::HandleOpenMyFiles(const base::ListValue* unused_args) { @@ -267,7 +262,6 @@ void StorageHandler::StopObservingEvents() { apps_size_calculator_.RemoveObserver(this); crostini_size_calculator_.RemoveObserver(this); other_users_size_calculator_.RemoveObserver(this); - dlcs_size_calculator_.RemoveObserver(this); } void StorageHandler::UpdateStorageItem( @@ -291,12 +285,6 @@ void StorageHandler::UpdateStorageItem( bool no_other_users = (total_bytes == 0); FireWebUIListener(CalculationTypeToEventName(calculation_type), base::Value(message), base::Value(no_other_users)); - } else if (calculation_type == - calculator::SizeCalculator::CalculationType::kDlcs) { - bool dlcs_exist = (total_bytes > 0); - FireWebUIListener(CalculationTypeToEventName(calculation_type), - base::Value(dlcs_exist), base::Value(message)); - } else { FireWebUIListener(CalculationTypeToEventName(calculation_type), base::Value(message)); diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h index d6b4e79a376..78e3db03d97 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 @@ -8,6 +8,7 @@ #include <string> #include "chrome/browser/chromeos/arc/session/arc_session_manager.h" +#include "chrome/browser/chromeos/arc/session/arc_session_manager_observer.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/disks/disk_mount_manager.h" @@ -41,7 +42,7 @@ const int64_t kSpaceCriticallyLowBytes = 512 * 1024 * 1024; const int64_t kSpaceLowBytes = 1 * 1024 * 1024 * 1024; class StorageHandler : public ::settings::SettingsPageUIHandler, - public arc::ArcSessionManager::Observer, + public arc::ArcSessionManagerObserver, public chromeos::disks::DiskMountManager::Observer, public calculator::SizeCalculator::Observer { public: @@ -53,7 +54,7 @@ class StorageHandler : public ::settings::SettingsPageUIHandler, void OnJavascriptAllowed() override; void OnJavascriptDisallowed() override; - // arc::ArcSessionManager::Observer: + // arc::ArcSessionManagerObserver: void OnArcPlayStoreEnabledChanged(bool enabled) override; // chromeos::disks::DiskMountManager::Observer: @@ -113,7 +114,6 @@ class StorageHandler : public ::settings::SettingsPageUIHandler, calculator::AppsSizeCalculator apps_size_calculator_; calculator::CrostiniSizeCalculator crostini_size_calculator_; calculator::OtherUsersSizeCalculator other_users_size_calculator_; - calculator::DlcsSizeCalculator dlcs_size_calculator_; // Controls if the size of each storage item has been calculated. std::bitset<calculator::SizeCalculator::kCalculationTypeCount> @@ -125,7 +125,7 @@ class StorageHandler : public ::settings::SettingsPageUIHandler, Profile* const profile_; const std::string source_name_; - ScopedObserver<arc::ArcSessionManager, arc::ArcSessionManager::Observer> + ScopedObserver<arc::ArcSessionManager, arc::ArcSessionManagerObserver> arc_observer_; const re2::RE2 special_volume_path_pattern_; diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler_unittest.cc index 86e80c50226..b05bf1bd730 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler_unittest.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler_unittest.cc @@ -23,7 +23,7 @@ #include "chrome/common/webui_url_constants.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile_manager.h" -#include "chromeos/dbus/dlcservice/fake_dlcservice_client.h" +#include "chromeos/dbus/dbus_thread_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" @@ -59,6 +59,9 @@ class StorageHandlerTest : public testing::Test { ~StorageHandlerTest() override = default; void SetUp() override { + // Need to initialize DBusThreadManager before ArcSessionManager's + // constructor calls DBusThreadManager::Get(). + chromeos::DBusThreadManager::Initialize(); // The storage handler requires an instance of DiskMountManager, // ArcServiceManager and ArcSessionManager. chromeos::disks::DiskMountManager::InitializeForTesting( @@ -97,8 +100,6 @@ class StorageHandlerTest : public testing::Test { other_users_size_test_api_ = std::make_unique<calculator::OtherUsersSizeTestAPI>( handler_.get(), new calculator::OtherUsersSizeCalculator()); - dlcs_size_test_api_ = std::make_unique<calculator::DlcsSizeTestAPI>( - handler_.get(), new calculator::DlcsSizeCalculator()); // Create and register My files directory. // By emulating chromeos running, GetMyFilesFolderForProfile will return the @@ -112,10 +113,6 @@ class StorageHandlerTest : public testing::Test { file_manager::util::GetDownloadsMountPointName(profile_), storage::kFileSystemTypeNativeLocal, storage::FileSystemMountOption(), my_files_path)); - - chromeos::DlcserviceClient::InitializeFake(); - fake_dlcservice_client_ = static_cast<chromeos::FakeDlcserviceClient*>( - chromeos::DlcserviceClient::Get()); } void TearDown() override { @@ -126,10 +123,11 @@ class StorageHandlerTest : public testing::Test { apps_size_test_api_.reset(); crostini_size_test_api_.reset(); other_users_size_test_api_.reset(); - dlcs_size_test_api_.reset(); + arc_session_manager_.reset(); + arc_service_manager_.reset(); chromeos::disks::DiskMountManager::Shutdown(); - chromeos::DlcserviceClient::Shutdown(); storage::ExternalMountPoints::GetSystemInstance()->RevokeAllFileSystems(); + chromeos::DBusThreadManager::Shutdown(); } protected: @@ -157,11 +155,8 @@ class StorageHandlerTest : public testing::Test { !data->arg1()->GetAsString(&name)) { continue; } - if (name == event_name) { - if (name == "storage-dlcs-size-changed") - return data->arg3(); + if (name == event_name) return data->arg2(); - } } return nullptr; } @@ -203,7 +198,6 @@ class StorageHandlerTest : public testing::Test { content::BrowserTaskEnvironment task_environment_; std::unique_ptr<TestingProfileManager> profile_manager_; Profile* profile_; - chromeos::FakeDlcserviceClient* fake_dlcservice_client_; std::unique_ptr<calculator::SizeStatTestAPI> size_stat_test_api_; std::unique_ptr<calculator::MyFilesSizeTestAPI> my_files_size_test_api_; std::unique_ptr<calculator::BrowsingDataSizeTestAPI> @@ -211,7 +205,6 @@ class StorageHandlerTest : public testing::Test { std::unique_ptr<calculator::AppsSizeTestAPI> apps_size_test_api_; std::unique_ptr<calculator::CrostiniSizeTestAPI> crostini_size_test_api_; std::unique_ptr<calculator::OtherUsersSizeTestAPI> other_users_size_test_api_; - std::unique_ptr<calculator::DlcsSizeTestAPI> dlcs_size_test_api_; private: std::unique_ptr<arc::ArcServiceManager> arc_service_manager_; @@ -355,26 +348,6 @@ TEST_F(StorageHandlerTest, MyFilesSize) { EXPECT_EQ("81.4 KB", callback->GetString()); } -TEST_F(StorageHandlerTest, DlcsSize) { - dlcservice::DlcsWithContent dlcs_with_content; - auto* dlc_info = dlcs_with_content.add_dlc_infos(); - dlc_info->set_used_bytes_on_disk(1); - dlc_info = dlcs_with_content.add_dlc_infos(); - dlc_info->set_used_bytes_on_disk(2); - fake_dlcservice_client_->set_dlcs_with_content(dlcs_with_content); - - // Calculate DLC size. - dlcs_size_test_api_->StartCalculation(); - task_environment_.RunUntilIdle(); - - const base::Value* callback = - GetWebUICallbackMessage("storage-dlcs-size-changed"); - ASSERT_TRUE(callback) << "No 'storage-dlcs-size-changed' callback"; - - // Check return value. - EXPECT_EQ("3 B", callback->GetString()); -} - TEST_F(StorageHandlerTest, AppsExtensionsSize) { // The data for apps and extensions apps_size_test_api_installed from the // webstore is stored in the Extensions folder. Add data at a random location @@ -489,18 +462,6 @@ TEST_F(StorageHandlerTest, SystemSize) { EXPECT_EQ("50.0 GB", callback->GetString()); ASSERT_FALSE(GetWebUICallbackMessage("storage-system-size-changed")); - // Simulate DLC size callback - dlcservice::DlcsWithContent dlcs_with_content; - auto* dlc_info = dlcs_with_content.add_dlc_infos(); - dlc_info->set_used_bytes_on_disk(20 * GB); - dlc_info = dlcs_with_content.add_dlc_infos(); - dlcs_size_test_api_->SimulateOnGetExistingDlcs(dlcservice::kErrorNone, - dlcs_with_content); - callback = GetWebUICallbackMessage("storage-dlcs-size-changed"); - ASSERT_TRUE(callback) << "No 'storage-dlcs-size-changed' callback"; - EXPECT_EQ("20.0 GB", callback->GetString()); - ASSERT_FALSE(GetWebUICallbackMessage("storage-system-size-changed")); - // Simulate other users size callback. No callback message until the sizes of // every users is calculated. std::vector<int64_t> other_user_sizes = @@ -527,7 +488,7 @@ TEST_F(StorageHandlerTest, SystemSize) { // updated. callback = GetWebUICallbackMessage("storage-system-size-changed"); ASSERT_TRUE(callback) << "No 'storage-system-size-changed' callback"; - EXPECT_EQ("100 GB", callback->GetString()); + EXPECT_EQ("120 GB", callback->GetString()); } } @@ -542,7 +503,7 @@ TEST_F(StorageHandlerTest, SystemSize) { // 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()); + EXPECT_EQ("144 GB", callback->GetString()); // No error while recalculating browsing data size, the UI should be updated // with the right sizes. @@ -553,7 +514,7 @@ TEST_F(StorageHandlerTest, SystemSize) { 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()); + EXPECT_EQ("120 GB", callback->GetString()); } } // namespace diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/internet_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/internet_section.cc index 69248ed127e..80441110d91 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/internet_section.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/internet_section.cc @@ -19,6 +19,7 @@ #include "chrome/common/webui_url_constants.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" +#include "chromeos/constants/chromeos_features.h" #include "chromeos/strings/grit/chromeos_strings.h" #include "components/strings/grit/components_strings.h" #include "content/public/browser/web_ui_data_source.h" @@ -316,6 +317,22 @@ const std::vector<SearchConcept>& GetCellularConnectedSearchConcepts() { return *tags; } +// TODO(1093185): Merge GetCellularSetupSearchConcepts() with +// GetCellularConnectedSearchConcepts() when flag is enabled. +const std::vector<SearchConcept>& GetCellularSetupSearchConcepts() { + static const base::NoDestructor<std::vector<SearchConcept>> tags({ + {IDS_OS_SETTINGS_TAG_ADD_CELLULAR, + mojom::kMobileDataNetworksSubpagePath, + mojom::SearchResultIcon::kCellular, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSetting, + {.setting = mojom::Setting::kCellularAddNetwork}, + {IDS_OS_SETTINGS_TAG_ADD_CELLULAR_ALT1, + IDS_OS_SETTINGS_TAG_ADD_CELLULAR_ALT2, SearchConcept::kAltTagEnd}}, + }); + return *tags; +} + const std::vector<SearchConcept>& GetCellularMeteredSearchConcepts() { static const base::NoDestructor<std::vector<SearchConcept>> tags({ {IDS_SETTINGS_INTERNET_NETWORK_METERED, @@ -433,6 +450,7 @@ const std::vector<mojom::Setting>& GetCellularDetailsSettings() { mojom::Setting::kCellularProxy, mojom::Setting::kCellularAutoConnectToNetwork, mojom::Setting::kCellularMetered, + mojom::Setting::kCellularAddNetwork, }); return *settings; } @@ -482,7 +500,9 @@ bool IsPartOfDetailsSubpage(mojom::SearchResultType type, std::string GetDetailsSubpageUrl(const std::string& url_to_modify, const std::string& guid) { - return base::StringPrintf("%s?guid=%s", url_to_modify.c_str(), guid.c_str()); + return base::StringPrintf( + "%s%sguid=%s", url_to_modify.c_str(), + url_to_modify.find('?') == std::string::npos ? "?" : "&", guid.c_str()); } } // namespace @@ -509,6 +529,7 @@ InternetSection::~InternetSection() = default; void InternetSection::AddLoadTimeData(content::WebUIDataSource* html_source) { static constexpr webui::LocalizedString kLocalizedStrings[] = { + {"internetAddCellular", IDS_SETTINGS_INTERNET_ADD_CELLULAR}, {"internetAddConnection", IDS_SETTINGS_INTERNET_ADD_CONNECTION}, {"internetAddConnectionExpandA11yLabel", IDS_SETTINGS_INTERNET_ADD_CONNECTION_EXPAND_ACCESSIBILITY_LABEL}, @@ -569,6 +590,7 @@ void InternetSection::AddLoadTimeData(content::WebUIDataSource* html_source) { {"networkIPAddress", IDS_SETTINGS_INTERNET_NETWORK_IP_ADDRESS}, {"networkIPConfigAuto", IDS_SETTINGS_INTERNET_NETWORK_IP_CONFIG_AUTO}, {"networkMetered", IDS_SETTINGS_INTERNET_NETWORK_METERED}, + {"networkMeteredDesc", IDS_SETTINGS_INTERNET_NETWORK_METERED_DESC}, {"networkNameserversLearnMore", IDS_LEARN_MORE}, {"networkPrefer", IDS_SETTINGS_INTERNET_NETWORK_PREFER}, {"networkPrimaryUserControlled", @@ -593,6 +615,8 @@ void InternetSection::AddLoadTimeData(content::WebUIDataSource* html_source) { IDS_SETTINGS_INTERNET_CELLULAR_CONTACT_SPECIFIC_CARRIER}, {"cellularContactDefaultCarrier", IDS_SETTINGS_INTERNET_CELLULAR_CONTACT_DEFAULT_CARRIER}, + {"cellularSetupDialogTitle", + IDS_SETTINGS_INTERNET_CELLULAR_SETUP_DIALOG_TITLE}, {"tetherPhoneOutOfRange", IDS_SETTINGS_INTERNET_TETHER_PHONE_OUT_OF_RANGE}, {"gmscoreNotificationsTitle", @@ -647,10 +671,14 @@ void InternetSection::AddLoadTimeData(content::WebUIDataSource* html_source) { !ash::features::IsSeparateNetworkIconsEnabled()); html_source->AddBoolean( "showMeteredToggle", - base::FeatureList::IsEnabled(features::kMeteredShowToggle)); + base::FeatureList::IsEnabled(::features::kMeteredShowToggle)); html_source->AddString("networkGoogleNameserversLearnMoreUrl", chrome::kGoogleNameserversLearnMoreURL); + html_source->AddBoolean( + "updatedCellularActivationUi", + base::FeatureList::IsEnabled( + chromeos::features::kUpdatedCellularActivationUi)); html_source->AddString( "networkNotSynced", @@ -786,23 +814,26 @@ std::string InternetSection::ModifySearchResultUrl( mojom::SearchResultType type, OsSettingsIdentifier id, const std::string& url_to_modify) const { + std::string modified_url = + OsSettingsSection::ModifySearchResultUrl(type, id, url_to_modify); + if (IsPartOfDetailsSubpage(type, id, mojom::Subpage::kEthernetDetails)) - return GetDetailsSubpageUrl(url_to_modify, *connected_ethernet_guid_); + return GetDetailsSubpageUrl(modified_url, *connected_ethernet_guid_); if (IsPartOfDetailsSubpage(type, id, mojom::Subpage::kWifiDetails)) - return GetDetailsSubpageUrl(url_to_modify, *connected_wifi_guid_); + return GetDetailsSubpageUrl(modified_url, *connected_wifi_guid_); if (IsPartOfDetailsSubpage(type, id, mojom::Subpage::kCellularDetails)) - return GetDetailsSubpageUrl(url_to_modify, *cellular_guid_); + return GetDetailsSubpageUrl(modified_url, *cellular_guid_); if (IsPartOfDetailsSubpage(type, id, mojom::Subpage::kTetherDetails)) - return GetDetailsSubpageUrl(url_to_modify, *connected_tether_guid_); + return GetDetailsSubpageUrl(modified_url, *connected_tether_guid_); if (IsPartOfDetailsSubpage(type, id, mojom::Subpage::kVpnDetails)) - return GetDetailsSubpageUrl(url_to_modify, *connected_vpn_guid_); + return GetDetailsSubpageUrl(modified_url, *connected_vpn_guid_); - // URL does not need to be modified; use default implementation. - return OsSettingsSection::ModifySearchResultUrl(type, id, url_to_modify); + // Use default implementation. + return modified_url; } void InternetSection::OnDeviceStateListChanged() { @@ -891,6 +922,7 @@ void InternetSection::OnNetworkList( updater.RemoveSearchTags(GetWifiMeteredSearchConcepts()); updater.RemoveSearchTags(GetCellularSearchConcepts()); updater.RemoveSearchTags(GetCellularConnectedSearchConcepts()); + updater.RemoveSearchTags(GetCellularSetupSearchConcepts()); updater.RemoveSearchTags(GetCellularMeteredSearchConcepts()); updater.RemoveSearchTags(GetInstantTetheringConnectedSearchConcepts()); updater.RemoveSearchTags(GetVpnConnectedSearchConcepts()); @@ -922,15 +954,20 @@ void InternetSection::OnNetworkList( case NetworkType::kWiFi: connected_wifi_guid_ = network->guid; updater.AddSearchTags(GetWifiConnectedSearchConcepts()); - if (base::FeatureList::IsEnabled(features::kMeteredShowToggle)) + if (base::FeatureList::IsEnabled(::features::kMeteredShowToggle)) updater.AddSearchTags(GetWifiMeteredSearchConcepts()); break; case NetworkType::kCellular: // Note: GUID is set above. updater.AddSearchTags(GetCellularConnectedSearchConcepts()); - if (base::FeatureList::IsEnabled(features::kMeteredShowToggle)) + if (base::FeatureList::IsEnabled(::features::kMeteredShowToggle)) updater.AddSearchTags(GetCellularMeteredSearchConcepts()); + + if (base::FeatureList::IsEnabled( + chromeos::features::kUpdatedCellularActivationUi)) { + updater.AddSearchTags(GetCellularSetupSearchConcepts()); + } break; case NetworkType::kTether: diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/languages_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/languages_section.cc index 78321bd8c64..49c7f9129b0 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/languages_section.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/languages_section.cc @@ -25,7 +25,7 @@ namespace chromeos { namespace settings { namespace { -const std::vector<SearchConcept>& GetLanguagesSearchConcepts() { +const std::vector<SearchConcept>& GetLanguagesSearchConceptsV1() { static const base::NoDestructor<std::vector<SearchConcept>> tags({ {IDS_OS_SETTINGS_TAG_LANGUAGES_INPUT, mojom::kLanguagesAndInputDetailsSubpagePath, @@ -57,9 +57,76 @@ const std::vector<SearchConcept>& GetLanguagesSearchConcepts() { return *tags; } +const std::vector<SearchConcept>& GetLanguagesPageSearchConceptsV2() { + static const base::NoDestructor<std::vector<SearchConcept>> tags({ + {IDS_OS_SETTINGS_TAG_LANGUAGES, + mojom::kLanguagesSubpagePath, + mojom::SearchResultIcon::kGlobe, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSubpage, + {.subpage = mojom::Subpage::kLanguages}}, + {IDS_OS_SETTINGS_TAG_LANGUAGES_CHANGE_SYSTEM_LANGUAGE, + mojom::kLanguagesSubpagePath, + mojom::SearchResultIcon::kGlobe, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSetting, + {.setting = mojom::Setting::kChangeSystemLanguage}}, + {IDS_OS_SETTINGS_TAG_LANGUAGES_INPUT_ADD_LANGUAGE, + mojom::kLanguagesSubpagePath, + mojom::SearchResultIcon::kGlobe, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSetting, + {.setting = mojom::Setting::kAddLanguage}}, + {IDS_OS_SETTINGS_TAG_LANGUAGES_OFFER_TRANSLATION, + mojom::kLanguagesSubpagePath, + mojom::SearchResultIcon::kGlobe, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSetting, + {.setting = mojom::Setting::kOfferTranslation}}, + }); + return *tags; +} + +const std::vector<SearchConcept>& GetInputPageSearchConceptsV2() { + static const base::NoDestructor<std::vector<SearchConcept>> tags({ + {IDS_OS_SETTINGS_TAG_INPUT, + mojom::kInputSubpagePath, + mojom::SearchResultIcon::kGlobe, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSubpage, + {.subpage = mojom::Subpage::kInput}}, + {IDS_OS_SETTINGS_TAG_LANGUAGES_INPUT_INPUT_OPTIONS_SHELF, + mojom::kInputSubpagePath, + mojom::SearchResultIcon::kGlobe, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSetting, + {.setting = mojom::Setting::kShowInputOptionsInShelf}, + {IDS_OS_SETTINGS_TAG_LANGUAGES_INPUT_INPUT_OPTIONS_SHELF_ALT1, + SearchConcept::kAltTagEnd}}, + {IDS_OS_SETTINGS_TAG_LANGUAGES_ADD_INPUT_METHOD, + mojom::kInputSubpagePath, + mojom::SearchResultIcon::kGlobe, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSetting, + {.setting = mojom::Setting::kAddInputMethod}}, + {IDS_OS_SETTINGS_TAG_LANGUAGES_SPELL_CHECK, + mojom::kInputSubpagePath, + mojom::SearchResultIcon::kGlobe, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSetting, + {.setting = mojom::Setting::kSpellCheck}}, + }); + return *tags; +} + +bool IsLanguageSettingsV2Enabled() { + return base::FeatureList::IsEnabled( + ::chromeos::features::kLanguageSettingsUpdate); +} + const std::vector<SearchConcept>& GetSmartInputsSearchConcepts() { static const base::NoDestructor<std::vector<SearchConcept>> tags({ - {IDS_OS_SETTINGS_TAG_LANGUAGES_SMART_INPUTS, + {IDS_OS_SETTINGS_TAG_LANGUAGES_SUGGESTIONS, mojom::kSmartInputsSubpagePath, mojom::SearchResultIcon::kGlobe, mojom::SearchResultDefaultRank::kMedium, @@ -99,22 +166,22 @@ bool IsAssistivePersonalInfoAllowed() { ::chromeos::features::kAssistPersonalInfo); } +// TODO(crbug/1113611): As Smart Inputs page is renamed to Suggestions. +// All related strings, function names and filenames should be renamed as well. void AddSmartInputsStrings(content::WebUIDataSource* html_source, bool is_emoji_suggestion_allowed) { static constexpr webui::LocalizedString kLocalizedStrings[] = { - {"smartInputsTitle", IDS_SETTINGS_SMART_INPUTS_TITLE}, + {"smartInputsTitle", IDS_SETTINGS_SUGGESTIONS_TITLE}, {"personalInfoSuggestionTitle", - IDS_SETTINGS_SMART_INPUTS_PERSONAL_INFO_TITLE}, + IDS_SETTINGS_SUGGESTIONS_PERSONAL_INFO_TITLE}, + {"personalInfoSuggestionHelpTooltip", + IDS_SETTINGS_SUGGESTIONS_PERSONAL_INFO_HELP_TOOLTIP}, {"personalInfoSuggestionDescription", - IDS_SETTINGS_SMART_INPUTS_PERSONAL_INFO_DESCRIPTION}, - {"showPersonalInfoSuggestion", - IDS_SETTINGS_SMART_INPUTS_SHOW_PERSONAL_INFO}, - {"managePersonalInfo", IDS_SETTINGS_SMART_INPUTS_MANAGE_PERSONAL_INFO}, - {"emojiSuggestionTitle", - IDS_SETTINGS_SMART_INPUTS_EMOJI_SUGGESTION_TITLE}, + IDS_SETTINGS_SUGGESTIONS_PERSONAL_INFO_DESCRIPTION}, + {"managePersonalInfo", IDS_SETTINGS_SUGGESTIONS_MANAGE_PERSONAL_INFO}, + {"emojiSuggestionTitle", IDS_SETTINGS_SUGGESTIONS_EMOJI_SUGGESTION_TITLE}, {"emojiSuggestionDescription", - IDS_SETTINGS_SMART_INPUTS_EMOJI_SUGGESTION_DESCRIPTION}, - {"showEmojiSuggestion", IDS_SETTINGS_SMART_INPUTS_SHOW_EMOJI_SUGGESTION}, + IDS_SETTINGS_SUGGESTIONS_EMOJI_SUGGESTION_DESCRIPTION}, }; AddLocalizedStringsBulk(html_source, kLocalizedStrings); @@ -177,13 +244,58 @@ void AddInputMethodOptionsStrings(content::WebUIDataSource* html_source) { AddLocalizedStringsBulk(html_source, kLocalizedStrings); } +void AddLanguagesPageStringsV2(content::WebUIDataSource* html_source) { + static constexpr webui::LocalizedString kLocalizedStrings[] = { + {"systemLanguageTitle", IDS_OS_SETTINGS_LANGUAGES_SYSTEM_LANGUAGE_TITLE}, + {"systemLanguageDescription", + IDS_OS_SETTINGS_LANGUAGES_SYSTEM_LANGUAGE_DESCRIPTION}, + {"changeSystemLanguageLabel", + IDS_OS_SETTINGS_LANGUAGES_CHANGE_SYSTEM_LANGUAGE_BUTTON_LABEL}, + {"changeSystemLanguageButtonDescription", + IDS_OS_SETTINGS_LANGUAGES_CHANGE_SYSTEM_LANGUAGE_BUTTON_DESCRIPTION}, + {"languagesPreferenceTitle", + IDS_OS_SETTINGS_LANGUAGES_LANGUAGES_PREFERENCE_TITLE}, + {"languagesPreferenceDescription", + IDS_OS_SETTINGS_LANGUAGES_LANGUAGES_PREFERENCE_DESCRIPTION}, + {"offerTranslationLabel", + IDS_OS_SETTINGS_LANGUAGES_OFFER_TRANSLATION_LABEL}, + {"offerTranslationSublabel", + IDS_OS_SETTINGS_LANGUAGES_OFFER_TRANSLATION_SUBLABEL}, + }; + AddLocalizedStringsBulk(html_source, kLocalizedStrings); + + html_source->AddString( + "languagesPreferenceDescription", + l10n_util::GetStringFUTF16( + IDS_OS_SETTINGS_LANGUAGES_LANGUAGES_PREFERENCE_DESCRIPTION, + base::ASCIIToUTF16(chrome::kLanguageSettingsLearnMoreUrl))); +} + +void AddInputPageStringsV2(content::WebUIDataSource* html_source) { + static constexpr webui::LocalizedString kLocalizedStrings[] = { + {"inputMethodListTitle", + IDS_OS_SETTINGS_LANGUAGES_INPUT_METHOD_LIST_TITLE}, + {"openOptionsPage", IDS_OS_SETTINGS_LANGUAGES_OPEN_OPTIONS_PAGE_LABEL}, + {"addInputMethodLabel", IDS_OS_SETTINGS_LANGUAGES_ADD_INPUT_METHOD_LABEL}, + {"spellCheckTitle", IDS_OS_SETTINGS_LANGUAGES_SPELL_CHECK_TITLE}, + {"spellCheckDisabledReason", + IDS_OS_SETTINGS_LANGUAGES_SPELL_CHECK_DISABLED_REASON}, + }; + AddLocalizedStringsBulk(html_source, kLocalizedStrings); +} + } // namespace LanguagesSection::LanguagesSection(Profile* profile, SearchTagRegistry* search_tag_registry) : OsSettingsSection(profile, search_tag_registry) { SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate(); - updater.AddSearchTags(GetLanguagesSearchConcepts()); + if (IsLanguageSettingsV2Enabled()) { + updater.AddSearchTags(GetLanguagesPageSearchConceptsV2()); + updater.AddSearchTags(GetInputPageSearchConceptsV2()); + } else { + updater.AddSearchTags(GetLanguagesSearchConceptsV1()); + } if (IsAssistivePersonalInfoAllowed() || IsEmojiSuggestionAllowed()) { updater.AddSearchTags(GetSmartInputsSearchConcepts()); @@ -201,6 +313,9 @@ void LanguagesSection::AddLoadTimeData(content::WebUIDataSource* html_source) { {"orderLanguagesInstructions", IDS_SETTINGS_LANGUAGES_LANGUAGES_LIST_ORDERING_INSTRUCTIONS}, {"osLanguagesPageTitle", IDS_OS_SETTINGS_LANGUAGES_AND_INPUT_PAGE_TITLE}, + {"languagesPageTitle", IDS_OS_SETTINGS_LANGUAGES_LANGUAGES_PAGE_TITLE}, + {"inputPageTitle", IDS_OS_SETTINGS_LANGUAGES_INPUT_PAGE_TITLE}, + {"osLanguagesPageTitle", IDS_OS_SETTINGS_LANGUAGES_AND_INPUT_PAGE_TITLE}, {"osLanguagesListTitle", IDS_OS_SETTINGS_LANGUAGES_LIST_TITLE}, {"inputMethodsListTitle", IDS_SETTINGS_LANGUAGES_INPUT_METHODS_LIST_TITLE}, @@ -231,6 +346,8 @@ void LanguagesSection::AddLoadTimeData(content::WebUIDataSource* html_source) { AddLocalizedStringsBulk(html_source, kLocalizedStrings); AddSmartInputsStrings(html_source, IsEmojiSuggestionAllowed()); AddInputMethodOptionsStrings(html_source); + AddLanguagesPageStringsV2(html_source); + AddInputPageStringsV2(html_source); html_source->AddString( "languagesLearnMoreURL", @@ -238,6 +355,8 @@ void LanguagesSection::AddLoadTimeData(content::WebUIDataSource* html_source) { html_source->AddBoolean("imeOptionsInSettings", base::FeatureList::IsEnabled( ::chromeos::features::kImeOptionsInSettings)); + html_source->AddBoolean("enableLanguageSettingsV2", + IsLanguageSettingsV2Enabled()); } void LanguagesSection::AddHandlers(content::WebUI* web_ui) { @@ -269,18 +388,51 @@ bool LanguagesSection::IsEmojiSuggestionAllowed() const { } void LanguagesSection::RegisterHierarchy(HierarchyGenerator* generator) const { + // Languages. + generator->RegisterTopLevelSubpage( + IDS_OS_SETTINGS_LANGUAGES_LANGUAGES_PAGE_TITLE, + mojom::Subpage::kLanguages, mojom::SearchResultIcon::kGlobe, + mojom::SearchResultDefaultRank::kMedium, mojom::kLanguagesSubpagePath); + static constexpr mojom::Setting kLanguagesPageSettings[] = { + mojom::Setting::kChangeSystemLanguage, + mojom::Setting::kOfferTranslation, + }; + RegisterNestedSettingBulk(mojom::Subpage::kLanguages, kLanguagesPageSettings, + generator); + + // Input. + generator->RegisterTopLevelSubpage( + IDS_OS_SETTINGS_LANGUAGES_INPUT_PAGE_TITLE, mojom::Subpage::kInput, + mojom::SearchResultIcon::kGlobe, mojom::SearchResultDefaultRank::kMedium, + mojom::kInputSubpagePath); + static constexpr mojom::Setting kInputPageSettings[] = { + mojom::Setting::kAddInputMethod, + mojom::Setting::kSpellCheck, + }; + RegisterNestedSettingBulk(mojom::Subpage::kInput, kInputPageSettings, + generator); + // Languages and input details. generator->RegisterTopLevelSubpage( IDS_OS_SETTINGS_LANGUAGES_AND_INPUT_PAGE_TITLE, mojom::Subpage::kLanguagesAndInputDetails, mojom::SearchResultIcon::kGlobe, mojom::SearchResultDefaultRank::kMedium, mojom::kLanguagesAndInputDetailsSubpagePath); - static constexpr mojom::Setting kLanguagesAndInputDetailsSettings[] = { - mojom::Setting::kAddLanguage, - mojom::Setting::kShowInputOptionsInShelf, - }; - RegisterNestedSettingBulk(mojom::Subpage::kLanguagesAndInputDetails, - kLanguagesAndInputDetailsSettings, generator); + + // Shared settings between existing pages and the updated pages. + if (IsLanguageSettingsV2Enabled()) { + generator->RegisterNestedSetting(mojom::Setting::kAddLanguage, + mojom::Subpage::kLanguages); + generator->RegisterNestedSetting(mojom::Setting::kShowInputOptionsInShelf, + mojom::Subpage::kInput); + } else { + static constexpr mojom::Setting kLanguagesAndInputDetailsSettings[] = { + mojom::Setting::kAddLanguage, + mojom::Setting::kShowInputOptionsInShelf, + }; + RegisterNestedSettingBulk(mojom::Subpage::kLanguagesAndInputDetails, + kLanguagesAndInputDetailsSettings, generator); + } // Manage input methods. generator->RegisterNestedSubpage( @@ -300,7 +452,7 @@ void LanguagesSection::RegisterHierarchy(HierarchyGenerator* generator) const { // Smart inputs. generator->RegisterTopLevelSubpage( - IDS_SETTINGS_SMART_INPUTS_TITLE, mojom::Subpage::kSmartInputs, + IDS_SETTINGS_SUGGESTIONS_TITLE, mojom::Subpage::kSmartInputs, mojom::SearchResultIcon::kGlobe, mojom::SearchResultDefaultRank::kMedium, mojom::kSmartInputsSubpagePath); static constexpr mojom::Setting kSmartInputsFeaturesSettings[] = { diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/main_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/main_section.cc index 0868f9c866a..06116213b78 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/main_section.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/main_section.cc @@ -6,8 +6,14 @@ #include "ash/public/cpp/resources/grit/ash_public_unscaled_resources.h" #include "base/feature_list.h" +#include "base/i18n/message_formatter.h" +#include "base/i18n/number_formatting.h" #include "base/no_destructor.h" #include "base/strings/utf_string_conversions.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/browser_process_platform_part.h" +#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" +#include "chrome/browser/chromeos/policy/minimum_version_policy_handler.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/metrics_handler.h" @@ -17,6 +23,7 @@ #include "chrome/browser/ui/webui/webui_util.h" #include "chrome/browser/web_applications/system_web_app_manager.h" #include "chrome/common/url_constants.h" +#include "chrome/common/webui_url_constants.h" #include "chrome/grit/browser_resources.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" @@ -28,6 +35,7 @@ #include "content/public/browser/web_ui_data_source.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/webui/web_ui_util.h" +#include "ui/chromeos/devicetype_utils.h" namespace chromeos { namespace settings { @@ -39,9 +47,7 @@ void AddSearchInSettingsStrings(content::WebUIDataSource* html_source) { {"searchNoResults", IDS_SEARCH_NO_RESULTS}, {"searchResults", IDS_SEARCH_RESULTS}, {"searchResultSelected", IDS_OS_SEARCH_RESULT_ROW_A11Y_RESULT_SELECTED}, - // 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}, + {"clearSearch", IDS_CLEAR_SEARCH}, }; AddLocalizedStringsBulk(html_source, kLocalizedStrings); @@ -56,6 +62,47 @@ void AddSearchInSettingsStrings(content::WebUIDataSource* html_source) { base::FeatureList::IsEnabled(::chromeos::features::kNewOsSettingsSearch)); } +void AddUpdateRequiredEolStrings(content::WebUIDataSource* html_source) { + policy::BrowserPolicyConnectorChromeOS* connector = + g_browser_process->platform_part()->browser_policy_connector_chromeos(); + policy::MinimumVersionPolicyHandler* handler = + connector->GetMinimumVersionPolicyHandler(); + bool device_managed = connector->IsEnterpriseManaged(); + + // |eol_return_banner_text| contains the update required end of life banner + // text which is left empty when the banner should not be shown. + base::string16 eol_return_banner_text; + if (device_managed && handler->ShouldShowUpdateRequiredEolBanner()) { + base::Optional<int> days = handler->GetTimeRemainingInDays(); + // We only need to show the banner if less than equal to one week remains to + // reach the update required deadline. + if (days && days.value() <= 7) { + // |days| could have value equal to zero if we are very close to the + // deadline. + int days_remaining = days.value() ? days.value() : 1; + base::string16 domain_name = + base::UTF8ToUTF16(connector->GetEnterpriseDisplayDomain()); + base::string16 link_url = + base::UTF8ToUTF16(chrome::kChromeUIManagementURL); + if (days_remaining == 7) { + eol_return_banner_text = l10n_util::GetStringFUTF16( + IDS_SETTINGS_UPDATE_REQUIRED_EOL_BANNER_ONE_WEEK, domain_name, + ui::GetChromeOSDeviceName(), link_url); + } else { + eol_return_banner_text = + base::i18n::MessageFormatter::FormatWithNumberedArgs( + l10n_util::GetStringUTF16( + IDS_SETTINGS_UPDATE_REQUIRED_EOL_BANNER_DAYS), + days_remaining, + base::UTF8ToUTF16(connector->GetEnterpriseDisplayDomain()), + ui::GetChromeOSDeviceName(), + base::UTF8ToUTF16(chrome::kChromeUIManagementURL)); + } + } + } + html_source->AddString("updateRequiredEolBannerText", eol_return_banner_text); +} + } // namespace MainSection::MainSection(Profile* profile, @@ -123,6 +170,9 @@ void MainSection::AddLoadTimeData(content::WebUIDataSource* html_source) { user_manager::UserManager::Get()->IsLoggedInAsAnyKioskApp()); html_source->AddBoolean("isSupervised", profile()->IsSupervised()); + html_source->AddBoolean("isDeepLinkingEnabled", + chromeos::features::IsDeepLinkingEnabled()); + // Add the System Web App resources for Settings. if (web_app::SystemWebAppManager::IsEnabled()) { html_source->AddResourcePath("icon-192.png", IDR_SETTINGS_LOGO_192); @@ -147,6 +197,7 @@ void MainSection::AddLoadTimeData(content::WebUIDataSource* html_source) { AddSearchInSettingsStrings(html_source); AddChromeOSUserStrings(html_source); + AddUpdateRequiredEolStrings(html_source); policy_indicator::AddLocalizedStrings(html_source); } diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.cc index 19977ff73a7..b359de47d5e 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.cc @@ -16,7 +16,9 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.h" #include "chromeos/components/multidevice/logging/logging.h" +#include "chromeos/components/phonehub/notification_access_manager.h" #include "chromeos/components/proximity_auth/proximity_auth_pref_names.h" +#include "chromeos/constants/chromeos_features.h" #include "chromeos/services/multidevice_setup/public/cpp/prefs.h" #include "components/content_settings/core/common/content_settings_pattern.h" #include "components/prefs/pref_service.h" @@ -34,6 +36,13 @@ const char kPageContentDataHostDeviceNameKey[] = "hostDeviceName"; const char kPageContentDataBetterTogetherStateKey[] = "betterTogetherState"; const char kPageContentDataInstantTetheringStateKey[] = "instantTetheringState"; const char kPageContentDataMessagesStateKey[] = "messagesState"; +const char kPageContentDataPhoneHubStateKey[] = "phoneHubState"; +const char kPageContentDataPhoneHubNotificationsStateKey[] = + "phoneHubNotificationsState"; +const char kPageContentDataPhoneHubNotificationBadgeStateKey[] = + "phoneHubNotificationBadgeState"; +const char kPageContentDataPhoneHubTaskContinuationStateKey[] = + "phoneHubTaskContinuationState"; const char kPageContentDataSmartLockStateKey[] = "smartLockState"; const char kIsAndroidSmsPairingComplete[] = "isAndroidSmsPairingComplete"; @@ -53,11 +62,13 @@ void OnRetrySetHostNowResult(bool success) { MultideviceHandler::MultideviceHandler( PrefService* prefs, multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client, + phonehub::NotificationAccessManager* notification_access_manager, multidevice_setup::AndroidSmsPairingStateTracker* android_sms_pairing_state_tracker, android_sms::AndroidSmsAppManager* android_sms_app_manager) : prefs_(prefs), multidevice_setup_client_(multidevice_setup_client), + notification_access_manager_(notification_access_manager), android_sms_pairing_state_tracker_(android_sms_pairing_state_tracker), android_sms_app_manager_(android_sms_app_manager), multidevice_setup_observer_(this), @@ -109,6 +120,14 @@ void MultideviceHandler::RegisterMessages() { "getAndroidSmsInfo", base::BindRepeating(&MultideviceHandler::HandleGetAndroidSmsInfo, base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "attemptNotificationSetup", + base::BindRepeating(&MultideviceHandler::HandleAttemptNotificationSetup, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "cancelNotificationSetup", + base::BindRepeating(&MultideviceHandler::HandleCancelNotificationSetup, + base::Unretained(this))); } void MultideviceHandler::OnJavascriptAllowed() { @@ -141,6 +160,9 @@ void MultideviceHandler::OnJavascriptDisallowed() { if (multidevice_setup_client_) multidevice_setup_observer_.Remove(multidevice_setup_client_); + if (notification_access_manager_) + notification_access_operation_.reset(); + if (android_sms_pairing_state_tracker_) { android_sms_pairing_state_tracker_observer_.Remove( android_sms_pairing_state_tracker_); @@ -330,7 +352,6 @@ MultideviceHandler::GenerateAndroidSmsInfo() { } void MultideviceHandler::HandleGetAndroidSmsInfo(const base::ListValue* args) { - AllowJavascript(); CHECK_EQ(1U, args->GetSize()); const base::Value* callback_id; CHECK(args->Get(0, &callback_id)); @@ -338,6 +359,39 @@ void MultideviceHandler::HandleGetAndroidSmsInfo(const base::ListValue* args) { ResolveJavascriptCallback(*callback_id, *GenerateAndroidSmsInfo()); } +void MultideviceHandler::HandleAttemptNotificationSetup( + const base::ListValue* args) { + DCHECK(features::IsPhoneHubEnabled()); + DCHECK(!notification_access_operation_); + + if (notification_access_manager_->HasAccessBeenGranted()) { + PA_LOG(WARNING) << "Phonehub notification access has already been granted, " + "returning early."; + return; + } + + notification_access_operation_ = + notification_access_manager_->AttemptNotificationSetup(/*delegate=*/this); + DCHECK(notification_access_operation_); +} + +void MultideviceHandler::HandleCancelNotificationSetup( + const base::ListValue* args) { + DCHECK(features::IsPhoneHubEnabled()); + DCHECK(notification_access_operation_); + + notification_access_operation_.reset(); +} + +void MultideviceHandler::OnStatusChange( + phonehub::NotificationAccessSetupOperation::Status new_status) { + FireWebUIListener("notification-access-setup-operation-status-changed", + base::Value(static_cast<int32_t>(new_status))); + + if (phonehub::NotificationAccessSetupOperation::IsFinalStatus(new_status)) + notification_access_operation_.reset(); +} + void MultideviceHandler::OnSetFeatureStateEnabledResult( const std::string& js_callback_id, bool success) { @@ -374,6 +428,25 @@ MultideviceHandler::GeneratePageContentDataDictionary() { kPageContentDataSmartLockStateKey, static_cast<int32_t>( feature_states[multidevice_setup::mojom::Feature::kSmartLock])); + page_content_dictionary->SetInteger( + kPageContentDataPhoneHubStateKey, + static_cast<int32_t>( + feature_states[multidevice_setup::mojom::Feature::kPhoneHub])); + page_content_dictionary->SetInteger( + kPageContentDataPhoneHubNotificationsStateKey, + static_cast<int32_t>( + feature_states + [multidevice_setup::mojom::Feature::kPhoneHubNotifications])); + page_content_dictionary->SetInteger( + kPageContentDataPhoneHubNotificationBadgeStateKey, + static_cast<int32_t>( + feature_states + [multidevice_setup::mojom::Feature::kPhoneHubNotificationBadge])); + page_content_dictionary->SetInteger( + kPageContentDataPhoneHubTaskContinuationStateKey, + static_cast<int32_t>( + feature_states + [multidevice_setup::mojom::Feature::kPhoneHubTaskContinuation])); if (host_status_with_device.second) { page_content_dictionary->SetString(kPageContentDataHostDeviceNameKey, 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 a103760bd1e..56fdd03db7e 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h @@ -12,6 +12,7 @@ #include "chrome/browser/chromeos/android_sms/android_sms_service_factory.h" #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" #include "chromeos/components/multidevice/remote_device_ref.h" +#include "chromeos/components/phonehub/notification_access_setup_operation.h" #include "chromeos/services/multidevice_setup/public/cpp/multidevice_setup_client.h" #include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom-forward.h" #include "components/prefs/pref_change_registrar.h" @@ -24,6 +25,10 @@ class DictionaryValue; namespace chromeos { +namespace phonehub { +class NotificationAccessManager; +} // namespace phonehub + namespace settings { // Chrome "Multidevice" (a.k.a. "Connected Devices") settings page UI handler. @@ -31,11 +36,13 @@ class MultideviceHandler : public ::settings::SettingsPageUIHandler, public multidevice_setup::MultiDeviceSetupClient::Observer, public multidevice_setup::AndroidSmsPairingStateTracker::Observer, - public android_sms::AndroidSmsAppManager::Observer { + public android_sms::AndroidSmsAppManager::Observer, + public phonehub::NotificationAccessSetupOperation::Delegate { public: MultideviceHandler( PrefService* prefs, multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client, + phonehub::NotificationAccessManager* notification_access_manager, multidevice_setup::AndroidSmsPairingStateTracker* android_sms_pairing_state_tracker, android_sms::AndroidSmsAppManager* android_sms_app_manager); @@ -58,6 +65,10 @@ class MultideviceHandler const multidevice_setup::MultiDeviceSetupClient::FeatureStatesMap& feature_states_map) override; + // NotificationAccessSetupOperation::Delegate: + void OnStatusChange( + phonehub::NotificationAccessSetupOperation::Status new_status) override; + // multidevice_setup::AndroidSmsPairingStateTracker::Observer: void OnPairingStateChanged() override; @@ -78,6 +89,8 @@ class MultideviceHandler void HandleSetSmartLockSignInEnabled(const base::ListValue* args); void HandleGetSmartLockSignInAllowed(const base::ListValue* args); void HandleGetAndroidSmsInfo(const base::ListValue* args); + void HandleAttemptNotificationSetup(const base::ListValue* args); + void HandleCancelNotificationSetup(const base::ListValue* args); void OnSetFeatureStateEnabledResult(const std::string& js_callback_id, bool success); @@ -110,6 +123,11 @@ class MultideviceHandler GetFeatureStatesMap(); multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client_; + + phonehub::NotificationAccessManager* notification_access_manager_; + std::unique_ptr<phonehub::NotificationAccessSetupOperation> + notification_access_operation_; + multidevice_setup::AndroidSmsPairingStateTracker* android_sms_pairing_state_tracker_; android_sms::AndroidSmsAppManager* android_sms_app_manager_; diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_handler_unittest.cc index e0efafd8f75..96a3b826a85 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_handler_unittest.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_handler_unittest.cc @@ -7,9 +7,12 @@ #include <memory> #include "base/macros.h" +#include "base/test/scoped_feature_list.h" #include "chrome/browser/chromeos/android_sms/android_sms_urls.h" #include "chrome/browser/chromeos/android_sms/fake_android_sms_app_manager.h" #include "chromeos/components/multidevice/remote_device_test_util.h" +#include "chromeos/components/phonehub/fake_notification_access_manager.h" +#include "chromeos/constants/chromeos_features.h" #include "chromeos/services/multidevice_setup/public/cpp/fake_android_sms_pairing_state_tracker.h" #include "chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup_client.h" #include "components/content_settings/core/common/content_settings_pattern.h" @@ -28,11 +31,13 @@ class TestMultideviceHandler : public MultideviceHandler { TestMultideviceHandler( PrefService* prefs, multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client, + phonehub::NotificationAccessManager* notification_access_manager, multidevice_setup::AndroidSmsPairingStateTracker* android_sms_pairing_state_tracker, android_sms::AndroidSmsAppManager* android_sms_app_manager) : MultideviceHandler(prefs, multidevice_setup_client, + notification_access_manager, android_sms_pairing_state_tracker, android_sms_app_manager) {} ~TestMultideviceHandler() override = default; @@ -53,6 +58,14 @@ GenerateDefaultFeatureStatesMap() { {multidevice_setup::mojom::Feature::kMessages, multidevice_setup::mojom::FeatureState::kUnavailableNoVerifiedHost}, {multidevice_setup::mojom::Feature::kSmartLock, + multidevice_setup::mojom::FeatureState::kUnavailableNoVerifiedHost}, + {multidevice_setup::mojom::Feature::kPhoneHub, + multidevice_setup::mojom::FeatureState::kUnavailableNoVerifiedHost}, + {multidevice_setup::mojom::Feature::kPhoneHubNotifications, + multidevice_setup::mojom::FeatureState::kUnavailableNoVerifiedHost}, + {multidevice_setup::mojom::Feature::kPhoneHubNotificationBadge, + multidevice_setup::mojom::FeatureState::kUnavailableNoVerifiedHost}, + {multidevice_setup::mojom::Feature::kPhoneHubTaskContinuation, multidevice_setup::mojom::FeatureState::kUnavailableNoVerifiedHost}}; } @@ -94,6 +107,32 @@ void VerifyPageContentDict( it = feature_states_map.find(multidevice_setup::mojom::Feature::kSmartLock); EXPECT_EQ(static_cast<int>(it->second), smart_lock_state); + int phone_hub_state; + EXPECT_TRUE(page_content_dict->GetInteger("phoneHubState", &phone_hub_state)); + it = feature_states_map.find(multidevice_setup::mojom::Feature::kPhoneHub); + EXPECT_EQ(static_cast<int>(it->second), phone_hub_state); + + int phone_hub_notifications_state; + EXPECT_TRUE(page_content_dict->GetInteger("phoneHubNotificationsState", + &phone_hub_notifications_state)); + it = feature_states_map.find( + multidevice_setup::mojom::Feature::kPhoneHubNotifications); + EXPECT_EQ(static_cast<int>(it->second), phone_hub_notifications_state); + + int phone_hub_notification_badge_state; + EXPECT_TRUE(page_content_dict->GetInteger( + "phoneHubNotificationBadgeState", &phone_hub_notification_badge_state)); + it = feature_states_map.find( + multidevice_setup::mojom::Feature::kPhoneHubNotificationBadge); + EXPECT_EQ(static_cast<int>(it->second), phone_hub_notification_badge_state); + + int phone_hub_task_continuation_state; + EXPECT_TRUE(page_content_dict->GetInteger( + "phoneHubTaskContinuationState", &phone_hub_task_continuation_state)); + it = feature_states_map.find( + multidevice_setup::mojom::Feature::kPhoneHubTaskContinuation); + EXPECT_EQ(static_cast<int>(it->second), phone_hub_task_continuation_state); + std::string host_device_name; if (expected_host_device) { EXPECT_TRUE( @@ -119,6 +158,9 @@ class MultideviceHandlerTest : public testing::Test { fake_multidevice_setup_client_ = std::make_unique<multidevice_setup::FakeMultiDeviceSetupClient>(); + fake_notification_access_manager_ = + std::make_unique<phonehub::FakeNotificationAccessManager>( + /*has_access_been_granted=*/false); fake_android_sms_pairing_state_tracker_ = std::make_unique< multidevice_setup::FakeAndroidSmsPairingStateTracker>(); fake_android_sms_app_manager_ = @@ -128,11 +170,14 @@ class MultideviceHandlerTest : public testing::Test { handler_ = std::make_unique<TestMultideviceHandler>( prefs_.get(), fake_multidevice_setup_client_.get(), + fake_notification_access_manager_.get(), fake_android_sms_pairing_state_tracker_.get(), fake_android_sms_app_manager_.get()); handler_->set_web_ui(test_web_ui_.get()); handler_->RegisterMessages(); handler_->AllowJavascript(); + + scoped_feature_list_.InitWithFeatures({chromeos::features::kPhoneHub}, {}); } void CallGetPageContentData() { @@ -183,6 +228,20 @@ class MultideviceHandlerTest : public testing::Test { call_data.arg3()->FindKey("enabled")->GetBool()); } + void CallAttemptNotificationSetup(bool has_access_been_granted) { + fake_notification_access_manager()->SetHasAccessBeenGranted( + has_access_been_granted); + base::ListValue empty_args; + test_web_ui()->HandleReceivedMessage("attemptNotificationSetup", + &empty_args); + } + + void CallCancelNotificationSetup() { + base::ListValue empty_args; + test_web_ui()->HandleReceivedMessage("cancelNotificationSetup", + &empty_args); + } + void SimulateHostStatusUpdate( multidevice_setup::mojom::HostStatus host_status, const base::Optional<multidevice::RemoteDeviceRef>& host_device) { @@ -291,6 +350,31 @@ class MultideviceHandlerTest : public testing::Test { return fake_android_sms_app_manager_.get(); } + phonehub::FakeNotificationAccessManager* fake_notification_access_manager() { + return fake_notification_access_manager_.get(); + } + + void SimulateNotificationOptInStatusChange( + phonehub::NotificationAccessSetupOperation::Status status) { + size_t call_data_count_before_call = test_web_ui()->call_data().size(); + + fake_notification_access_manager()->SetNotificationSetupOperationStatus( + status); + + EXPECT_EQ(call_data_count_before_call + 1u, + test_web_ui()->call_data().size()); + const content::TestWebUI::CallData& call_data = + CallDataAtIndex(call_data_count_before_call); + EXPECT_EQ("cr.webUIListenerCallback", call_data.function_name()); + EXPECT_EQ("notification-access-setup-operation-status-changed", + call_data.arg1()->GetString()); + EXPECT_EQ(call_data.arg2()->GetInt(), static_cast<int32_t>(status)); + } + + bool IsNotificationAccessSetupOperationInProgress() { + return fake_notification_access_manager()->IsSetupOperationInProgress(); + } + const multidevice::RemoteDeviceRef test_device_; private: @@ -305,6 +389,8 @@ class MultideviceHandlerTest : public testing::Test { std::unique_ptr<content::TestWebUI> test_web_ui_; std::unique_ptr<multidevice_setup::FakeMultiDeviceSetupClient> fake_multidevice_setup_client_; + std::unique_ptr<phonehub::FakeNotificationAccessManager> + fake_notification_access_manager_; std::unique_ptr<multidevice_setup::FakeAndroidSmsPairingStateTracker> fake_android_sms_pairing_state_tracker_; @@ -317,9 +403,60 @@ class MultideviceHandlerTest : public testing::Test { std::unique_ptr<TestMultideviceHandler> handler_; + base::test::ScopedFeatureList scoped_feature_list_; + DISALLOW_COPY_AND_ASSIGN(MultideviceHandlerTest); }; +TEST_F(MultideviceHandlerTest, NotificationSetupFlow) { + using Status = phonehub::NotificationAccessSetupOperation::Status; + + // Simulate success flow. + CallAttemptNotificationSetup(/*has_access_been_granted=*/false); + EXPECT_TRUE(IsNotificationAccessSetupOperationInProgress()); + + SimulateNotificationOptInStatusChange(Status::kConnecting); + EXPECT_TRUE(IsNotificationAccessSetupOperationInProgress()); + + SimulateNotificationOptInStatusChange( + Status::kSentMessageToPhoneAndWaitingForResponse); + EXPECT_TRUE(IsNotificationAccessSetupOperationInProgress()); + + SimulateNotificationOptInStatusChange(Status::kCompletedSuccessfully); + EXPECT_FALSE(IsNotificationAccessSetupOperationInProgress()); + + // Simulate cancel flow. + CallAttemptNotificationSetup(/*has_access_been_granted=*/false); + EXPECT_TRUE(IsNotificationAccessSetupOperationInProgress()); + + CallCancelNotificationSetup(); + EXPECT_FALSE(IsNotificationAccessSetupOperationInProgress()); + + // Simulate failure via time-out flow. + CallAttemptNotificationSetup(/*has_access_been_granted=*/false); + EXPECT_TRUE(IsNotificationAccessSetupOperationInProgress()); + + SimulateNotificationOptInStatusChange(Status::kConnecting); + EXPECT_TRUE(IsNotificationAccessSetupOperationInProgress()); + + SimulateNotificationOptInStatusChange(Status::kTimedOutConnecting); + EXPECT_FALSE(IsNotificationAccessSetupOperationInProgress()); + + // Simulate failure via connected then disconnected flow. + CallAttemptNotificationSetup(/*has_access_been_granted=*/false); + EXPECT_TRUE(IsNotificationAccessSetupOperationInProgress()); + + SimulateNotificationOptInStatusChange(Status::kConnecting); + EXPECT_TRUE(IsNotificationAccessSetupOperationInProgress()); + + SimulateNotificationOptInStatusChange(Status::kConnectionDisconnected); + EXPECT_FALSE(IsNotificationAccessSetupOperationInProgress()); + + // If access has already been granted, a setup operation should not occur. + CallAttemptNotificationSetup(/*has_access_been_granted=*/true); + EXPECT_FALSE(IsNotificationAccessSetupOperationInProgress()); +} + TEST_F(MultideviceHandlerTest, PageContentData) { CallGetPageContentData(); CallGetPageContentData(); diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_section.cc index da38e8b2896..ad527c32bea 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_section.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_section.cc @@ -9,7 +9,7 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/browser_features.h" #include "chrome/browser/chromeos/android_sms/android_sms_service.h" -#include "chrome/browser/nearby_sharing/nearby_sharing_prefs.h" +#include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" @@ -18,6 +18,7 @@ #include "chrome/common/url_constants.h" #include "chrome/common/webui_url_constants.h" #include "chrome/grit/generated_resources.h" +#include "chromeos/components/phonehub/phone_hub_manager.h" #include "chromeos/constants/chromeos_features.h" #include "chromeos/services/multidevice_setup/public/cpp/prefs.h" #include "chromeos/services/multidevice_setup/public/cpp/url_provider.h" @@ -34,43 +35,72 @@ namespace settings { namespace { const std::vector<SearchConcept>& GetMultiDeviceOptedInSearchConcepts() { - static const base::NoDestructor<std::vector<SearchConcept>> tags({ - {IDS_OS_SETTINGS_TAG_MULTIDEVICE_SMART_LOCK_OPTIONS, - mojom::kSmartLockSubpagePath, - mojom::SearchResultIcon::kLock, - mojom::SearchResultDefaultRank::kMedium, - mojom::SearchResultType::kSubpage, - {.subpage = mojom::Subpage::kSmartLock}}, - {IDS_OS_SETTINGS_TAG_MULTIDEVICE_FORGET, - mojom::kMultiDeviceFeaturesSubpagePath, - mojom::SearchResultIcon::kPhone, - mojom::SearchResultDefaultRank::kMedium, - mojom::SearchResultType::kSetting, - {.setting = mojom::Setting::kForgetPhone}, - {IDS_OS_SETTINGS_TAG_MULTIDEVICE_FORGET_ALT1, - SearchConcept::kAltTagEnd}}, - {IDS_OS_SETTINGS_TAG_MULTIDEVICE_MESSAGES, - mojom::kMultiDeviceFeaturesSubpagePath, - mojom::SearchResultIcon::kMessages, - mojom::SearchResultDefaultRank::kMedium, - mojom::SearchResultType::kSetting, - {.setting = mojom::Setting::kMessagesOnOff}, - {IDS_OS_SETTINGS_TAG_MULTIDEVICE_MESSAGES_ALT1, - SearchConcept::kAltTagEnd}}, - {IDS_OS_SETTINGS_TAG_MULTIDEVICE, - mojom::kMultiDeviceFeaturesSubpagePath, - mojom::SearchResultIcon::kPhone, - mojom::SearchResultDefaultRank::kMedium, - mojom::SearchResultType::kSubpage, - {.subpage = mojom::Subpage::kMultiDeviceFeatures}, - {IDS_OS_SETTINGS_TAG_MULTIDEVICE_ALT1, SearchConcept::kAltTagEnd}}, - {IDS_OS_SETTINGS_TAG_MULTIDEVICE_SMART_LOCK, - mojom::kMultiDeviceFeaturesSubpagePath, - mojom::SearchResultIcon::kLock, - mojom::SearchResultDefaultRank::kMedium, - mojom::SearchResultType::kSubpage, - {.subpage = mojom::Subpage::kSmartLock}}, - }); + static const base::NoDestructor<std::vector<SearchConcept>> tags( + {{IDS_OS_SETTINGS_TAG_MULTIDEVICE_SMART_LOCK_OPTIONS, + mojom::kSmartLockSubpagePath, + mojom::SearchResultIcon::kLock, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSubpage, + {.subpage = mojom::Subpage::kSmartLock}}, + {IDS_OS_SETTINGS_TAG_MULTIDEVICE_FORGET, + mojom::kMultiDeviceFeaturesSubpagePath, + mojom::SearchResultIcon::kPhone, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSetting, + {.setting = mojom::Setting::kForgetPhone}, + {IDS_OS_SETTINGS_TAG_MULTIDEVICE_FORGET_ALT1, + SearchConcept::kAltTagEnd}}, + {IDS_OS_SETTINGS_TAG_MULTIDEVICE_MESSAGES, + mojom::kMultiDeviceFeaturesSubpagePath, + mojom::SearchResultIcon::kMessages, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSetting, + {.setting = mojom::Setting::kMessagesOnOff}, + {IDS_OS_SETTINGS_TAG_MULTIDEVICE_MESSAGES_ALT1, + SearchConcept::kAltTagEnd}}, + {IDS_OS_SETTINGS_TAG_MULTIDEVICE, + mojom::kMultiDeviceFeaturesSubpagePath, + mojom::SearchResultIcon::kPhone, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSubpage, + {.subpage = mojom::Subpage::kMultiDeviceFeatures}, + {IDS_OS_SETTINGS_TAG_MULTIDEVICE_ALT1, SearchConcept::kAltTagEnd}}, + {IDS_OS_SETTINGS_TAG_MULTIDEVICE_SMART_LOCK, + mojom::kMultiDeviceFeaturesSubpagePath, + mojom::SearchResultIcon::kLock, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSubpage, + {.subpage = mojom::Subpage::kSmartLock}}}); + return *tags; +} + +const std::vector<SearchConcept>& +GetMultiDeviceOptedInPhoneHubSearchConcepts() { + static const base::NoDestructor<std::vector<SearchConcept>> tags( + {{IDS_OS_SETTINGS_TAG_MULTIDEVICE_PHONE_HUB, + mojom::kMultiDeviceFeaturesSubpagePath, + mojom::SearchResultIcon::kPhone, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSetting, + {.setting = mojom::Setting::kPhoneHubOnOff}}, + {IDS_OS_SETTINGS_TAG_MULTIDEVICE_PHONE_HUB_NOTIFICATIONS, + mojom::kMultiDeviceFeaturesSubpagePath, + mojom::SearchResultIcon::kPhone, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSetting, + {.setting = mojom::Setting::kPhoneHubNotificationsOnOff}}, + {IDS_OS_SETTINGS_TAG_MULTIDEVICE_PHONE_HUB_NOTIFICATION_BADGE, + mojom::kMultiDeviceFeaturesSubpagePath, + mojom::SearchResultIcon::kPhone, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSetting, + {.setting = mojom::Setting::kPhoneHubNotificationBadgeOnOff}}, + {IDS_OS_SETTINGS_TAG_MULTIDEVICE_PHONE_HUB_TASK_CONTINUATION, + mojom::kMultiDeviceFeaturesSubpagePath, + mojom::SearchResultIcon::kPhone, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSetting, + {.setting = mojom::Setting::kPhoneHubTaskContinuationOnOff}}}); return *tags; } @@ -91,8 +121,21 @@ const std::vector<SearchConcept>& GetMultiDeviceOptedOutSearchConcepts() { IDS_OS_SETTINGS_TAG_MULTIDEVICE_SMART_LOCK, SearchConcept::kAltTagEnd}, }; - // If Instant Tethering is available, also include that in the list. - if (base::FeatureList::IsEnabled(features::kInstantTethering)) { + bool is_phone_hub_enabled = features::IsPhoneHubEnabled(); + bool is_instant_tether_enabled = + base::FeatureList::IsEnabled(features::kInstantTethering); + + // If Phone Hub and/or Instant Tethering is available, also include them in + // the list. + if (is_phone_hub_enabled) { + set_up_concept.alt_tag_ids[3] = IDS_OS_SETTINGS_TAG_MULTIDEVICE_PHONE_HUB; + + if (is_instant_tether_enabled) { + set_up_concept.alt_tag_ids[4] = IDS_OS_SETTINGS_TAG_INSTANT_TETHERING; + } else { + set_up_concept.alt_tag_ids[4] = SearchConcept::kAltTagEnd; + } + } else if (is_instant_tether_enabled) { set_up_concept.alt_tag_ids[3] = IDS_OS_SETTINGS_TAG_INSTANT_TETHERING; set_up_concept.alt_tag_ids[4] = SearchConcept::kAltTagEnd; } @@ -159,10 +202,12 @@ MultiDeviceSection::MultiDeviceSection( Profile* profile, SearchTagRegistry* search_tag_registry, multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client, + phonehub::PhoneHubManager* phone_hub_manager, android_sms::AndroidSmsService* android_sms_service, PrefService* pref_service) : OsSettingsSection(profile, search_tag_registry), multidevice_setup_client_(multidevice_setup_client), + phone_hub_manager_(phone_hub_manager), android_sms_service_(android_sms_service), pref_service_(pref_service) { if (base::FeatureList::IsEnabled(::features::kNearbySharing)) { @@ -199,6 +244,14 @@ void MultiDeviceSection::AddLoadTimeData( {"multideviceEnabled", IDS_SETTINGS_MULTIDEVICE_ENABLED}, {"multideviceDisabled", IDS_SETTINGS_MULTIDEVICE_DISABLED}, {"multideviceSmartLockItemTitle", IDS_SETTINGS_EASY_UNLOCK_SECTION_TITLE}, + {"multidevicePhoneHubItemTitle", + IDS_SETTINGS_MULTIDEVICE_PHONE_HUB_SECTION_TITLE}, + {"multidevicePhoneHubNotificationsItemTitle", + IDS_SETTINGS_MULTIDEVICE_PHONE_HUB_NOTIFICATIONS_SECTION_TITLE}, + {"multidevicePhoneHubNotificationBadgeItemTitle", + IDS_SETTINGS_MULTIDEVICE_PHONE_HUB_NOTIFICATION_BADGE_SECTION_TITLE}, + {"multidevicePhoneHubTaskContinuationItemTitle", + IDS_SETTINGS_MULTIDEVICE_PHONE_HUB_TASK_CONTINUATION_SECTION_TITLE}, {"multideviceInstantTetheringItemTitle", IDS_SETTINGS_MULTIDEVICE_INSTANT_TETHERING}, {"multideviceInstantTetheringItemSummary", @@ -277,6 +330,8 @@ void MultiDeviceSection::AddHandlers(content::WebUI* web_ui) { web_ui->AddMessageHandler( std::make_unique<chromeos::settings::MultideviceHandler>( pref_service_, multidevice_setup_client_, + phone_hub_manager_ ? phone_hub_manager_->notification_access_manager() + : nullptr, android_sms_service_ ? android_sms_service_->android_sms_pairing_state_tracker() : nullptr, @@ -315,6 +370,10 @@ void MultiDeviceSection::RegisterHierarchy( mojom::Setting::kMessagesSetUp, mojom::Setting::kMessagesOnOff, mojom::Setting::kForgetPhone, + mojom::Setting::kPhoneHubOnOff, + mojom::Setting::kPhoneHubNotificationsOnOff, + mojom::Setting::kPhoneHubNotificationBadgeOnOff, + mojom::Setting::kPhoneHubTaskContinuationOnOff, }; RegisterNestedSettingBulk(mojom::Subpage::kMultiDeviceFeatures, kMultiDeviceFeaturesSettings, generator); @@ -355,12 +414,15 @@ void MultiDeviceSection::OnHostStatusChanged( const multidevice_setup::MultiDeviceSetupClient::HostStatusWithDevice& host_status_with_device) { SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate(); + updater.RemoveSearchTags(GetMultiDeviceOptedOutSearchConcepts()); + updater.RemoveSearchTags(GetMultiDeviceOptedInPhoneHubSearchConcepts()); + updater.RemoveSearchTags(GetMultiDeviceOptedInSearchConcepts()); if (IsOptedIn(host_status_with_device.first)) { - updater.RemoveSearchTags(GetMultiDeviceOptedOutSearchConcepts()); updater.AddSearchTags(GetMultiDeviceOptedInSearchConcepts()); + if (features::IsPhoneHubEnabled()) + updater.AddSearchTags(GetMultiDeviceOptedInPhoneHubSearchConcepts()); } else { - updater.RemoveSearchTags(GetMultiDeviceOptedInSearchConcepts()); updater.AddSearchTags(GetMultiDeviceOptedOutSearchConcepts()); } } diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_section.h b/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_section.h index 2c608c9e03c..866c5ca6673 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_section.h +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/multidevice_section.h @@ -21,6 +21,10 @@ namespace android_sms { class AndroidSmsService; } // namespace android_sms +namespace phonehub { +class PhoneHubManager; +} // namespace phonehub + namespace settings { class SearchTagRegistry; @@ -36,6 +40,7 @@ class MultiDeviceSection Profile* profile, SearchTagRegistry* search_tag_registry, multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client, + phonehub::PhoneHubManager* phone_hub_manager, android_sms::AndroidSmsService* android_sms_service, PrefService* pref_service); ~MultiDeviceSection() override; @@ -59,6 +64,7 @@ class MultiDeviceSection void OnNearbySharingEnabledChanged(); multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client_; + phonehub::PhoneHubManager* phone_hub_manager_; android_sms::AndroidSmsService* android_sms_service_; PrefService* pref_service_; PrefChangeRegistrar pref_change_registrar_; diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_features_util.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_features_util.cc index 961505560e9..66ff64e5a31 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_features_util.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_features_util.cc @@ -47,11 +47,6 @@ bool ShouldShowExternalStorageSettings(const Profile* profile) { arc::IsArcPlayStoreEnabledForProfile(profile); } -bool ShouldShowDlcSettings() { - return !IsGuestModeActive() && - base::FeatureList::IsEnabled(chromeos::features::kDlcSettingsUi); -} - } // namespace features } // namespace settings } // namespace chromeos diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_features_util.h b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_features_util.h index 33da01f6065..b175319fd81 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_features_util.h +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_features_util.h @@ -21,9 +21,6 @@ bool ShouldShowParentalControlSettings(const Profile* profile); // shown for |profile|. bool ShouldShowExternalStorageSettings(const Profile* profile); -// Determines whether the DLC section of Storage settings should be shown. -bool ShouldShowDlcSettings(); - } // namespace features } // namespace settings } // namespace chromeos diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.cc index 95cd5692e5c..2543930d326 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.cc @@ -6,11 +6,11 @@ #include "base/bind.h" #include "base/feature_list.h" -#include "chrome/browser/chromeos/local_search_service/local_search_service.h" #include "chrome/browser/ui/webui/settings/chromeos/hierarchy.h" #include "chrome/browser/ui/webui/settings/chromeos/os_settings_sections.h" #include "chrome/browser/ui/webui/settings/chromeos/search/search_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" +#include "chromeos/components/local_search_service/local_search_service.h" #include "chromeos/constants/chromeos_features.h" #include "content/public/browser/web_ui_data_source.h" #include "ui/base/l10n/l10n_util.h" @@ -22,6 +22,7 @@ OsSettingsManager::OsSettingsManager( Profile* profile, local_search_service::LocalSearchService* local_search_service, multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client, + phonehub::PhoneHubManager* phone_hub_manager, syncer::SyncService* sync_service, SupervisedUserService* supervised_user_service, KerberosCredentialsManager* kerberos_credentials_manager, @@ -35,6 +36,7 @@ OsSettingsManager::OsSettingsManager( std::make_unique<OsSettingsSections>(profile, search_tag_registry_.get(), multidevice_setup_client, + phone_hub_manager, sync_service, supervised_user_service, kerberos_credentials_manager, diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.h b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.h index 78a9008a482..11d5bfc50cb 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.h +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.h @@ -19,10 +19,6 @@ class WebUI; class WebUIDataSource; } // namespace content -namespace local_search_service { -class LocalSearchService; -} // namespace local_search_service - namespace signin { class IdentityManager; } // namespace signin @@ -40,10 +36,18 @@ namespace android_sms { class AndroidSmsService; } // namespace android_sms +namespace local_search_service { +class LocalSearchService; +} // namespace local_search_service + namespace multidevice_setup { class MultiDeviceSetupClient; } // namespace multidevice_setup +namespace phonehub { +class PhoneHubManager; +} // namespace phonehub + namespace settings { class Hierarchy; @@ -82,6 +86,7 @@ class OsSettingsManager : public KeyedService { Profile* profile, local_search_service::LocalSearchService* local_search_service, multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client, + phonehub::PhoneHubManager* phone_hub_manager, syncer::SyncService* sync_service, SupervisedUserService* supervised_user_service, KerberosCredentialsManager* kerberos_credentials_manager, diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_factory.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_factory.cc index 71e5abc2b2f..11ad06e9db6 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_factory.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_factory.cc @@ -6,8 +6,8 @@ #include "chrome/browser/chromeos/android_sms/android_sms_service_factory.h" #include "chrome/browser/chromeos/kerberos/kerberos_credentials_manager_factory.h" -#include "chrome/browser/chromeos/local_search_service/local_search_service_factory.h" #include "chrome/browser/chromeos/multidevice_setup/multidevice_setup_client_factory.h" +#include "chrome/browser/chromeos/phonehub/phone_hub_manager_factory.h" #include "chrome/browser/chromeos/printing/cups_printers_manager_factory.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/incognito_helpers.h" @@ -17,6 +17,7 @@ #include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.h" #include "chrome/browser/ui/webui/settings/chromeos/os_settings_manager.h" +#include "chromeos/components/local_search_service/local_search_service_factory.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" namespace chromeos { @@ -40,6 +41,7 @@ OsSettingsManagerFactory::OsSettingsManagerFactory() BrowserContextDependencyManager::GetInstance()) { DependsOn(local_search_service::LocalSearchServiceFactory::GetInstance()); DependsOn(multidevice_setup::MultiDeviceSetupClientFactory::GetInstance()); + DependsOn(phonehub::PhoneHubManagerFactory::GetInstance()); DependsOn(ProfileSyncServiceFactory::GetInstance()); DependsOn(SupervisedUserServiceFactory::GetInstance()); DependsOn(KerberosCredentialsManagerFactory::GetInstance()); @@ -66,8 +68,10 @@ KeyedService* OsSettingsManagerFactory::BuildServiceInstanceFor( return new OsSettingsManager( profile, - local_search_service::LocalSearchServiceFactory::GetForProfile(profile), + local_search_service::LocalSearchServiceFactory::GetForBrowserContext( + context), multidevice_setup::MultiDeviceSetupClientFactory::GetForProfile(profile), + phonehub::PhoneHubManagerFactory::GetForProfile(profile), ProfileSyncServiceFactory::GetForProfile(profile), SupervisedUserServiceFactory::GetForProfile(profile), kerberos_credentials_manager, diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_section.cc index 02bdc340841..6ae3dd1cc8e 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_section.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_section.cc @@ -8,12 +8,16 @@ #include "base/strings/utf_string_conversions.h" #include "base/system/sys_info.h" #include "chrome/grit/generated_resources.h" +#include "chromeos/constants/chromeos_features.h" #include "ui/base/l10n/l10n_util.h" namespace chromeos { namespace settings { // static +constexpr const char OsSettingsSection::kSettingIdUrlParam[]; + +// static base::string16 OsSettingsSection::GetHelpUrlWithBoard( const std::string& original_url) { return base::ASCIIToUTF16(original_url + @@ -44,8 +48,7 @@ std::string OsSettingsSection::ModifySearchResultUrl( mojom::SearchResultType type, OsSettingsIdentifier id, const std::string& url_to_modify) const { - // Default case for static URLs which do not need to be modified. - return url_to_modify; + return GetDefaultModifiedUrl(type, id, url_to_modify); } mojom::SearchResultPtr OsSettingsSection::GenerateSectionSearchResult( @@ -66,5 +69,29 @@ mojom::SearchResultPtr OsSettingsSection::GenerateSectionSearchResult( mojom::SearchResultIdentifier::NewSection(GetSection())); } +// static +std::string OsSettingsSection::GetDefaultModifiedUrl( + mojom::SearchResultType type, + OsSettingsIdentifier id, + const std::string& url_to_modify) { + if (!chromeos::features::IsDeepLinkingEnabled() || + type != mojom::SearchResultType::kSetting) { + // Default case for static URLs which do not need to be modified. + return url_to_modify; + } + + std::stringstream ss; + ss << url_to_modify; + // Handle existing query parameters. + if (url_to_modify.find('?') == std::string::npos) { + ss << '?'; + } else { + ss << '&'; + } + // Add deep link to query i.e. "settingId=4". + ss << kSettingIdUrlParam << '=' << static_cast<int32_t>(id.setting); + return ss.str(); +} + } // namespace settings } // namespace chromeos diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_section.h b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_section.h index b4406ff4c3e..d2a4dc4dde7 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_section.h +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_section.h @@ -154,6 +154,22 @@ class OsSettingsSection { SearchTagRegistry* registry() { return search_tag_registry_; } private: + FRIEND_TEST_ALL_PREFIXES(OsSettingsSectionTest, SectionWithFlag); + FRIEND_TEST_ALL_PREFIXES(OsSettingsSectionTest, SectionNoFlag); + FRIEND_TEST_ALL_PREFIXES(OsSettingsSectionTest, SubpageWithFlag); + FRIEND_TEST_ALL_PREFIXES(OsSettingsSectionTest, SubpageNoFlag); + FRIEND_TEST_ALL_PREFIXES(OsSettingsSectionTest, SettingWithFlag); + FRIEND_TEST_ALL_PREFIXES(OsSettingsSectionTest, SettingExistingQueryWithFlag); + FRIEND_TEST_ALL_PREFIXES(OsSettingsSectionTest, SettingNoFlag); + + static constexpr char kSettingIdUrlParam[] = "settingId"; + + // If type is Setting, adds the kSettingIdUrlParam to the query parameter + // and returns the deep linked url. Doesn't modify url otherwise. + static std::string GetDefaultModifiedUrl(mojom::SearchResultType type, + OsSettingsIdentifier id, + const std::string& url_to_modify); + Profile* profile_; SearchTagRegistry* search_tag_registry_; }; diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_section_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_section_unittest.cc new file mode 100644 index 00000000000..7408442bf73 --- /dev/null +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_section_unittest.cc @@ -0,0 +1,105 @@ +// 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_section.h" + +#include "base/test/scoped_feature_list.h" +#include "chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom.h" +#include "chromeos/constants/chromeos_features.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromeos { +namespace settings { + +TEST(OsSettingsSectionTest, SectionWithFlag) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + chromeos::features::kOsSettingsDeepLinking); + + // Sections should not incur modification. + EXPECT_EQ("internet", OsSettingsSection::GetDefaultModifiedUrl( + /*type=*/mojom::SearchResultType::kSection, + /*id=*/{.section = mojom::Section::kNetwork}, + /*url_to_modify=*/"internet")); +} + +TEST(OsSettingsSectionTest, SectionNoFlag) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndDisableFeature( + chromeos::features::kOsSettingsDeepLinking); + + // Deep linking disabled, should not modify. + EXPECT_EQ("internet", OsSettingsSection::GetDefaultModifiedUrl( + /*type=*/mojom::SearchResultType::kSection, + /*id=*/{.section = mojom::Section::kNetwork}, + /*url_to_modify=*/"internet")); +} + +TEST(OsSettingsSectionTest, SubpageWithFlag) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + chromeos::features::kOsSettingsDeepLinking); + + // Subpages should not incur modification. + EXPECT_EQ("networks?type=WiFi", + OsSettingsSection::GetDefaultModifiedUrl( + /*type=*/mojom::SearchResultType::kSubpage, + /*id=*/{.subpage = mojom::Subpage::kWifiNetworks}, + /*url_to_modify=*/"networks?type=WiFi")); +} + +TEST(OsSettingsSectionTest, SubpageNoFlag) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndDisableFeature( + chromeos::features::kOsSettingsDeepLinking); + + // Deep linking disabled, should not modify. + EXPECT_EQ("networks?type=WiFi", + OsSettingsSection::GetDefaultModifiedUrl( + /*type=*/mojom::SearchResultType::kSubpage, + /*id=*/{.subpage = mojom::Subpage::kWifiNetworks}, + /*url_to_modify=*/"networks?type=WiFi")); +} + +TEST(OsSettingsSectionTest, SettingWithFlag) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + chromeos::features::kOsSettingsDeepLinking); + + // Settings should have settingId added + EXPECT_EQ("networks?settingId=4", + OsSettingsSection::GetDefaultModifiedUrl( + /*type=*/mojom::SearchResultType::kSetting, + /*id=*/{.setting = mojom::Setting::kWifiOnOff}, + /*url_to_modify=*/"networks")); +} + +TEST(OsSettingsSectionTest, SettingExistingQueryWithFlag) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + chromeos::features::kOsSettingsDeepLinking); + + // Settings with existing query parameters should have settingId added. + EXPECT_EQ("networks?type=WiFi&settingId=4", + OsSettingsSection::GetDefaultModifiedUrl( + /*type=*/mojom::SearchResultType::kSetting, + /*id=*/{.setting = mojom::Setting::kWifiOnOff}, + /*url_to_modify=*/"networks?type=WiFi")); +} + +TEST(OsSettingsSectionTest, SettingNoFlag) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndDisableFeature( + chromeos::features::kOsSettingsDeepLinking); + + // Deep linking disabled, should not modify. + EXPECT_EQ("networks?type=WiFi", + OsSettingsSection::GetDefaultModifiedUrl( + /*type=*/mojom::SearchResultType::kSetting, + /*id=*/{.setting = mojom::Setting::kWifiOnOff}, + /*url_to_modify=*/"networks?type=WiFi")); +} + +} // namespace settings +} // namespace chromeos diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.cc index 334128e8509..744325a9a6f 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.cc @@ -24,6 +24,7 @@ #include "chrome/browser/ui/webui/settings/chromeos/privacy_section.h" #include "chrome/browser/ui/webui/settings/chromeos/reset_section.h" #include "chrome/browser/ui/webui/settings/chromeos/search_section.h" +#include "chromeos/components/phonehub/phone_hub_manager.h" namespace chromeos { namespace settings { @@ -32,6 +33,7 @@ OsSettingsSections::OsSettingsSections( Profile* profile, SearchTagRegistry* search_tag_registry, multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client, + phonehub::PhoneHubManager* phone_hub_manager, syncer::SyncService* sync_service, SupervisedUserService* supervised_user_service, KerberosCredentialsManager* kerberos_credentials_manager, @@ -54,7 +56,7 @@ OsSettingsSections::OsSettingsSections( sections_.push_back(std::move(bluetooth_section)); auto multidevice_section = std::make_unique<MultiDeviceSection>( - profile, search_tag_registry, multidevice_setup_client, + profile, search_tag_registry, multidevice_setup_client, phone_hub_manager, android_sms_service, profile->GetPrefs()); sections_map_[mojom::Section::kMultiDevice] = multidevice_section.get(); sections_.push_back(std::move(multidevice_section)); diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.h b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.h index d1526481464..0f294235d21 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.h +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/os_settings_sections.h @@ -36,6 +36,10 @@ namespace multidevice_setup { class MultiDeviceSetupClient; } // namespace multidevice_setup +namespace phonehub { +class PhoneHubManager; +} // namespace phonehub + namespace settings { // Collection of all OsSettingsSection implementations. @@ -45,6 +49,7 @@ class OsSettingsSections { Profile* profile, SearchTagRegistry* search_tag_registry, multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client, + phonehub::PhoneHubManager* phone_hub_manager, syncer::SyncService* sync_service, SupervisedUserService* supervised_user_service, KerberosCredentialsManager* kerberos_credentials_manager, 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 8bddd59808d..e625820a30d 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 @@ -8,7 +8,11 @@ #include "ash/public/cpp/network_config_service.h" #include "base/metrics/histogram_functions.h" +#include "chrome/browser/nearby_sharing/nearby_share_settings.h" +#include "chrome/browser/nearby_sharing/nearby_sharing_service_factory.h" +#include "chrome/browser/nearby_sharing/nearby_sharing_service_impl.h" #include "chrome/browser/ui/webui/managed_ui_handler.h" +#include "chrome/browser/ui/webui/nearby_share/shared_resources.h" #include "chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/os_settings_manager.h" #include "chrome/browser/ui/webui/settings/chromeos/os_settings_manager_factory.h" @@ -24,6 +28,7 @@ #include "components/prefs/pref_service.h" #include "content/public/browser/web_ui_data_source.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/self_owned_receiver.h" namespace chromeos { namespace settings { @@ -54,6 +59,7 @@ OSSettingsUI::OSSettingsUI(content::WebUI* web_ui) OsSettingsManager* manager = OsSettingsManagerFactory::GetForProfile(profile); manager->AddHandlers(web_ui); manager->AddLoadTimeData(html_source); + html_source->DisableTrustedTypesCSP(); // TODO(khorimoto): Move to DeviceSection::AddHandler() once |html_source| // parameter is removed. @@ -62,23 +68,40 @@ OSSettingsUI::OSSettingsUI(content::WebUI* web_ui) html_source)); #if BUILDFLAG(OPTIMIZE_WEBUI) - html_source->AddResourcePath("crisper.js", IDR_OS_SETTINGS_CRISPER_JS); - html_source->AddResourcePath("lazy_load.crisper.js", - IDR_OS_SETTINGS_LAZY_LOAD_CRISPER_JS); - html_source->AddResourcePath("chromeos/lazy_load.html", - IDR_OS_SETTINGS_LAZY_LOAD_VULCANIZED_HTML); - html_source->SetDefaultResource(IDR_OS_SETTINGS_VULCANIZED_HTML); - html_source->AddResourcePath("chromeos/os_settings_v3.html", - IDR_OS_SETTINGS_OS_SETTINGS_V3_HTML); - html_source->AddResourcePath("chromeos/os_settings.js", - IDR_OS_SETTINGS_SETTINGS_ROLLUP_JS); + if (base::FeatureList::IsEnabled(::chromeos::features::kOsSettingsPolymer3)) { + // Polymer3 Source files + webui::SetupBundledWebUIDataSource(html_source, "chromeos/os_settings.js", + IDR_OS_SETTINGS_OS_SETTINGS_ROLLUP_JS, + IDR_OS_SETTINGS_OS_SETTINGS_V3_HTML); + html_source->AddResourcePath("chromeos/shared.rollup.js", + IDR_OS_SETTINGS_SHARED_ROLLUP_JS); + html_source->AddResourcePath("chromeos/lazy_load.js", + IDR_OS_SETTINGS_LAZY_LOAD_ROLLUP_JS); + } else { + // Polymer2 Source files + html_source->AddResourcePath("crisper.js", IDR_OS_SETTINGS_CRISPER_JS); + html_source->AddResourcePath("lazy_load.crisper.js", + IDR_OS_SETTINGS_LAZY_LOAD_CRISPER_JS); + html_source->AddResourcePath("chromeos/lazy_load.html", + IDR_OS_SETTINGS_LAZY_LOAD_VULCANIZED_HTML); + html_source->SetDefaultResource(IDR_OS_SETTINGS_VULCANIZED_HTML); + } #else webui::SetupWebUIDataSource( html_source, base::make_span(kOsSettingsResources, kOsSettingsResourcesSize), - kOsGeneratedPath, IDR_OS_SETTINGS_SETTINGS_HTML); + kOsGeneratedPath, + base::FeatureList::IsEnabled(chromeos::features::kOsSettingsPolymer3) + ? IDR_OS_SETTINGS_OS_SETTINGS_V3_HTML + : IDR_OS_SETTINGS_SETTINGS_HTML); #endif + // Register chrome://nearby resources so they are available at + // chrome://os-settings. This allows the sharing of resources without having + // to put everything in chrome://resources. This is necessary because portions + // of the nearby UI need to be re-used in both places. + RegisterNearbySharedResources(html_source); + ManagedUIHandler::Initialize(web_ui, html_source); content::WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(), @@ -125,6 +148,14 @@ void OSSettingsUI::BindInterface( app_management_page_handler_factory_->Bind(std::move(receiver)); } +void OSSettingsUI::BindInterface( + mojo::PendingReceiver<nearby_share::mojom::NearbyShareSettings> receiver) { + NearbySharingService* service = + NearbySharingServiceFactory::GetForBrowserContext( + Profile::FromWebUI(web_ui())); + service->GetSettings()->Bind(std::move(receiver)); +} + WEB_UI_CONTROLLER_TYPE_IMPL(OSSettingsUI) } // namespace settings 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 2b4e49fd6bb..cd8e8062190 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 @@ -10,6 +10,7 @@ #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/nearby_share/public/mojom/nearby_share_settings.mojom.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" @@ -55,6 +56,11 @@ class OSSettingsUI : public ui::MojoWebUIController { mojo::PendingReceiver<app_management::mojom::PageHandlerFactory> receiver); + // Binds to the existing settings instance owned by the nearby share keyed + // service. + void BindInterface( + mojo::PendingReceiver<nearby_share::mojom::NearbyShareSettings> receiver); + private: base::TimeTicks time_when_opened_; diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/people_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/people_section.cc index e5bb33b3244..e40dd48d4ca 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/people_section.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/people_section.cc @@ -417,6 +417,8 @@ void AddLockScreenPageStrings(content::WebUIDataSource* html_source, IDS_ASH_SETTINGS_LOCK_SCREEN_NOTIFICATION_SHOW}, {"lockScreenPinOrPassword", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_PIN_OR_PASSWORD}, + {"lockScreenPinAutoSubmit", + IDS_SETTINGS_PEOPLE_LOCK_SCREEN_PIN_AUTOSUBMIT}, {"lockScreenSetupFingerprintButton", IDS_SETTINGS_PEOPLE_LOCK_SCREEN_FINGERPRINT_SETUP_BUTTON}, {"lockScreenNotificationHide", @@ -445,6 +447,12 @@ void AddLockScreenPageStrings(content::WebUIDataSource* html_source, IDS_SETTINGS_PEOPLE_LOCK_SCREEN_TITLE_LOGIN_LOCK}, {"passwordPromptEnterPasswordLock", IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_ENTER_PASSWORD_LOCK}, + {"pinAutoSubmitPrompt", + IDS_SETTINGS_PEOPLE_LOCK_SCREEN_PIN_AUTOSUBMIT_PROMPT}, + {"pinAutoSubmitLongPinError", + IDS_SETTINGS_PEOPLE_LOCK_SCREEN_PIN_AUTOSUBMIT_ERROR_PIN_TOO_LONG}, + {"pinAutoSubmitPinIncorrect", + IDS_SETTINGS_PEOPLE_LOCK_SCREEN_PIN_AUTOSUBMIT_ERROR_PIN_INCORRECT}, {"passwordPromptEnterPasswordLoginLock", IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_ENTER_PASSWORD_LOGIN_LOCK}, }; @@ -452,6 +460,8 @@ void AddLockScreenPageStrings(content::WebUIDataSource* html_source, html_source->AddBoolean("quickUnlockEnabled", chromeos::quick_unlock::IsPinEnabled(pref_service)); + html_source->AddBoolean("quickUnlockPinAutosubmitFeatureEnabled", + chromeos::features::IsPinAutosubmitFeatureEnabled()); html_source->AddBoolean( "quickUnlockDisabledByPolicy", chromeos::quick_unlock::IsPinDisabledByPolicy(pref_service)); @@ -552,6 +562,7 @@ void AddSetupPinDialogStrings(content::WebUIDataSource* html_source) { IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_CHOOSE_PIN_TITLE}, {"configurePinConfirmPinTitle", IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_CONFIRM_PIN_TITLE}, + {"invalidPin", IDS_SETTINGS_PEOPLE_PIN_PROMPT_INVALID_PIN}, {"configurePinMismatched", IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_MISMATCHED}, {"configurePinTooShort", IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_TOO_SHORT}, {"configurePinTooLong", IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_TOO_LONG}, @@ -775,8 +786,6 @@ void PeopleSection::AddLoadTimeData(content::WebUIDataSource* html_source) { "secondaryGoogleAccountSigninAllowed", pref_service_->GetBoolean( chromeos::prefs::kSecondaryGoogleAccountSigninAllowed)); - html_source->AddBoolean("isEduCoexistenceEnabled", - ::chromeos::features::IsEduCoexistenceEnabled()); html_source->AddBoolean( "driveSuggestAvailable", diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/personalization_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/personalization_section.cc index dfbbaf17853..36b5635a8de 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/personalization_section.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/personalization_section.cc @@ -4,9 +4,11 @@ #include "chrome/browser/ui/webui/settings/chromeos/personalization_section.h" +#include "ash/public/cpp/ambient/ambient_client.h" #include "ash/public/cpp/ambient/ambient_prefs.h" #include "base/bind.h" #include "base/no_destructor.h" +#include "base/strings/utf_string_conversions.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h" @@ -15,6 +17,7 @@ #include "chrome/browser/ui/webui/settings/chromeos/wallpaper_handler.h" #include "chrome/browser/ui/webui/webui_util.h" #include "chrome/common/chrome_features.h" +#include "chrome/common/url_constants.h" #include "chrome/grit/generated_resources.h" #include "chromeos/constants/chromeos_features.h" #include "components/prefs/pref_service.h" @@ -22,6 +25,7 @@ #include "content/public/browser/web_ui_data_source.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/webui/web_ui_util.h" +#include "url/gurl.h" namespace chromeos { namespace settings { @@ -60,7 +64,6 @@ const std::vector<SearchConcept>& GetPersonalizationSearchConcepts() { return *tags; } -// TODO(b/159766700): Add search concepts for |kAmbientModePhotosSubpagePath|. const std::vector<SearchConcept>& GetAmbientModeSearchConcepts() { static const base::NoDestructor<std::vector<SearchConcept>> tags({ {IDS_OS_SETTINGS_TAG_AMBIENT_MODE, @@ -89,6 +92,18 @@ const std::vector<SearchConcept>& GetAmbientModeOnSearchConcepts() { {.setting = mojom::Setting::kAmbientModeOnOff}, {IDS_OS_SETTINGS_TAG_AMBIENT_MODE_TURN_OFF_ALT1, SearchConcept::kAltTagEnd}}, + {IDS_OS_SETTINGS_TAG_AMBIENT_MODE_GOOGLE_PHOTOS_ALBUM, + mojom::kAmbientModeGooglePhotosAlbumSubpagePath, + mojom::SearchResultIcon::kWallpaper, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSubpage, + {.subpage = mojom::Subpage::kAmbientModeGooglePhotosAlbum}}, + {IDS_OS_SETTINGS_TAG_AMBIENT_MODE_ART_GALLERY_ALBUM, + mojom::kAmbientModeArtGalleryAlbumSubpagePath, + mojom::SearchResultIcon::kWallpaper, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSubpage, + {.subpage = mojom::Subpage::kAmbientModeArtGalleryAlbum}}, }); return *tags; } @@ -108,7 +123,16 @@ const std::vector<SearchConcept>& GetAmbientModeOffSearchConcepts() { } bool IsAmbientModeAllowed() { - return chromeos::features::IsAmbientModeEnabled(); + return chromeos::features::IsAmbientModeEnabled() && + ash::AmbientClient::Get()->IsAmbientModeAllowed(); +} + +bool IsAmbientModePhotoPreviewAllowed() { + return chromeos::features::IsAmbientModePhotoPreviewEnabled(); +} + +GURL GetGooglePhotosURL() { + return GURL(chrome::kGooglePhotosURL); } } // namespace @@ -147,14 +171,37 @@ void PersonalizationSection::AddLoadTimeData( {"ambientModeTitle", IDS_OS_SETTINGS_AMBIENT_MODE_TITLE}, {"ambientModeEnabled", IDS_OS_SETTINGS_AMBIENT_MODE_ENABLED}, {"ambientModeDisabled", IDS_OS_SETTINGS_AMBIENT_MODE_DISABLED}, + {"ambientModePageDescription", + IDS_OS_SETTINGS_AMBIENT_MODE_PAGE_DESCRIPTION}, {"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}, + {"ambientModeTopicSourceGooglePhotosDescription", + IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_GOOGLE_PHOTOS_DESC}, + {"ambientModeTopicSourceGooglePhotosDescriptionNoAlbum", + IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_GOOGLE_PHOTOS_DESC_NO_ALBUM}, {"ambientModeTopicSourceArtGallery", IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_ART_GALLERY}, + {"ambientModeTopicSourceArtGalleryDescription", + IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_ART_GALLERY_DESCRIPTION}, + {"ambientModeTopicSourceSelectedRow", + IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_SELECTED_ROW}, + {"ambientModeTopicSourceUnselectedRow", + IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_UNSELECTED_ROW}, + {"ambientModeTopicSourceSubpage", + IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_SUBPAGE}, + {"ambientModeWeatherTitle", IDS_OS_SETTINGS_AMBIENT_MODE_WEATHER_TITLE}, + {"ambientModeTemperatureUnitFahrenheit", + IDS_OS_SETTINGS_AMBIENT_MODE_TEMPERATURE_UNIT_FAHRENHEIT}, + {"ambientModeTemperatureUnitCelsius", + IDS_OS_SETTINGS_AMBIENT_MODE_TEMPERATURE_UNIT_CELSIUS}, + {"ambientModeAlbumsSubpageAlbumSelected", + IDS_OS_SETTINGS_AMBIENT_MODE_ALBUMS_SUBPAGE_ALBUM_SELECTED}, + {"ambientModeAlbumsSubpageAlbumUnselected", + IDS_OS_SETTINGS_AMBIENT_MODE_ALBUMS_SUBPAGE_ALBUM_UNSELECTED}, {"changePictureTitle", IDS_OS_SETTINGS_CHANGE_PICTURE_TITLE}, {"openWallpaperApp", IDS_OS_SETTINGS_OPEN_WALLPAPER_APP}, {"personalizationPageTitle", IDS_OS_SETTINGS_PERSONALIZATION}, @@ -184,6 +231,18 @@ void PersonalizationSection::AddLoadTimeData( "changePictureVideoModeEnabled", base::FeatureList::IsEnabled(::features::kChangePictureVideoMode)); html_source->AddBoolean("isAmbientModeEnabled", IsAmbientModeAllowed()); + html_source->AddBoolean("isAmbientModePhotoPreviewEnabled", + IsAmbientModePhotoPreviewAllowed()); + html_source->AddString( + "ambientModeAlbumsSubpageGooglePhotosTitle", + l10n_util::GetStringFUTF16( + IDS_OS_SETTINGS_AMBIENT_MODE_ALBUMS_SUBPAGE_GOOGLE_PHOTOS_TITLE, + base::UTF8ToUTF16(GetGooglePhotosURL().spec()))); + html_source->AddString( + "ambientModeAlbumsSubpageGooglePhotosNoAlbum", + l10n_util::GetStringFUTF16( + IDS_OS_SETTINGS_AMBIENT_MODE_ALBUMS_SUBPAGE_GOOGLE_PHOTOS_NO_ALBUM, + base::UTF8ToUTF16(GetGooglePhotosURL().spec()))); } void PersonalizationSection::AddHandlers(content::WebUI* web_ui) { @@ -238,19 +297,18 @@ void PersonalizationSection::RegisterHierarchy( }; RegisterNestedSettingBulk(mojom::Subpage::kAmbientMode, kAmbientModeSettings, generator); - - // Note: The subpage name in the UI is updated dynamically based on the topic - // source. - // TODO(b/159766700): Create a string for the page title and strings for the - // search. generator->RegisterNestedSubpage( - IDS_OS_SETTINGS_AMBIENT_MODE_TITLE, mojom::Subpage::kAmbientModePhotos, + IDS_OS_SETTINGS_AMBIENT_MODE_TITLE, + mojom::Subpage::kAmbientModeGooglePhotosAlbum, mojom::Subpage::kAmbientMode, mojom::SearchResultIcon::kWallpaper, mojom::SearchResultDefaultRank::kMedium, - mojom::kAmbientModePhotosSubpagePath); - generator->RegisterNestedSetting( - mojom::Setting::kAmbientModeUpdatePhotosContainers, - mojom::Subpage::kAmbientModePhotos); + mojom::kAmbientModeGooglePhotosAlbumSubpagePath); + generator->RegisterNestedSubpage( + IDS_OS_SETTINGS_AMBIENT_MODE_TITLE, + mojom::Subpage::kAmbientModeArtGalleryAlbum, mojom::Subpage::kAmbientMode, + mojom::SearchResultIcon::kWallpaper, + mojom::SearchResultDefaultRank::kMedium, + mojom::kAmbientModeArtGalleryAlbumSubpagePath); } void PersonalizationSection::OnAmbientModeEnabledStateChanged() { diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc index 85c6dea6016..c895cfb5e51 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc @@ -36,14 +36,6 @@ const std::vector<SearchConcept>& GetPrivacySearchConcepts() { mojom::SearchResultDefaultRank::kMedium, mojom::SearchResultType::kSection, {.section = mojom::Section::kPrivacyAndSecurity}}, - {IDS_OS_SETTINGS_TAG_PRIVACY_WIFI_SLEEP, - mojom::kPrivacyAndSecuritySectionPath, - mojom::SearchResultIcon::kShield, - mojom::SearchResultDefaultRank::kMedium, - mojom::SearchResultType::kSetting, - {.setting = mojom::Setting::kKeepWifiOnDuringSleep}, - {IDS_OS_SETTINGS_TAG_PRIVACY_WIFI_SLEEP_ALT1, - SearchConcept::kAltTagEnd}}, }); return *tags; } @@ -83,7 +75,6 @@ void PrivacySection::AddLoadTimeData(content::WebUIDataSource* html_source) { {"privacyPageTitle", IDS_SETTINGS_PRIVACY}, {"enableLogging", IDS_SETTINGS_ENABLE_LOGGING_TOGGLE_TITLE}, {"enableLoggingDesc", IDS_SETTINGS_ENABLE_LOGGING_TOGGLE_DESC}, - {"wakeOnWifi", IDS_SETTINGS_WAKE_ON_WIFI_DESCRIPTION}, {"enableContentProtectionAttestation", IDS_SETTINGS_ENABLE_CONTENT_PROTECTION_ATTESTATION}, {"enableSuggestedContent", IDS_SETTINGS_ENABLE_SUGGESTED_CONTENT_TITLE}, @@ -126,7 +117,6 @@ std::string PrivacySection::GetSectionPath() const { void PrivacySection::RegisterHierarchy(HierarchyGenerator* generator) const { generator->RegisterTopLevelSetting(mojom::Setting::kVerifiedAccess); - generator->RegisterTopLevelSetting(mojom::Setting::kKeepWifiOnDuringSleep); generator->RegisterTopLevelSetting( mojom::Setting::kUsageStatsAndCrashReports); } diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/reset_section.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/reset_section.cc index 21216088ddc..1d2a250448f 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/reset_section.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/reset_section.cc @@ -6,8 +6,6 @@ #include "base/no_destructor.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" #include "chrome/browser/ui/webui/settings/reset_settings_handler.h" #include "chrome/browser/ui/webui/webui_util.h" @@ -43,9 +41,7 @@ const std::vector<SearchConcept>& GetResetSearchConcepts() { } bool IsPowerwashAllowed() { - policy::BrowserPolicyConnectorChromeOS* connector = - g_browser_process->platform_part()->browser_policy_connector_chromeos(); - return !connector->IsEnterpriseManaged() && + return !webui::IsEnterpriseManaged() && !user_manager::UserManager::Get()->IsLoggedInAsGuest() && !user_manager::UserManager::Get()->IsLoggedInAsSupervisedUser() && !user_manager::UserManager::Get()->IsLoggedInAsChildUser(); diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc index 1bde04057b2..fb6284e9d9f 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc @@ -7,12 +7,13 @@ #include <algorithm> #include "base/strings/string_number_conversions.h" -#include "chrome/browser/chromeos/local_search_service/local_search_service.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/ui/webui/settings/chromeos/hierarchy.h" #include "chrome/browser/ui/webui/settings/chromeos/os_settings_sections.h" #include "chrome/browser/ui/webui/settings/chromeos/search/search_concept.h" #include "chrome/browser/ui/webui/settings/chromeos/search/search_result_icon.mojom.h" #include "chrome/grit/generated_resources.h" +#include "chromeos/components/local_search_service/local_search_service.h" #include "ui/base/l10n/l10n_util.h" namespace chromeos { @@ -48,7 +49,9 @@ SearchHandler::SearchHandler( sections_(sections), hierarchy_(hierarchy), index_(local_search_service->GetIndex( - local_search_service::IndexId::kCrosSettings)) { + local_search_service::IndexId::kCrosSettings, + local_search_service::Backend::kLinearMap, + g_browser_process ? g_browser_process->local_state() : nullptr)) { search_tag_registry_->AddObserver(this); } diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.h index 2425c2b56ac..90ef05dca83 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.h +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler.h @@ -9,20 +9,21 @@ #include "base/gtest_prod_util.h" #include "base/optional.h" -#include "chrome/browser/chromeos/local_search_service/index.h" #include "chrome/browser/ui/webui/settings/chromeos/search/search.mojom.h" #include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" +#include "chromeos/components/local_search_service/index.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver_set.h" #include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/bindings/remote_set.h" +namespace chromeos { + namespace local_search_service { class LocalSearchService; } // namespace local_search_service -namespace chromeos { namespace settings { class Hierarchy; diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc index d0ecd2baef6..52c6502053e 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc @@ -8,13 +8,13 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" -#include "chrome/browser/chromeos/local_search_service/local_search_service.h" #include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h" #include "chrome/browser/ui/webui/settings/chromeos/fake_hierarchy.h" #include "chrome/browser/ui/webui/settings/chromeos/fake_os_settings_sections.h" #include "chrome/browser/ui/webui/settings/chromeos/search/search.mojom-test-utils.h" #include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" #include "chrome/grit/generated_resources.h" +#include "chromeos/components/local_search_service/local_search_service.h" #include "chromeos/constants/chromeos_features.h" #include "mojo/public/cpp/bindings/remote.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.cc index 618022b76ba..1591a342b6d 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.cc @@ -9,8 +9,9 @@ #include "base/feature_list.h" #include "base/strings/string_number_conversions.h" -#include "chrome/browser/chromeos/local_search_service/local_search_service.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/ui/webui/settings/chromeos/search/search_concept.h" +#include "chromeos/components/local_search_service/local_search_service.h" #include "chromeos/constants/chromeos_features.h" #include "ui/base/l10n/l10n_util.h" @@ -100,7 +101,9 @@ void SearchTagRegistry::ScopedTagUpdater::ProcessPendingSearchTags( SearchTagRegistry::SearchTagRegistry( local_search_service::LocalSearchService* local_search_service) : index_(local_search_service->GetIndex( - local_search_service::IndexId::kCrosSettings)) {} + local_search_service::IndexId::kCrosSettings, + local_search_service::Backend::kLinearMap, + g_browser_process ? g_browser_process->local_state() : nullptr)) {} SearchTagRegistry::~SearchTagRegistry() = default; diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h index abd1f83b1fa..1524800f9c5 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h @@ -12,15 +12,16 @@ #include "base/gtest_prod_util.h" #include "base/observer_list.h" #include "base/observer_list_types.h" -#include "chrome/browser/chromeos/local_search_service/index.h" #include "chrome/browser/ui/webui/settings/chromeos/os_settings_section.h" +#include "chromeos/components/local_search_service/index.h" + +namespace chromeos { namespace local_search_service { class Index; class LocalSearchService; } // namespace local_search_service -namespace chromeos { namespace settings { struct SearchConcept; diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry_unittest.cc index 1aebe00ce35..67ab6f4fb00 100644 --- a/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry_unittest.cc +++ b/chromium/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry_unittest.cc @@ -5,11 +5,12 @@ #include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h" #include "base/no_destructor.h" -#include "chrome/browser/chromeos/local_search_service/index.h" -#include "chrome/browser/chromeos/local_search_service/local_search_service.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h" #include "chrome/browser/ui/webui/settings/chromeos/search/search_concept.h" #include "chrome/grit/generated_resources.h" +#include "chromeos/components/local_search_service/index.h" +#include "chromeos/components/local_search_service/local_search_service.h" #include "testing/gtest/include/gtest/gtest.h" namespace chromeos { @@ -69,7 +70,8 @@ class SearchTagRegistryTest : public testing::Test { void SetUp() override { search_tag_registry_.AddObserver(&observer_); index_ = local_search_service_.GetIndex( - local_search_service::IndexId::kCrosSettings); + local_search_service::IndexId::kCrosSettings, + local_search_service::Backend::kLinearMap, nullptr /* local_state */); } void TearDown() override { search_tag_registry_.RemoveObserver(&observer_); } diff --git a/chromium/chrome/browser/ui/webui/settings/font_handler.cc b/chromium/chrome/browser/ui/webui/settings/font_handler.cc index 2597d8c3154..121cecf66f0 100644 --- a/chromium/chrome/browser/ui/webui/settings/font_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/font_handler.cc @@ -20,14 +20,14 @@ #include "content/public/browser/font_list_async.h" #include "content/public/browser/web_ui.h" -#if defined(OS_MACOSX) +#if defined(OS_MAC) #include "chrome/browser/ui/webui/settings_utils.h" #endif namespace settings { FontHandler::FontHandler(Profile* profile) { -#if defined(OS_MACOSX) +#if defined(OS_MAC) // Perform validation for saved fonts. settings_utils::ValidateSavedFonts(profile->GetPrefs()); #endif diff --git a/chromium/chrome/browser/ui/webui/settings/metrics_reporting_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/metrics_reporting_handler_unittest.cc index c33bd5da63e..189c2a837cd 100644 --- a/chromium/chrome/browser/ui/webui/settings/metrics_reporting_handler_unittest.cc +++ b/chromium/chrome/browser/ui/webui/settings/metrics_reporting_handler_unittest.cc @@ -107,8 +107,7 @@ TEST_F(MetricsReportingHandlerTest, PolicyChangesNotifyPage) { // Change the policy, check that the page was notified. map()->Set(policy::key::kMetricsReportingEnabled, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, - policy::POLICY_SOURCE_CLOUD, std::make_unique<base::Value>(true), - nullptr); + policy::POLICY_SOURCE_CLOUD, base::Value(true), nullptr); provider()->UpdateChromePolicy(*map()); EXPECT_EQ(1u, test_web_ui()->call_data().size()); @@ -118,8 +117,7 @@ TEST_F(MetricsReportingHandlerTest, PolicyChangesNotifyPage) { // Policies changing while JavaScript is disabled shouldn't notify the page. map()->Set(policy::key::kMetricsReportingEnabled, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, - policy::POLICY_SOURCE_CLOUD, std::make_unique<base::Value>(false), - nullptr); + policy::POLICY_SOURCE_CLOUD, base::Value(false), nullptr); provider()->UpdateChromePolicy(*map()); EXPECT_TRUE(test_web_ui()->call_data().empty()); } diff --git a/chromium/chrome/browser/ui/webui/settings/people_handler.cc b/chromium/chrome/browser/ui/webui/settings/people_handler.cc index 7e3a8677080..702dce69777 100644 --- a/chromium/chrome/browser/ui/webui/settings/people_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/people_handler.cc @@ -175,9 +175,12 @@ std::string GetSyncErrorAction(sync_ui_util::ActionType action_type) { return "retrieveTrustedVaultKeys"; case sync_ui_util::CONFIRM_SYNC_SETTINGS: return "confirmSyncSettings"; - default: + case sync_ui_util::NO_ACTION: return "noAction"; } + + NOTREACHED(); + return std::string(); } // Returns the base::Value associated with the account, to use in the stored @@ -286,7 +289,7 @@ void PeopleHandler::RegisterMessages() { base::Unretained(this))); web_ui()->RegisterMessageCallback( "SyncSetupShowSetupUI", - base::BindRepeating(&PeopleHandler::HandleShowSetupUI, + base::BindRepeating(&PeopleHandler::HandleShowSyncSetupUI, base::Unretained(this))); web_ui()->RegisterMessageCallback( "SyncSetupGetSyncStatus", @@ -615,7 +618,7 @@ void PeopleHandler::HandleSetEncryption(const base::ListValue* args) { ProfileMetrics::LogProfileSyncInfo(ProfileMetrics::SYNC_PASSPHRASE); } -void PeopleHandler::HandleShowSetupUI(const base::ListValue* args) { +void PeopleHandler::HandleShowSyncSetupUI(const base::ListValue* args) { AllowJavascript(); syncer::SyncService* service = GetSyncService(); @@ -635,6 +638,8 @@ void PeopleHandler::HandleShowSetupUI(const base::ListValue* args) { // Observe the web contents for a before unload event. Observe(web_ui()->GetWebContents()); + MaybeMarkSyncConfiguring(); + PushSyncPrefs(); // Focus the web contents in case the location bar was focused before. This @@ -697,10 +702,13 @@ void PeopleHandler::HandleSignout(const base::ListValue* args) { delete_profile ? signin_metrics::SignoutDelete::DELETED : signin_metrics::SignoutDelete::KEEPING; - // Do not remove the accounts: the Gaia logout tab will remove them in a - // better way (see http://crbug.com/1068978). + // Use ClearAccountsAction::kDefault: if the primary account is still + // valid, it will be removed by the Gaia logout tab + // (see http://crbug.com/1068978). If the account is already invalid, drop + // the token now (because it's already invalid on the web, so the Gaia + // logout tab won't affect it, see http://crbug.com/1114646). identity_manager->GetPrimaryAccountMutator()->ClearPrimaryAccount( - signin::PrimaryAccountMutator::ClearAccountsAction::kKeepAll, + signin::PrimaryAccountMutator::ClearAccountsAction::kDefault, signin_metrics::USER_CLICKED_SIGNOUT_SETTINGS, delete_metric); } else { DCHECK(!delete_profile) @@ -862,9 +870,10 @@ void PeopleHandler::OnPrimaryAccountCleared( void PeopleHandler::OnStateChanged(syncer::SyncService* sync) { UpdateSyncStatus(); - - // When the SyncService changes its state, we should also push the updated - // sync preferences. + // TODO(crbug.com/1106764): Re-evaluate marking sync as configuring here, + // since this gets called whenever ProfileSyncService changes state. Inline + // MaybeMarkSyncConfiguring() then. + MaybeMarkSyncConfiguring(); PushSyncPrefs(); } @@ -952,21 +961,13 @@ std::unique_ptr<base::DictionaryValue> PeopleHandler::GetSyncStatusDictionary() } void PeopleHandler::PushSyncPrefs() { -#if !defined(OS_CHROMEOS) - // Early exit if the user has not signed in yet. - if (IsProfileAuthNeededOrHasErrors()) - return; -#endif - syncer::SyncService* service = GetSyncService(); // The sync service may be nullptr if it has been just disabled by policy. if (!service || !service->IsEngineInitialized()) { return; } - configuring_sync_ = true; - - // Setup args for the sync configure screen: + // Setup values for the JSON response: // syncAllDataTypes: true if the user wants to sync everything // <data_type>Registered: true if the associated data type is supported // <data_type>Synced: true if the user wants to sync that specific data type @@ -1064,6 +1065,17 @@ void PeopleHandler::MarkFirstSetupComplete() { FireWebUIListener("sync-settings-saved"); } +void PeopleHandler::MaybeMarkSyncConfiguring() { +#if !defined(OS_CHROMEOS) + if (IsProfileAuthNeededOrHasErrors()) + return; +#endif + syncer::SyncService* service = GetSyncService(); + // The sync service may be nullptr if it has been just disabled by policy. + if (service && service->IsEngineInitialized()) + configuring_sync_ = true; +} + bool PeopleHandler::IsProfileAuthNeededOrHasErrors() { return !IdentityManagerFactory::GetForProfile(profile_) ->HasPrimaryAccount() || diff --git a/chromium/chrome/browser/ui/webui/settings/people_handler.h b/chromium/chrome/browser/ui/webui/settings/people_handler.h index 50093e129c3..a27f0a153ec 100644 --- a/chromium/chrome/browser/ui/webui/settings/people_handler.h +++ b/chromium/chrome/browser/ui/webui/settings/people_handler.h @@ -152,7 +152,7 @@ class PeopleHandler : public SettingsPageUIHandler, void OnDidClosePage(const base::ListValue* args); void HandleSetDatatypes(const base::ListValue* args); void HandleSetEncryption(const base::ListValue* args); - void HandleShowSetupUI(const base::ListValue* args); + void HandleShowSyncSetupUI(const base::ListValue* args); void HandleSyncPrefsDispatch(const base::ListValue* args); #if defined(OS_CHROMEOS) void HandleAttemptUserExit(const base::ListValue* args); @@ -190,6 +190,9 @@ class PeopleHandler : public SettingsPageUIHandler, // Suppresses any further signin promos, since the user has signed in once. void MarkFirstSetupComplete(); + // If sync is indeed being configured, sets |configuring_sync_| to true. + void MaybeMarkSyncConfiguring(); + // True if profile needs authentication before sync can run. bool IsProfileAuthNeededOrHasErrors(); diff --git a/chromium/chrome/browser/ui/webui/settings/people_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/people_handler_unittest.cc index e35907dc4dd..7865dd365a5 100644 --- a/chromium/chrome/browser/ui/webui/settings/people_handler_unittest.cc +++ b/chromium/chrome/browser/ui/webui/settings/people_handler_unittest.cc @@ -413,7 +413,7 @@ TEST_F(PeopleHandlerTest, DisplayConfigureWithEngineDisabledAndCancel) { // engine will try to download control data types (e.g encryption info), but // that won't finish for this test as we're simulating cancelling while the // spinner is showing. - handler_->HandleShowSetupUI(nullptr); + handler_->HandleShowSyncSetupUI(nullptr); EXPECT_EQ( handler_.get(), @@ -447,7 +447,7 @@ TEST_F(PeopleHandlerTest, SetSyncRequested(true)); SetDefaultExpectationsForConfigPage(); - handler_->HandleShowSetupUI(nullptr); + handler_->HandleShowSyncSetupUI(nullptr); // No data is sent yet, because the engine is not initialized. EXPECT_EQ(0U, web_ui_.call_data().size()); @@ -488,7 +488,7 @@ TEST_F(PeopleHandlerTest, EXPECT_CALL(*mock_sync_service_->GetMockUserSettings(), SetSyncRequested(true)); SetDefaultExpectationsForConfigPage(); - handler_->HandleShowSetupUI(nullptr); + handler_->HandleShowSyncSetupUI(nullptr); // Sync engine becomes active, so |handler_| is notified. NotifySyncStateChanged(); @@ -530,7 +530,7 @@ TEST_F(PeopleHandlerTest, RestartSyncAfterDashboardClear) { Return(syncer::SyncService::TransportState::INITIALIZING)); }); - handler_->HandleShowSetupUI(nullptr); + handler_->HandleShowSyncSetupUI(nullptr); // Since the engine is not initialized yet, no data should be sent. EXPECT_EQ(0U, web_ui_.call_data().size()); @@ -563,7 +563,7 @@ TEST_F(PeopleHandlerTest, Return(syncer::SyncService::TransportState::CONFIGURING)); }); - handler_->HandleShowSetupUI(nullptr); + handler_->HandleShowSyncSetupUI(nullptr); // Since the engine was already running, we should *not* get a spinner - all // the necessary values are already available. ExpectSyncPrefsChanged(); @@ -614,7 +614,7 @@ TEST_F(PeopleHandlerTest, UnrecoverableErrorInitializingSync) { ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsFirstSetupComplete()) .WillByDefault(Return(false)); // Open the web UI. - handler_->HandleShowSetupUI(nullptr); + handler_->HandleShowSyncSetupUI(nullptr); ASSERT_FALSE(handler_->is_configuring_sync()); } @@ -627,7 +627,7 @@ TEST_F(PeopleHandlerTest, GaiaErrorInitializingSync) { ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsFirstSetupComplete()) .WillByDefault(Return(false)); // Open the web UI. - handler_->HandleShowSetupUI(nullptr); + handler_->HandleShowSyncSetupUI(nullptr); ASSERT_FALSE(handler_->is_configuring_sync()); } @@ -888,7 +888,7 @@ TEST_F(PeopleHandlerTest, ShowSyncSetup) { SetupInitializedSyncService(); // This should display the sync setup dialog (not login). SetDefaultExpectationsForConfigPage(); - handler_->HandleShowSetupUI(nullptr); + handler_->HandleShowSyncSetupUI(nullptr); ExpectSyncPrefsChanged(); } @@ -904,7 +904,7 @@ TEST_F(PeopleHandlerTest, ShowSetupSyncEverything) { SetupInitializedSyncService(); SetDefaultExpectationsForConfigPage(); // This should display the sync setup dialog (not login). - handler_->HandleShowSetupUI(nullptr); + handler_->HandleShowSyncSetupUI(nullptr); const base::DictionaryValue* dictionary = ExpectSyncPrefsChanged(); CheckBool(dictionary, "syncAllDataTypes", true); @@ -936,7 +936,7 @@ TEST_F(PeopleHandlerTest, ShowSetupManuallySyncAll) { ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsSyncEverythingEnabled()) .WillByDefault(Return(false)); // This should display the sync setup dialog (not login). - handler_->HandleShowSetupUI(nullptr); + handler_->HandleShowSyncSetupUI(nullptr); const base::DictionaryValue* dictionary = ExpectSyncPrefsChanged(); CheckConfigDataTypeArguments(dictionary, CHOOSE_WHAT_TO_SYNC, GetAllTypes()); @@ -961,7 +961,7 @@ TEST_F(PeopleHandlerTest, ShowSetupSyncForAllTypesIndividually) { .WillByDefault(Return(types)); // This should display the sync setup dialog (not login). - handler_->HandleShowSetupUI(nullptr); + handler_->HandleShowSyncSetupUI(nullptr); // Close the config overlay. LoginUIServiceFactory::GetForProfile(profile())->LoginUIClosed( @@ -986,7 +986,7 @@ TEST_F(PeopleHandlerTest, ShowSetupOldGaiaPassphraseRequired) { SetDefaultExpectationsForConfigPage(); // This should display the sync setup dialog (not login). - handler_->HandleShowSetupUI(nullptr); + handler_->HandleShowSyncSetupUI(nullptr); const base::DictionaryValue* dictionary = ExpectSyncPrefsChanged(); CheckBool(dictionary, "passphraseRequired", true); @@ -1004,7 +1004,7 @@ TEST_F(PeopleHandlerTest, ShowSetupCustomPassphraseRequired) { SetDefaultExpectationsForConfigPage(); // This should display the sync setup dialog (not login). - handler_->HandleShowSetupUI(nullptr); + handler_->HandleShowSyncSetupUI(nullptr); const base::DictionaryValue* dictionary = ExpectSyncPrefsChanged(); CheckBool(dictionary, "passphraseRequired", true); @@ -1023,7 +1023,7 @@ TEST_F(PeopleHandlerTest, ShowSetupTrustedVaultKeysRequired) { SetDefaultExpectationsForConfigPage(); // This should display the sync setup dialog (not login). - handler_->HandleShowSetupUI(nullptr); + handler_->HandleShowSyncSetupUI(nullptr); const base::DictionaryValue* dictionary = ExpectSyncPrefsChanged(); CheckBool(dictionary, "passphraseRequired", false); @@ -1046,7 +1046,7 @@ TEST_F(PeopleHandlerTest, ShowSetupEncryptAll) { .WillByDefault(Return(true)); // This should display the sync setup dialog (not login). - handler_->HandleShowSetupUI(nullptr); + handler_->HandleShowSyncSetupUI(nullptr); const base::DictionaryValue* dictionary = ExpectSyncPrefsChanged(); CheckBool(dictionary, "encryptAllData", true); @@ -1067,7 +1067,7 @@ TEST_F(PeopleHandlerTest, ShowSetupEncryptAllDisallowed) { .WillByDefault(Return(false)); // This should display the sync setup dialog (not login). - handler_->HandleShowSetupUI(nullptr); + handler_->HandleShowSyncSetupUI(nullptr); const base::DictionaryValue* dictionary = ExpectSyncPrefsChanged(); CheckBool(dictionary, "encryptAllData", false); @@ -1113,7 +1113,7 @@ TEST_F(PeopleHandlerTest, DashboardClearWhileSettingsOpen_ConfirmSoon) { // Sync starts out fully enabled. SetDefaultExpectationsForConfigPage(); - handler_->HandleShowSetupUI(nullptr); + handler_->HandleShowSyncSetupUI(nullptr); // Now sync gets reset from the dashboard (the user clicked the "Manage synced // data" link), which results in the sync-requested and first-setup-complete @@ -1168,7 +1168,7 @@ TEST_F(PeopleHandlerTest, DashboardClearWhileSettingsOpen_ConfirmLater) { // Sync starts out fully enabled. SetDefaultExpectationsForConfigPage(); - handler_->HandleShowSetupUI(nullptr); + handler_->HandleShowSyncSetupUI(nullptr); // Now sync gets reset from the dashboard (the user clicked the "Manage synced // data" link), which results in the sync-requested and first-setup-complete diff --git a/chromium/chrome/browser/ui/webui/settings/reset_settings_handler.cc b/chromium/chrome/browser/ui/webui/settings/reset_settings_handler.cc index f689a4343bb..10c424f4fd5 100644 --- a/chromium/chrome/browser/ui/webui/settings/reset_settings_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/reset_settings_handler.cc @@ -225,7 +225,7 @@ void ResetSettingsHandler::OnHideResetProfileBanner( void ResetSettingsHandler::OnSettingsFetched() { DCHECK(config_fetcher_); DCHECK(!config_fetcher_->IsActive()); - // The master prefs is fetched. We are waiting for user pressing 'Reset'. + // The initial prefs is fetched. We are waiting for user pressing 'Reset'. } void ResetSettingsHandler::ResetProfile( diff --git a/chromium/chrome/browser/ui/webui/settings/reset_settings_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/reset_settings_handler_unittest.cc index b21f85e169b..4800e171f3d 100644 --- a/chromium/chrome/browser/ui/webui/settings/reset_settings_handler_unittest.cc +++ b/chromium/chrome/browser/ui/webui/settings/reset_settings_handler_unittest.cc @@ -31,10 +31,10 @@ class MockProfileResetter : public ProfileResetter { } void Reset(ResettableFlags resettable_flags, - std::unique_ptr<BrandcodedDefaultSettings> master_settings, - const base::Closure& callback) override { + std::unique_ptr<BrandcodedDefaultSettings> initial_settings, + base::OnceClosure callback) override { resets_++; - callback.Run(); + std::move(callback).Run(); } size_t resets() const { diff --git a/chromium/chrome/browser/ui/webui/settings/safe_browsing_handler.cc b/chromium/chrome/browser/ui/webui/settings/safe_browsing_handler.cc deleted file mode 100644 index 7403e565a5a..00000000000 --- a/chromium/chrome/browser/ui/webui/settings/safe_browsing_handler.cc +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/settings/safe_browsing_handler.h" - -#include "components/prefs/pref_change_registrar.h" -#include "components/prefs/pref_service.h" -#include "components/safe_browsing/core/common/safe_browsing_prefs.h" -#include "components/safe_browsing/core/features.h" - -namespace settings { - -SafeBrowsingHandler::SafeBrowsingHandler(Profile* profile) - : profile_(profile) {} -SafeBrowsingHandler::~SafeBrowsingHandler() = default; - -void SafeBrowsingHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback( - "getSafeBrowsingRadioManagedState", - base::BindRepeating( - &SafeBrowsingHandler::HandleGetSafeBrowsingRadioManagedState, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "validateSafeBrowsingEnhanced", - base::BindRepeating( - &SafeBrowsingHandler::HandleValidateSafeBrowsingEnhanced, - base::Unretained(this))); -} - -void SafeBrowsingHandler::HandleGetSafeBrowsingRadioManagedState( - const base::ListValue* args) { - AllowJavascript(); - CHECK_EQ(1U, args->GetList().size()); - std::string callback_id = args->GetList()[0].GetString(); - - auto state = GetSafeBrowsingRadioManagedState(profile_); - - base::Value result(base::Value::Type::DICTIONARY); - // TODO(crbug.com/1063265): Move managed state functions out of site_settings. - result.SetKey(kSafeBrowsingEnhanced, - site_settings::GetValueForManagedState(state.enhanced)); - result.SetKey(kSafeBrowsingStandard, - site_settings::GetValueForManagedState(state.standard)); - result.SetKey(kSafeBrowsingDisabled, - site_settings::GetValueForManagedState(state.disabled)); - - ResolveJavascriptCallback(base::Value(callback_id), result); -} - -void SafeBrowsingHandler::HandleValidateSafeBrowsingEnhanced( - const base::ListValue* args) { - // TODO(crbug.com/1074499) Remove this logic when Enhanced protection is - // considered stable. - if (!base::FeatureList::IsEnabled(safe_browsing::kEnhancedProtection)) - profile_->GetPrefs()->SetBoolean(prefs::kSafeBrowsingEnhanced, false); -} - -SafeBrowsingRadioManagedState -SafeBrowsingHandler::GetSafeBrowsingRadioManagedState(Profile* profile) { - // Create a default managed state that is updated based on preferences. - SafeBrowsingRadioManagedState managed_state; - - // Computing the effective Safe Browsing managed state requires inspecting - // three different preferences. It is possible that these may be in - // temporarily conflicting managed states. The enabled preference is always - // taken as the canonical source of management. - const PrefService::Preference* enabled_pref = - profile->GetPrefs()->FindPreference(prefs::kSafeBrowsingEnabled); - const bool enabled_enforced = !enabled_pref->IsUserModifiable(); - const bool enabled_recommended = - (enabled_pref && enabled_pref->GetRecommendedValue()); - const bool enabled_recommended_on = - enabled_recommended && enabled_pref->GetRecommendedValue()->GetBool(); - const auto enabled_policy_indicator = - site_settings::GetPolicyIndicatorFromPref(enabled_pref); - - // The enhanced preference may have a recommended setting. This only takes - // effect if the enabled preference also has a recommended setting. - const PrefService::Preference* enhanced_pref = - profile->GetPrefs()->FindPreference(prefs::kSafeBrowsingEnhanced); - const bool enhanced_recommended_on = - enhanced_pref->GetRecommendedValue() && - enhanced_pref->GetRecommendedValue()->GetBool(); - - // A forcefully disabled reporting preference will disallow enhanced from - // being selected and thus it must also be considered. - const PrefService::Preference* reporting_pref = - profile->GetPrefs()->FindPreference( - prefs::kSafeBrowsingScoutReportingEnabled); - const bool reporting_on = reporting_pref->GetValue()->GetBool(); - const bool reporting_enforced = !reporting_pref->IsUserModifiable(); - const auto reporting_policy_indicator = - site_settings::GetPolicyIndicatorFromPref(reporting_pref); - - if (!enabled_enforced && !enabled_recommended && !reporting_enforced) { - // No relevant policies are applied, return the default state. - return managed_state; - } - if (enabled_enforced) { - // All radio controls are managed. - managed_state.enhanced.disabled = true; - managed_state.enhanced.indicator = enabled_policy_indicator; - managed_state.standard.disabled = true; - managed_state.standard.indicator = enabled_policy_indicator; - managed_state.disabled.disabled = true; - managed_state.disabled.indicator = enabled_policy_indicator; - return managed_state; - } - if (enabled_recommended) { - if (enhanced_recommended_on) { - managed_state.enhanced.indicator = enabled_policy_indicator; - } else if (enabled_recommended_on) { - managed_state.standard.indicator = enabled_policy_indicator; - } else { - managed_state.disabled.indicator = enabled_policy_indicator; - } - return managed_state; - } - if (reporting_enforced && !reporting_on) { - // Disable enhanced protection when reporting has been enforced off. - managed_state.enhanced.disabled = true; - managed_state.enhanced.indicator = reporting_policy_indicator; - return managed_state; - } - - return managed_state; -} - -} // namespace settings diff --git a/chromium/chrome/browser/ui/webui/settings/safe_browsing_handler.h b/chromium/chrome/browser/ui/webui/settings/safe_browsing_handler.h deleted file mode 100644 index a92e70ad9ab..00000000000 --- a/chromium/chrome/browser/ui/webui/settings/safe_browsing_handler.h +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_SAFE_BROWSING_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_SETTINGS_SAFE_BROWSING_HANDLER_H_ - -#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" -#include "chrome/browser/ui/webui/settings/site_settings_helper.h" - -#include "chrome/browser/profiles/profile.h" - -namespace settings { - -constexpr char kSafeBrowsingEnhanced[] = "enhanced"; -constexpr char kSafeBrowsingStandard[] = "standard"; -constexpr char kSafeBrowsingDisabled[] = "disabled"; - -struct SafeBrowsingRadioManagedState { - site_settings::ManagedState enhanced; - site_settings::ManagedState standard; - site_settings::ManagedState disabled; -}; - -// Settings page UI handler that provides representation of Safe Browsing -// settings. -class SafeBrowsingHandler : public SettingsPageUIHandler { - public: - explicit SafeBrowsingHandler(Profile* profile); - ~SafeBrowsingHandler() override; - - // WebUIMessageHandler implementation. - void RegisterMessages() override; - - // Calculate and return the current Safe Browsing radio buttons. - void HandleGetSafeBrowsingRadioManagedState(const base::ListValue* args); - - // Confirm that the current Safe Browsing Enhanced preference is appropriate - // for the currently enabled features, updating it if required. - void HandleValidateSafeBrowsingEnhanced(const base::ListValue* args); - - private: - friend class SafeBrowsingHandlerTest; - FRIEND_TEST_ALL_PREFIXES(SafeBrowsingHandlerTest, GenerateRadioManagedState); - FRIEND_TEST_ALL_PREFIXES(SafeBrowsingHandlerTest, ProvideRadioManagedState); - - // SettingsPageUIHandler implementation. - void OnJavascriptAllowed() override {} - void OnJavascriptDisallowed() override {} - - // Calculate the current Safe Browsing control state for the provided profile. - static SafeBrowsingRadioManagedState GetSafeBrowsingRadioManagedState( - Profile* profile); - - Profile* profile_; - - DISALLOW_COPY_AND_ASSIGN(SafeBrowsingHandler); -}; - -} // namespace settings - -#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_SAFE_BROWSING_HANDLER_H_ diff --git a/chromium/chrome/browser/ui/webui/settings/safe_browsing_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/safe_browsing_handler_unittest.cc deleted file mode 100644 index 3065bc295e2..00000000000 --- a/chromium/chrome/browser/ui/webui/settings/safe_browsing_handler_unittest.cc +++ /dev/null @@ -1,248 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/settings/safe_browsing_handler.h" - -#include <memory> -#include <string> - -#include "base/test/scoped_feature_list.h" -#include "base/values.h" -#include "chrome/test/base/chrome_render_view_host_test_harness.h" -#include "chrome/test/base/testing_profile.h" -#include "components/prefs/pref_service.h" -#include "components/safe_browsing/core/common/safe_browsing_prefs.h" -#include "components/safe_browsing/core/features.h" -#include "components/sync_preferences/testing_pref_service_syncable.h" -#include "content/public/test/browser_task_environment.h" -#include "content/public/test/test_web_ui.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace settings { - -class SafeBrowsingHandlerTest : public testing::Test { - public: - void SetUp() override { - handler_ = std::make_unique<SafeBrowsingHandler>(profile()); - handler()->set_web_ui(web_ui()); - handler()->AllowJavascript(); - web_ui()->ClearTrackedCalls(); - } - - TestingProfile* profile() { return &profile_; } - content::TestWebUI* web_ui() { return &web_ui_; } - SafeBrowsingHandler* handler() { return handler_.get(); } - - private: - content::BrowserTaskEnvironment task_environment_; - std::unique_ptr<SafeBrowsingHandler> handler_; - TestingProfile profile_; - content::TestWebUI web_ui_; -}; - -// All of the possible managed states for a boolean preference that can be -// both enforced and recommended. -// TODO(crbug.com/1063265): Remove duplication with site_settings_helper. -enum class PrefSetting { - kEnforcedOff, - kEnforcedOn, - kRecommendedOff, - kRecommendedOn, - kNotSet, -}; - -// Possible preference sources supported by TestingPrefService. -// TODO(crbug.com/1063265): Remove duplication with site_settings_helper. -enum class PrefSource { - kExtension, - kDevicePolicy, - kRecommended, - kNone, -}; - -void AssertRadioManagedStateEqual(const SafeBrowsingRadioManagedState& a, - const SafeBrowsingRadioManagedState& b) { - ASSERT_EQ(a.enhanced.disabled, b.enhanced.disabled); - ASSERT_EQ(a.enhanced.indicator, b.enhanced.indicator); - ASSERT_EQ(a.standard.disabled, b.standard.disabled); - ASSERT_EQ(a.standard.indicator, b.standard.indicator); - ASSERT_EQ(a.disabled.disabled, b.disabled.disabled); - ASSERT_EQ(a.disabled.indicator, b.disabled.indicator); -} - -struct RadioManagedStateTestCase { - PrefSetting safe_browsing_enhanced; - PrefSetting safe_browsing_enabled; - PrefSetting safe_browsing_reporting; - PrefSource preference_source; - SafeBrowsingRadioManagedState expected_result; -}; - -const std::vector<RadioManagedStateTestCase> test_cases = { - {PrefSetting::kNotSet, - PrefSetting::kNotSet, - PrefSetting::kNotSet, - PrefSource::kNone, - {{false, site_settings::PolicyIndicatorType::kNone}, - {false, site_settings::PolicyIndicatorType::kNone}, - {false, site_settings::PolicyIndicatorType::kNone}}}, - {PrefSetting::kEnforcedOn, - PrefSetting::kEnforcedOn, - PrefSetting::kNotSet, - PrefSource::kExtension, - {{true, site_settings::PolicyIndicatorType::kExtension}, - {true, site_settings::PolicyIndicatorType::kExtension}, - {true, site_settings::PolicyIndicatorType::kExtension}}}, - {PrefSetting::kEnforcedOff, - PrefSetting::kEnforcedOff, - PrefSetting::kNotSet, - PrefSource::kDevicePolicy, - {{true, site_settings::PolicyIndicatorType::kDevicePolicy}, - {true, site_settings::PolicyIndicatorType::kDevicePolicy}, - {true, site_settings::PolicyIndicatorType::kDevicePolicy}}}, - {PrefSetting::kEnforcedOff, - PrefSetting::kEnforcedOn, - PrefSetting::kNotSet, - PrefSource::kExtension, - {{true, site_settings::PolicyIndicatorType::kExtension}, - {true, site_settings::PolicyIndicatorType::kExtension}, - {true, site_settings::PolicyIndicatorType::kExtension}}}, - {PrefSetting::kRecommendedOn, - PrefSetting::kRecommendedOn, - PrefSetting::kNotSet, - PrefSource::kRecommended, - {{false, site_settings::PolicyIndicatorType::kRecommended}, - {false, site_settings::PolicyIndicatorType::kNone}, - {false, site_settings::PolicyIndicatorType::kNone}}}, - {PrefSetting::kRecommendedOff, - PrefSetting::kRecommendedOn, - PrefSetting::kNotSet, - PrefSource::kRecommended, - {{false, site_settings::PolicyIndicatorType::kNone}, - {false, site_settings::PolicyIndicatorType::kRecommended}, - {false, site_settings::PolicyIndicatorType::kNone}}}, - {PrefSetting::kRecommendedOff, - PrefSetting::kRecommendedOff, - PrefSetting::kNotSet, - PrefSource::kRecommended, - {{false, site_settings::PolicyIndicatorType::kNone}, - {false, site_settings::PolicyIndicatorType::kNone}, - {false, site_settings::PolicyIndicatorType::kRecommended}}}, - {PrefSetting::kNotSet, - PrefSetting::kNotSet, - PrefSetting::kEnforcedOff, - PrefSource::kDevicePolicy, - {{true, site_settings::PolicyIndicatorType::kDevicePolicy}, - {false, site_settings::PolicyIndicatorType::kNone}, - {false, site_settings::PolicyIndicatorType::kNone}}}}; - -void SetupTestConditions(TestingProfile* profile, - const RadioManagedStateTestCase& test_case) { - sync_preferences::TestingPrefServiceSyncable* prefs = - profile->GetTestingPrefService(); - const std::map<const char*, PrefSetting> pref_to_setting = { - {prefs::kSafeBrowsingEnhanced, test_case.safe_browsing_enhanced}, - {prefs::kSafeBrowsingEnabled, test_case.safe_browsing_enabled}, - {prefs::kSafeBrowsingScoutReportingEnabled, - test_case.safe_browsing_reporting}}; - - for (const auto& pref_setting : pref_to_setting) { - if (pref_setting.second == PrefSetting::kNotSet) { - continue; - } - auto pref_value = std::make_unique<base::Value>( - pref_setting.second == PrefSetting::kRecommendedOn || - pref_setting.second == PrefSetting::kEnforcedOn); - if (test_case.preference_source == PrefSource::kExtension) { - prefs->SetExtensionPref(pref_setting.first, std::move(pref_value)); - } else if (test_case.preference_source == PrefSource::kDevicePolicy) { - prefs->SetManagedPref(pref_setting.first, std::move(pref_value)); - } else if (test_case.preference_source == PrefSource::kRecommended) { - prefs->SetRecommendedPref(pref_setting.first, std::move(pref_value)); - } - } -} - -TEST_F(SafeBrowsingHandlerTest, GenerateRadioManagedState) { - int count = 0; - for (const auto& test_case : test_cases) { - TestingProfile profile; - SCOPED_TRACE(base::StringPrintf("Test case %d", count++)); - SetupTestConditions(&profile, test_case); - AssertRadioManagedStateEqual( - handler()->GetSafeBrowsingRadioManagedState(&profile), - test_case.expected_result); - } -} - -TEST_F(SafeBrowsingHandlerTest, ProvideRadioManagedState) { - // Test that the handler correctly wraps the generated result. - const std::string kNone = "none"; - const std::string kDevicePolicy = "devicePolicy"; - const std::string kCallbackId = "callback"; - const std::vector<std::string> kRadioNames = {"enhanced", "standard", - "disabled"}; - - // Check that the default radio state is handled correctly. - base::ListValue get_args; - get_args.AppendString(kCallbackId); - handler()->HandleGetSafeBrowsingRadioManagedState(&get_args); - { - const content::TestWebUI::CallData& data = *web_ui()->call_data().back(); - EXPECT_EQ("cr.webUIResponse", data.function_name()); - EXPECT_EQ(kCallbackId, data.arg1()->GetString()); - ASSERT_TRUE(data.arg2()->GetBool()); - for (const auto& control_name : kRadioNames) { - auto* control_state = data.arg3()->FindPath(control_name); - ASSERT_FALSE(control_state->FindKey("disabled")->GetBool()); - ASSERT_EQ(kNone, control_state->FindKey("indicator")->GetString()); - } - } - - // Create a fully managed state and check it is returned correctly. - sync_preferences::TestingPrefServiceSyncable* pref_service = - profile()->GetTestingPrefService(); - pref_service->SetManagedPref(prefs::kSafeBrowsingEnhanced, - std::make_unique<base::Value>(true)); - pref_service->SetManagedPref(prefs::kSafeBrowsingEnabled, - std::make_unique<base::Value>(true)); - - handler()->HandleGetSafeBrowsingRadioManagedState(&get_args); - { - const content::TestWebUI::CallData& data = *web_ui()->call_data().back(); - EXPECT_EQ("cr.webUIResponse", data.function_name()); - EXPECT_EQ(kCallbackId, data.arg1()->GetString()); - ASSERT_TRUE(data.arg2()->GetBool()); - for (const auto& control_name : kRadioNames) { - auto* control_state = data.arg3()->FindPath(control_name); - ASSERT_TRUE(control_state->FindKey("disabled")->GetBool()); - ASSERT_EQ(kDevicePolicy, - control_state->FindKey("indicator")->GetString()); - } - } -} - -TEST_F(SafeBrowsingHandlerTest, ValidateSafeBrowsingPrefs) { - base::ListValue args; - base::test::ScopedFeatureList scoped_feature_list_; - sync_preferences::TestingPrefServiceSyncable* pref_service = - profile()->GetTestingPrefService(); - - pref_service->SetBoolean(prefs::kSafeBrowsingEnhanced, true); - - // Ensure the preference is not changed when the Enhanced feature is enabled. - scoped_feature_list_.InitWithFeatures({safe_browsing::kEnhancedProtection}, - {}); - handler()->HandleValidateSafeBrowsingEnhanced(&args); - EXPECT_TRUE(pref_service->GetBoolean(prefs::kSafeBrowsingEnhanced)); - scoped_feature_list_.Reset(); - - // Ensure the preference is disabled when the Enhanced feature is disabled. - scoped_feature_list_.InitWithFeatures({}, - {safe_browsing::kEnhancedProtection}); - handler()->HandleValidateSafeBrowsingEnhanced(&args); - EXPECT_FALSE(pref_service->GetBoolean(prefs::kSafeBrowsingEnhanced)); -} - -} // namespace settings diff --git a/chromium/chrome/browser/ui/webui/settings/safety_check_handler.cc b/chromium/chrome/browser/ui/webui/settings/safety_check_handler.cc index 81877f13bcf..20aa230a020 100644 --- a/chromium/chrome/browser/ui/webui/settings/safety_check_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/safety_check_handler.cc @@ -6,15 +6,16 @@ #include "base/bind.h" #include "base/i18n/number_formatting.h" +#include "base/macros.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" -#include "build/build_config.h" #include "chrome/browser/extensions/api/passwords_private/passwords_private_delegate_factory.h" #include "chrome/browser/password_manager/bulk_leak_check_service_factory.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/webui/version_ui.h" #include "chrome/common/channel_info.h" #include "chrome/common/url_constants.h" #include "chrome/grit/chromium_strings.h" @@ -30,6 +31,10 @@ #include "extensions/common/extension_id.h" #include "ui/base/l10n/l10n_util.h" +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) +#include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h" +#endif + #if defined(OS_CHROMEOS) #include "ui/chromeos/devicetype_utils.h" #endif @@ -43,6 +48,10 @@ constexpr char kPasswordsEvent[] = "safety-check-passwords-status-changed"; constexpr char kSafeBrowsingEvent[] = "safety-check-safe-browsing-status-changed"; constexpr char kExtensionsEvent[] = "safety-check-extensions-status-changed"; +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) +constexpr char kChromeCleanerEvent[] = + "safety-check-chrome-cleaner-status-changed"; +#endif constexpr char kPerformSafetyCheck[] = "performSafetyCheck"; constexpr char kGetParentRanDisplayString[] = "getSafetyCheckRanDisplayString"; constexpr char kNewState[] = "newState"; @@ -80,11 +89,69 @@ SafetyCheckHandler::UpdateStatus ConvertToUpdateStatus( return SafetyCheckHandler::UpdateStatus::kFailedOffline; } } + +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) +SafetyCheckHandler::ChromeCleanerStatus ConvertToChromeCleanerStatus( + safe_browsing::ChromeCleanerController::State state, + safe_browsing::ChromeCleanerController::IdleReason idle_reason) { + switch (state) { + case safe_browsing::ChromeCleanerController::State::kIdle: + switch (idle_reason) { + case safe_browsing::ChromeCleanerController::IdleReason::kInitial: + case safe_browsing::ChromeCleanerController::IdleReason:: + kReporterFoundNothing: + case safe_browsing::ChromeCleanerController::IdleReason:: + kReporterFailed: + case safe_browsing::ChromeCleanerController::IdleReason:: + kScanningFoundNothing: + case safe_browsing::ChromeCleanerController::IdleReason:: + kScanningFailed: + case safe_browsing::ChromeCleanerController::IdleReason:: + kCleaningFailed: + case safe_browsing::ChromeCleanerController::IdleReason:: + kCleaningSucceeded: + case safe_browsing::ChromeCleanerController::IdleReason:: + kCleanerDownloadFailed: + return SafetyCheckHandler::ChromeCleanerStatus::kHidden; + case safe_browsing::ChromeCleanerController::IdleReason:: + kConnectionLost: + case safe_browsing::ChromeCleanerController::IdleReason:: + kUserDeclinedCleanup: + return SafetyCheckHandler::ChromeCleanerStatus::kInfected; + } + case safe_browsing::ChromeCleanerController::State::kReporterRunning: + case safe_browsing::ChromeCleanerController::State::kScanning: + case safe_browsing::ChromeCleanerController::State::kCleaning: + return SafetyCheckHandler::ChromeCleanerStatus::kHidden; + case safe_browsing::ChromeCleanerController::State::kInfected: + return SafetyCheckHandler::ChromeCleanerStatus::kInfected; + case safe_browsing::ChromeCleanerController::State::kRebootRequired: + return SafetyCheckHandler::ChromeCleanerStatus::kRebootRequired; + } +} + +SafetyCheckHandler::ChromeCleanerStatus fetchCurrentChromeCleanerStatus() { + if (!safe_browsing::ChromeCleanerController::GetInstance() + ->IsAllowedByPolicy()) { + return SafetyCheckHandler::ChromeCleanerStatus::kHidden; + } + return ConvertToChromeCleanerStatus( + safe_browsing::ChromeCleanerController::GetInstance()->state(), + safe_browsing::ChromeCleanerController::GetInstance()->idle_reason()); +} +#endif } // namespace SafetyCheckHandler::SafetyCheckHandler() = default; -SafetyCheckHandler::~SafetyCheckHandler() = default; +SafetyCheckHandler::~SafetyCheckHandler() { +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + // It seems |OnJavascriptDisallowed| is not always called before the + // deconstructor. Remove the CCT observer (no-op if not registered) + // also here to ensure it does not stay registered. + safe_browsing::ChromeCleanerController::GetInstance()->RemoveObserver(this); +#endif +} void SafetyCheckHandler::SendSafetyCheckStartedWebUiUpdates() { AllowJavascript(); @@ -96,11 +163,18 @@ void SafetyCheckHandler::SendSafetyCheckStartedWebUiUpdates() { passwords_status_ = PasswordsStatus::kChecking; safe_browsing_status_ = SafeBrowsingStatus::kChecking; extensions_status_ = ExtensionsStatus::kChecking; +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + // If the Chrome cleaner status results in the child being hidden, + // then also hide it already in the "running" state. + if (fetchCurrentChromeCleanerStatus() == + SafetyCheckHandler::ChromeCleanerStatus::kHidden) { + chrome_cleaner_status_ = SafetyCheckHandler::ChromeCleanerStatus::kHidden; + } else { + chrome_cleaner_status_ = SafetyCheckHandler::ChromeCleanerStatus::kChecking; + } +#endif // Update WebUi. - FireBasicSafetyCheckWebUiListener(kParentEvent, - static_cast<int>(parent_status_), - GetStringForParent(parent_status_)); FireBasicSafetyCheckWebUiListener(kUpdatesEvent, static_cast<int>(update_status_), GetStringForUpdates(update_status_)); @@ -115,14 +189,18 @@ void SafetyCheckHandler::SendSafetyCheckStartedWebUiUpdates() { kExtensionsEvent, static_cast<int>(extensions_status_), GetStringForExtensions(extensions_status_, Blocklisted(0), ReenabledUser(0), ReenabledAdmin(0))); +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + FireBasicSafetyCheckWebUiListener( + kChromeCleanerEvent, static_cast<int>(chrome_cleaner_status_), + GetStringForChromeCleaner(chrome_cleaner_status_)); +#endif + // Parent update is last as it reveals the children elements. + FireBasicSafetyCheckWebUiListener(kParentEvent, + static_cast<int>(parent_status_), + GetStringForParent(parent_status_)); } void SafetyCheckHandler::PerformSafetyCheck() { - // If the user refreshes the Settings tab in the delay between starting safety - // check and now, then the check should no longer be run. - if (!IsJavascriptAllowed()) - return; - // Checks common to desktop, Android, and iOS are handled by // safety_check::SafetyCheck. safety_check_.reset(new safety_check::SafetyCheck(this)); @@ -166,6 +244,10 @@ void SafetyCheckHandler::PerformSafetyCheck() { } DCHECK(extension_service_); CheckExtensions(); + +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + CheckChromeCleaner(); +#endif } SafetyCheckHandler::SafetyCheckHandler( @@ -231,17 +313,17 @@ void SafetyCheckHandler::CheckExtensions() { int reenabled_by_user = 0; int reenabled_by_admin = 0; for (auto extension_id : extensions) { - extensions::BlacklistState state = - extension_prefs_->GetExtensionBlacklistState(extension_id); - if (state == extensions::BLACKLISTED_UNKNOWN) { - // If any of the extensions are in the unknown blacklist state, that means - // there was an error the last time the blacklist was fetched. That means + extensions::BlocklistState state = + extension_prefs_->GetExtensionBlocklistState(extension_id); + if (state == extensions::BLOCKLISTED_UNKNOWN) { + // If any of the extensions are in the unknown blocklist state, that means + // there was an error the last time the blocklist was fetched. That means // the results cannot be relied upon. OnExtensionsCheckResult(ExtensionsStatus::kError, Blocklisted(0), ReenabledUser(0), ReenabledAdmin(0)); return; } - if (state == extensions::NOT_BLACKLISTED) { + if (state == extensions::NOT_BLOCKLISTED) { continue; } ++blocklisted; @@ -278,6 +360,14 @@ void SafetyCheckHandler::CheckExtensions() { } } +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) +void SafetyCheckHandler::CheckChromeCleaner() { + // Registering the observer immediately triggers a callback with the + // current state. + safe_browsing::ChromeCleanerController::GetInstance()->AddObserver(this); +} +#endif + void SafetyCheckHandler::OnUpdateCheckResult(UpdateStatus status) { update_status_ = status; if (update_status_ != UpdateStatus::kChecking) { @@ -342,6 +432,23 @@ void SafetyCheckHandler::OnExtensionsCheckResult( CompleteParentIfChildrenCompleted(); } +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) +void SafetyCheckHandler::OnChromeCleanerCheckResult( + ChromeCleanerStatus status) { + base::DictionaryValue event; + event.SetIntKey(kNewState, static_cast<int>(status)); + event.SetStringKey(kDisplayString, GetStringForChromeCleaner(status)); + FireWebUIListener(kChromeCleanerEvent, event); + if (status != ChromeCleanerStatus::kHidden && + status != ChromeCleanerStatus::kChecking) { + base::UmaHistogramEnumeration("Settings.SafetyCheck.ChromeCleanerResult", + status); + } + chrome_cleaner_status_ = status; + CompleteParentIfChildrenCompleted(); +} +#endif + base::string16 SafetyCheckHandler::GetStringForParent(ParentStatus status) { switch (status) { case ParentStatus::kBefore: @@ -389,8 +496,11 @@ base::string16 SafetyCheckHandler::GetStringForUpdates(UpdateStatus status) { ? IDS_VERSION_UI_OFFICIAL : IDS_VERSION_UI_UNOFFICIAL), base::UTF8ToUTF16(chrome::GetChannelName()), - l10n_util::GetStringUTF16(sizeof(void*) == 8 ? IDS_VERSION_UI_64BIT - : IDS_VERSION_UI_32BIT)); + l10n_util::GetStringUTF16(VersionUI::VersionProcessorVariation())); + // This state is only used on Android for recording metrics. This codepath + // is unreachable. + case UpdateStatus::kOutdated: + return base::UTF8ToUTF16(""); } } @@ -416,6 +526,9 @@ base::string16 SafetyCheckHandler::GetStringForSafeBrowsing( case SafeBrowsingStatus::kDisabledByExtension: return l10n_util::GetStringUTF16( IDS_SETTINGS_SAFETY_CHECK_SAFE_BROWSING_DISABLED_BY_EXTENSION); + case SafeBrowsingStatus::kEnabledStandardAvailableEnhanced: + return l10n_util::GetStringUTF16( + IDS_SETTINGS_SAFETY_CHECK_SAFE_BROWSING_ENABLED_STANDARD_AVAILABLE_ENHANCED); } } @@ -501,17 +614,33 @@ base::string16 SafetyCheckHandler::GetStringForExtensions( } } -base::string16 SafetyCheckHandler::GetStringForParentRan( - base::Time safety_check_completion_time) { - return SafetyCheckHandler::GetStringForParentRan(safety_check_completion_time, - base::Time::Now()); +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) +base::string16 SafetyCheckHandler::GetStringForChromeCleaner( + ChromeCleanerStatus status) { + switch (status) { + case ChromeCleanerStatus::kHidden: + case ChromeCleanerStatus::kChecking: + return base::UTF8ToUTF16(""); + case ChromeCleanerStatus::kInfected: + return l10n_util::GetStringUTF16( + IDS_SETTINGS_SAFETY_CHECK_CHROME_CLEANER_INFECTED); + case ChromeCleanerStatus::kRebootRequired: + return l10n_util::GetStringUTF16( + IDS_SETTINGS_RESET_CLEANUP_TITLE_RESTART); + } } +#endif -base::string16 SafetyCheckHandler::GetStringForParentRan( - base::Time safety_check_completion_time, - base::Time system_time) { +base::string16 SafetyCheckHandler::GetStringForTimePassed( + base::Time completion_timestamp, + base::Time system_time, + int less_than_one_minute_ago_message_id, + int minutes_ago_message_id, + int hours_ago_message_id, + int yesterday_message_id, + int days_ago_message_id) { base::Time::Exploded completion_time_exploded; - safety_check_completion_time.LocalExplode(&completion_time_exploded); + completion_timestamp.LocalExplode(&completion_time_exploded); base::Time::Exploded system_time_exploded; system_time.LocalExplode(&system_time_exploded); @@ -520,43 +649,82 @@ base::string16 SafetyCheckHandler::GetStringForParentRan( base::Time::Exploded time_yesterday_exploded; time_yesterday.LocalExplode(&time_yesterday_exploded); - const auto time_diff = system_time - safety_check_completion_time; + const auto time_diff = system_time - completion_timestamp; if (completion_time_exploded.year == system_time_exploded.year && completion_time_exploded.month == system_time_exploded.month && completion_time_exploded.day_of_month == system_time_exploded.day_of_month) { - // Safety check ran today. + // The timestamp is today. const int time_diff_in_mins = time_diff.InMinutes(); if (time_diff_in_mins == 0) { - return l10n_util::GetStringUTF16( - IDS_SETTINGS_SAFETY_CHECK_PARENT_PRIMARY_LABEL_AFTER); + return l10n_util::GetStringUTF16(less_than_one_minute_ago_message_id); } else if (time_diff_in_mins < 60) { - return l10n_util::GetPluralStringFUTF16( - IDS_SETTINGS_SAFETY_CHECK_PARENT_PRIMARY_LABEL_AFTER_MINS, - time_diff_in_mins); + return l10n_util::GetPluralStringFUTF16(minutes_ago_message_id, + time_diff_in_mins); } else { - return l10n_util::GetPluralStringFUTF16( - IDS_SETTINGS_SAFETY_CHECK_PARENT_PRIMARY_LABEL_AFTER_HOURS, - time_diff_in_mins / 60); + return l10n_util::GetPluralStringFUTF16(hours_ago_message_id, + time_diff_in_mins / 60); } } else if (completion_time_exploded.year == time_yesterday_exploded.year && completion_time_exploded.month == time_yesterday_exploded.month && completion_time_exploded.day_of_month == time_yesterday_exploded.day_of_month) { - // Safety check ran yesterday. - return l10n_util::GetStringUTF16( - IDS_SETTINGS_SAFETY_CHECK_PARENT_PRIMARY_LABEL_AFTER_YESTERDAY); + // The timestamp was yesterday. + return l10n_util::GetStringUTF16(yesterday_message_id); } else { - // Safety check ran longer ago than yesterday. + // The timestamp is longer ago than yesterday. // TODO(crbug.com/1015841): While a minor issue, this is not be the ideal - // way to calculate the days passed since safety check ran. For example, + // way to calculate the days passed since the timestamp. For example, // <48 h might still be 2 days ago. const int time_diff_in_days = time_diff.InDays(); - return l10n_util::GetPluralStringFUTF16( - IDS_SETTINGS_SAFETY_CHECK_PARENT_PRIMARY_LABEL_AFTER_DAYS, - time_diff_in_days); + return l10n_util::GetPluralStringFUTF16(days_ago_message_id, + time_diff_in_days); + } +} + +base::string16 SafetyCheckHandler::GetStringForParentRan( + base::Time safety_check_completion_time, + base::Time system_time) { + return SafetyCheckHandler::GetStringForTimePassed( + safety_check_completion_time, system_time, + IDS_SETTINGS_SAFETY_CHECK_PARENT_PRIMARY_LABEL_AFTER, + IDS_SETTINGS_SAFETY_CHECK_PARENT_PRIMARY_LABEL_AFTER_MINS, + IDS_SETTINGS_SAFETY_CHECK_PARENT_PRIMARY_LABEL_AFTER_HOURS, + IDS_SETTINGS_SAFETY_CHECK_PARENT_PRIMARY_LABEL_AFTER_YESTERDAY, + IDS_SETTINGS_SAFETY_CHECK_PARENT_PRIMARY_LABEL_AFTER_DAYS); +} + +base::string16 SafetyCheckHandler::GetStringForParentRan( + base::Time safety_check_completion_time) { + return SafetyCheckHandler::GetStringForParentRan(safety_check_completion_time, + base::Time::Now()); +} + +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) +base::string16 SafetyCheckHandler::GetStringForChromeCleanerRan() { + base::Time cct_completion_time; + // TODO(crbug.com/1087263): If FOIL completion time exists in Windows Registry + // write it to |cct_completion_time|. + return SafetyCheckHandler::GetStringForChromeCleanerRan(cct_completion_time, + base::Time::Now()); +} + +base::string16 SafetyCheckHandler::GetStringForChromeCleanerRan( + base::Time cct_completion_time, + base::Time system_time) { + if (cct_completion_time.is_null()) { + return l10n_util::GetStringUTF16( + IDS_SETTINGS_SAFETY_CHECK_CHROME_CLEANER_AFTER); } + return SafetyCheckHandler::GetStringForTimePassed( + cct_completion_time, system_time, + IDS_SETTINGS_SAFETY_CHECK_CHROME_CLEANER_AFTER_SECONDS, + IDS_SETTINGS_SAFETY_CHECK_CHROME_CLEANER_AFTER_MINUTES, + IDS_SETTINGS_SAFETY_CHECK_CHROME_CLEANER_AFTER_HOURS, + IDS_SETTINGS_SAFETY_CHECK_CHROME_CLEANER_YESTERDAY, + IDS_SETTINGS_SAFETY_CHECK_CHROME_CLEANER_AFTER_DAYS); } +#endif void SafetyCheckHandler::DetermineIfOfflineOrError(bool connected) { OnUpdateCheckResult(connected ? UpdateStatus::kFailed @@ -666,10 +834,48 @@ void SafetyCheckHandler::OnCredentialDone( total); } } +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) +void SafetyCheckHandler::OnIdle( + safe_browsing::ChromeCleanerController::IdleReason idle_reason) { + OnChromeCleanerCheckResult(fetchCurrentChromeCleanerStatus()); +} + +void SafetyCheckHandler::OnReporterRunning() { + OnChromeCleanerCheckResult(fetchCurrentChromeCleanerStatus()); +} + +void SafetyCheckHandler::OnScanning() { + OnChromeCleanerCheckResult(fetchCurrentChromeCleanerStatus()); +} + +void SafetyCheckHandler::OnInfected( + bool is_powered_by_partner, + const safe_browsing::ChromeCleanerScannerResults& scanner_results) { + OnChromeCleanerCheckResult(fetchCurrentChromeCleanerStatus()); +} + +void SafetyCheckHandler::OnCleaning( + bool is_powered_by_partner, + const safe_browsing::ChromeCleanerScannerResults& scanner_results) { + OnChromeCleanerCheckResult(fetchCurrentChromeCleanerStatus()); +} + +void SafetyCheckHandler::OnRebootRequired() { + OnChromeCleanerCheckResult(fetchCurrentChromeCleanerStatus()); +} + +void SafetyCheckHandler::OnRebootFailed() { + OnChromeCleanerCheckResult(fetchCurrentChromeCleanerStatus()); +} +#endif void SafetyCheckHandler::OnJavascriptAllowed() {} void SafetyCheckHandler::OnJavascriptDisallowed() { + // If the user refreshes the Settings tab in the delay between starting safety + // check and now, then the check should no longer be run. Invalidating the + // pointer prevents the callback from returning after the delay. + weak_ptr_factory_.InvalidateWeakPtrs(); // Remove |this| as an observer for BulkLeakCheck. This takes care of an edge // case when the page is reloaded while the password check is in progress and // another safety check is started. Otherwise |observed_leak_check_| @@ -680,6 +886,10 @@ void SafetyCheckHandler::OnJavascriptDisallowed() { version_updater_.reset(); // Stop observing safety check events. safety_check_.reset(nullptr); +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + // Remove |this| as an observer for the Chrome cleaner. + safe_browsing::ChromeCleanerController::GetInstance()->RemoveObserver(this); +#endif } void SafetyCheckHandler::RegisterMessages() { @@ -696,18 +906,26 @@ void SafetyCheckHandler::RegisterMessages() { } void SafetyCheckHandler::CompleteParentIfChildrenCompleted() { - if (update_status_ != UpdateStatus::kChecking && - passwords_status_ != PasswordsStatus::kChecking && - safe_browsing_status_ != SafeBrowsingStatus::kChecking && - extensions_status_ != ExtensionsStatus::kChecking) { - parent_status_ = ParentStatus::kAfter; - // Remember when safety check completed. - safety_check_completion_time_ = base::Time::Now(); - // Update UI. - FireBasicSafetyCheckWebUiListener(kParentEvent, - static_cast<int>(parent_status_), - GetStringForParent(parent_status_)); + if (update_status_ == UpdateStatus::kChecking || + passwords_status_ == PasswordsStatus::kChecking || + safe_browsing_status_ == SafeBrowsingStatus::kChecking || + extensions_status_ == ExtensionsStatus::kChecking) { + return; } +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + if (chrome_cleaner_status_ == ChromeCleanerStatus::kChecking) { + return; + } +#endif + + // All children checks completed. + parent_status_ = ParentStatus::kAfter; + // Remember when safety check completed. + safety_check_completion_time_ = base::Time::Now(); + // Update UI. + FireBasicSafetyCheckWebUiListener(kParentEvent, + static_cast<int>(parent_status_), + GetStringForParent(parent_status_)); } void SafetyCheckHandler::FireBasicSafetyCheckWebUiListener( diff --git a/chromium/chrome/browser/ui/webui/settings/safety_check_handler.h b/chromium/chrome/browser/ui/webui/settings/safety_check_handler.h index 8e6d9336183..1005025b49e 100644 --- a/chromium/chrome/browser/ui/webui/settings/safety_check_handler.h +++ b/chromium/chrome/browser/ui/webui/settings/safety_check_handler.h @@ -15,6 +15,8 @@ #include "base/memory/weak_ptr.h" #include "base/scoped_observer.h" #include "base/util/type_safety/strong_alias.h" +#include "build/branding_buildflags.h" +#include "build/build_config.h" #include "chrome/browser/extensions/api/passwords_private/passwords_private_delegate.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/ui/webui/help/version_updater.h" @@ -25,12 +27,20 @@ #include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_registry.h" +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) +#include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h" +#include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_scanner_results_win.h" +#endif + // Settings page UI handler that checks four areas of browser safety: // browser updates, password leaks, malicious extensions, and unwanted // software. class SafetyCheckHandler : public settings::SettingsPageUIHandler, public password_manager::BulkLeakCheckServiceInterface::Observer, +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + public safe_browsing::ChromeCleanerController::Observer, +#endif public safety_check::SafetyCheck::SafetyCheckHandlerInterface { public: // The following enum represent the state of the safety check parent @@ -46,34 +56,9 @@ class SafetyCheckHandler // check and should be kept in sync with the JS frontend // (safety_check_browser_proxy.js) and |SafetyCheck*| metrics enums in // enums.xml. + using PasswordsStatus = safety_check::SafetyCheck::PasswordsStatus; using SafeBrowsingStatus = safety_check::SafetyCheck::SafeBrowsingStatus; - enum class UpdateStatus { - kChecking = 0, - kUpdated = 1, - kUpdating = 2, - kRelaunch = 3, - kDisabledByAdmin = 4, - kFailedOffline = 5, - kFailed = 6, - // Non-Google branded browsers cannot check for updates using - // VersionUpdater. - kUnknown = 7, - // New enum values must go above here. - kMaxValue = kUnknown, - }; - enum class PasswordsStatus { - kChecking = 0, - kSafe = 1, - kCompromisedExist = 2, - kOffline = 3, - kNoPasswords = 4, - kSignedOut = 5, - kQuotaLimit = 6, - kError = 7, - kFeatureUnavailable = 8, - // New enum values must go above here. - kMaxValue = kFeatureUnavailable, - }; + using UpdateStatus = safety_check::SafetyCheck::UpdateStatus; enum class ExtensionsStatus { kChecking = 0, kError = 1, @@ -86,6 +71,14 @@ class SafetyCheckHandler // New enum values must go above here. kMaxValue = kBlocklistedReenabledAllByAdmin, }; + enum class ChromeCleanerStatus { + kHidden = 0, + kChecking = 1, + kInfected = 2, + kRebootRequired = 3, + // New enum values must go above here. + kMaxValue = kRebootRequired, + }; SafetyCheckHandler(); ~SafetyCheckHandler() override; @@ -100,12 +93,30 @@ class SafetyCheckHandler // should only be called as a result of an explicit user action. void PerformSafetyCheck(); + // Constructs a string depicting how much time passed since the completion of + // something from the corresponding timestamps and strings IDs. + base::string16 GetStringForTimePassed(base::Time completion_timestamp, + base::Time system_time, + int less_than_one_minute_ago_message_id, + int minutes_ago_message_id, + int hours_ago_message_id, + int yesterday_message_id, + int days_ago_message_id); + // Constructs the 'safety check ran' display string by how long ago safety // check ran. base::string16 GetStringForParentRan(base::Time safety_check_completion_time); base::string16 GetStringForParentRan(base::Time safety_check_completion_time, base::Time system_time); +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + // Constructs the string for the Chrome cleaner 'safe' state which depicts + // how long ago its last check ran. + base::string16 GetStringForChromeCleanerRan(); + base::string16 GetStringForChromeCleanerRan(base::Time cct_completion_time, + base::Time system_time); +#endif + protected: SafetyCheckHandler( std::unique_ptr<safety_check::UpdateCheckHelper> update_helper, @@ -150,6 +161,11 @@ class SafetyCheckHandler // that case, if any of those were re-enabled. void CheckExtensions(); +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + // Checks for unwanted software via the Chrome Cleanup Tool. Only on Windows. + void CheckChromeCleaner(); +#endif + // Callbacks that get triggered when each check completes. void OnUpdateCheckResult(UpdateStatus status); void OnPasswordsCheckResult(PasswordsStatus status, @@ -160,6 +176,9 @@ class SafetyCheckHandler Blocklisted blocklisted, ReenabledUser reenabled_user, ReenabledAdmin reenabled_admin); +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + void OnChromeCleanerCheckResult(ChromeCleanerStatus status); +#endif // Methods for building user-visible strings based on the safety check // state. @@ -174,6 +193,9 @@ class SafetyCheckHandler Blocklisted blocklisted, ReenabledUser reenabled_user, ReenabledAdmin reenabled_admin); +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + base::string16 GetStringForChromeCleaner(ChromeCleanerStatus status); +#endif // A generic error state often includes the offline state. This method is used // as a callback for |UpdateCheckHelper| to check connectivity. @@ -207,6 +229,22 @@ class SafetyCheckHandler void OnCredentialDone(const password_manager::LeakCheckCredential& credential, password_manager::IsLeaked is_leaked) override; +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + // safe_browsing::ChromeCleanerController::Observer overrides. + void OnIdle( + safe_browsing::ChromeCleanerController::IdleReason idle_reason) override; + void OnReporterRunning() override; + void OnScanning() override; + void OnInfected(bool is_powered_by_partner, + const safe_browsing::ChromeCleanerScannerResults& + scanner_results) override; + void OnCleaning(bool is_powered_by_partner, + const safe_browsing::ChromeCleanerScannerResults& + scanner_results) override; + void OnRebootRequired() override; + void OnRebootFailed() override; +#endif + // SettingsPageUIHandler implementation. void OnJavascriptAllowed() override; void OnJavascriptDisallowed() override; @@ -229,7 +267,7 @@ class SafetyCheckHandler PasswordsStatus passwords_status_ = PasswordsStatus::kChecking; SafeBrowsingStatus safe_browsing_status_ = SafeBrowsingStatus::kChecking; ExtensionsStatus extensions_status_ = ExtensionsStatus::kChecking; - + ChromeCleanerStatus chrome_cleaner_status_ = ChromeCleanerStatus::kHidden; // System time when safety check completed. base::Time safety_check_completion_time_; diff --git a/chromium/chrome/browser/ui/webui/settings/safety_check_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/safety_check_handler_unittest.cc index 9a790eea198..aba8ab6b18d 100644 --- a/chromium/chrome/browser/ui/webui/settings/safety_check_handler_unittest.cc +++ b/chromium/chrome/browser/ui/webui/settings/safety_check_handler_unittest.cc @@ -39,16 +39,27 @@ #include "services/network/public/cpp/shared_url_loader_factory.h" #include "testing/gtest/include/gtest/gtest.h" +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) +#include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.h" +#endif + #if defined(OS_CHROMEOS) #include "ui/chromeos/devicetype_utils.h" #endif +#if defined(OS_MAC) +#include "base/mac/mac_util.h" +#endif + // Components for building event strings. constexpr char kParent[] = "parent"; constexpr char kUpdates[] = "updates"; constexpr char kPasswords[] = "passwords"; constexpr char kSafeBrowsing[] = "safe-browsing"; constexpr char kExtensions[] = "extensions"; +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) +constexpr char kChromeCleaner[] = "chrome-cleaner"; +#endif namespace { using Enabled = util::StrongAlias<class EnabledTag, bool>; @@ -177,6 +188,14 @@ class TestSafetyCheckExtensionService : public TestExtensionService { std::unordered_map<std::string, ExtensionState> state_map_; }; +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) +class TestChromeCleanerControllerDelegate + : public safe_browsing::ChromeCleanerControllerDelegate { + public: + bool IsAllowedByPolicy() override { return false; } +}; +#endif + } // namespace class SafetyCheckHandlerTest : public ChromeRenderViewHostTestHarness { @@ -197,6 +216,11 @@ class SafetyCheckHandlerTest : public ChromeRenderViewHostTestHarness { void VerifyDisplayString(const base::DictionaryValue* event, const std::string& expected); + // Replaces any instances of browser name (e.g. Google Chrome, Chromium, + // etc) with "browser" to make sure tests work both on Chromium and + // Google Chrome. + void ReplaceBrowserName(base::string16* s); + protected: safety_check::TestUpdateCheckHelper* update_helper_ = nullptr; TestVersionUpdater* version_updater_ = nullptr; @@ -207,12 +231,9 @@ class SafetyCheckHandlerTest : public ChromeRenderViewHostTestHarness { content::TestWebUI test_web_ui_; std::unique_ptr<TestingSafetyCheckHandler> safety_check_; base::HistogramTester histogram_tester_; - - private: - // Replaces any instances of browser name (e.g. Google Chrome, Chromium, - // etc) with "browser" to make sure tests work both on Chromium and - // Google Chrome. - void ReplaceBrowserName(base::string16* s); +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + TestChromeCleanerControllerDelegate test_chrome_cleaner_controller_delegate_; +#endif }; void SafetyCheckHandlerTest::SetUp() { @@ -376,6 +397,27 @@ TEST_F(SafetyCheckHandlerTest, CheckUpdates_Relaunch) { } TEST_F(SafetyCheckHandlerTest, CheckUpdates_Disabled) { + const char* processor_variation = nullptr; +#if defined(OS_MAC) + switch (base::mac::GetCPUType()) { + case base::mac::CPUType::kIntel: + processor_variation = " (x86_64)"; + break; + case base::mac::CPUType::kTranslatedIntel: + processor_variation = " (x86_64 translated)"; + break; + case base::mac::CPUType::kArm: + processor_variation = " (arm64)"; + break; + } +#elif defined(ARCH_CPU_64_BITS) + processor_variation = " (64-bit)"; +#elif defined(ARCH_CPU_32_BITS) + processor_variation = " (32-bit)"; +#else +#error Update for a processor that is neither 32-bit nor 64-bit. +#endif // OS_* + version_updater_->SetReturnedStatus(VersionUpdater::Status::DISABLED); safety_check_->PerformSafetyCheck(); // TODO(crbug/1072432): Since the UNKNOWN state is not present in JS in M83, @@ -389,8 +431,7 @@ TEST_F(SafetyCheckHandlerTest, CheckUpdates_Disabled) { event, "Version " + version_info::GetVersionNumber() + " (" + (version_info::IsOfficialBuild() ? "Official Build" : "Developer Build") + - ") " + chrome::GetChannelName() + - (sizeof(void*) == 8 ? " (64-bit)" : " (32-bit)")); + ") " + chrome::GetChannelName() + processor_variation); histogram_tester_.ExpectBucketCount( "Settings.SafetyCheck.UpdatesResult", SafetyCheckHandler::UpdateStatus::kUnknown, 1); @@ -477,6 +518,26 @@ TEST_F(SafetyCheckHandlerTest, CheckUpdates_DestroyedOnJavascriptDisallowed) { } TEST_F(SafetyCheckHandlerTest, CheckSafeBrowsing_EnabledStandard) { + TestingProfile::FromWebUI(&test_web_ui_) + ->AsTestingProfile() + ->GetTestingPrefService() + ->SetManagedPref(prefs::kSafeBrowsingEnabled, + std::make_unique<base::Value>(true)); + safety_check_->PerformSafetyCheck(); + const base::DictionaryValue* event = + GetSafetyCheckStatusChangedWithDataIfExists( + kSafeBrowsing, + static_cast<int>( + SafetyCheckHandler::SafeBrowsingStatus::kEnabledStandard)); + ASSERT_TRUE(event); + VerifyDisplayString(event, "Standard Protection is on"); + histogram_tester_.ExpectBucketCount( + "Settings.SafetyCheck.SafeBrowsingResult", + SafetyCheckHandler::SafeBrowsingStatus::kEnabledStandard, 1); +} + +TEST_F(SafetyCheckHandlerTest, + CheckSafeBrowsing_EnabledStandardAvailableEnhanced) { Profile::FromWebUI(&test_web_ui_) ->GetPrefs() ->SetBoolean(prefs::kSafeBrowsingEnabled, true); @@ -487,13 +548,16 @@ TEST_F(SafetyCheckHandlerTest, CheckSafeBrowsing_EnabledStandard) { const base::DictionaryValue* event = GetSafetyCheckStatusChangedWithDataIfExists( kSafeBrowsing, - static_cast<int>( - SafetyCheckHandler::SafeBrowsingStatus::kEnabledStandard)); + static_cast<int>(SafetyCheckHandler::SafeBrowsingStatus:: + kEnabledStandardAvailableEnhanced)); ASSERT_TRUE(event); - VerifyDisplayString(event, "Standard Protection is on"); + VerifyDisplayString(event, + "Standard protection is on. For even more security, use " + "enhanced protection."); histogram_tester_.ExpectBucketCount( "Settings.SafetyCheck.SafeBrowsingResult", - SafetyCheckHandler::SafeBrowsingStatus::kEnabledStandard, 1); + SafetyCheckHandler::SafeBrowsingStatus::kEnabledStandardAvailableEnhanced, + 1); } TEST_F(SafetyCheckHandlerTest, CheckSafeBrowsing_EnabledEnhanced) { @@ -915,8 +979,8 @@ TEST_F(SafetyCheckHandlerTest, CheckExtensions_NoneBlocklisted) { test_extension_prefs_->OnExtensionInstalled( extension.get(), extensions::Extension::State::ENABLED, syncer::StringOrdinal(), ""); - test_extension_prefs_->SetExtensionBlacklistState( - extension_id, extensions::NOT_BLACKLISTED); + test_extension_prefs_->SetExtensionBlocklistState( + extension_id, extensions::NOT_BLOCKLISTED); safety_check_->PerformSafetyCheck(); const base::DictionaryValue* event = GetSafetyCheckStatusChangedWithDataIfExists( @@ -938,8 +1002,8 @@ TEST_F(SafetyCheckHandlerTest, CheckExtensions_BlocklistedAllDisabled) { test_extension_prefs_->OnExtensionInstalled( extension.get(), extensions::Extension::State::DISABLED, syncer::StringOrdinal(), ""); - test_extension_prefs_->SetExtensionBlacklistState( - extension_id, extensions::BLACKLISTED_MALWARE); + test_extension_prefs_->SetExtensionBlocklistState( + extension_id, extensions::BLOCKLISTED_MALWARE); test_extension_service_.AddExtensionState(extension_id, Enabled(false), UserCanDisable(false)); safety_check_->PerformSafetyCheck(); @@ -963,8 +1027,8 @@ TEST_F(SafetyCheckHandlerTest, CheckExtensions_BlocklistedReenabledAllByUser) { test_extension_prefs_->OnExtensionInstalled( extension.get(), extensions::Extension::State::ENABLED, syncer::StringOrdinal(), ""); - test_extension_prefs_->SetExtensionBlacklistState( - extension_id, extensions::BLACKLISTED_POTENTIALLY_UNWANTED); + test_extension_prefs_->SetExtensionBlocklistState( + extension_id, extensions::BLOCKLISTED_POTENTIALLY_UNWANTED); test_extension_service_.AddExtensionState(extension_id, Enabled(true), UserCanDisable(true)); safety_check_->PerformSafetyCheck(); @@ -987,8 +1051,8 @@ TEST_F(SafetyCheckHandlerTest, CheckExtensions_BlocklistedReenabledAllByAdmin) { test_extension_prefs_->OnExtensionInstalled( extension.get(), extensions::Extension::State::ENABLED, syncer::StringOrdinal(), ""); - test_extension_prefs_->SetExtensionBlacklistState( - extension_id, extensions::BLACKLISTED_POTENTIALLY_UNWANTED); + test_extension_prefs_->SetExtensionBlocklistState( + extension_id, extensions::BLOCKLISTED_POTENTIALLY_UNWANTED); test_extension_service_.AddExtensionState(extension_id, Enabled(true), UserCanDisable(false)); safety_check_->PerformSafetyCheck(); @@ -1011,8 +1075,8 @@ TEST_F(SafetyCheckHandlerTest, CheckExtensions_BlocklistedReenabledSomeByUser) { test_extension_prefs_->OnExtensionInstalled( extension.get(), extensions::Extension::State::ENABLED, syncer::StringOrdinal(), ""); - test_extension_prefs_->SetExtensionBlacklistState( - extension_id, extensions::BLACKLISTED_POTENTIALLY_UNWANTED); + test_extension_prefs_->SetExtensionBlocklistState( + extension_id, extensions::BLOCKLISTED_POTENTIALLY_UNWANTED); test_extension_service_.AddExtensionState(extension_id, Enabled(true), UserCanDisable(true)); @@ -1022,8 +1086,8 @@ TEST_F(SafetyCheckHandlerTest, CheckExtensions_BlocklistedReenabledSomeByUser) { test_extension_prefs_->OnExtensionInstalled( extension2.get(), extensions::Extension::State::ENABLED, syncer::StringOrdinal(), ""); - test_extension_prefs_->SetExtensionBlacklistState( - extension2_id, extensions::BLACKLISTED_POTENTIALLY_UNWANTED); + test_extension_prefs_->SetExtensionBlocklistState( + extension2_id, extensions::BLOCKLISTED_POTENTIALLY_UNWANTED); test_extension_service_.AddExtensionState(extension2_id, Enabled(true), UserCanDisable(false)); @@ -1050,8 +1114,8 @@ TEST_F(SafetyCheckHandlerTest, CheckExtensions_Error) { test_extension_prefs_->OnExtensionInstalled( extension.get(), extensions::Extension::State::ENABLED, syncer::StringOrdinal(), ""); - test_extension_prefs_->SetExtensionBlacklistState( - extension_id, extensions::BLACKLISTED_UNKNOWN); + test_extension_prefs_->SetExtensionBlocklistState( + extension_id, extensions::BLOCKLISTED_UNKNOWN); test_extension_service_.AddExtensionState(extension_id, Enabled(true), UserCanDisable(true)); @@ -1062,8 +1126,8 @@ TEST_F(SafetyCheckHandlerTest, CheckExtensions_Error) { test_extension_prefs_->OnExtensionInstalled( extension2.get(), extensions::Extension::State::ENABLED, syncer::StringOrdinal(), ""); - test_extension_prefs_->SetExtensionBlacklistState( - extension2_id, extensions::BLACKLISTED_POTENTIALLY_UNWANTED); + test_extension_prefs_->SetExtensionBlocklistState( + extension2_id, extensions::BLOCKLISTED_POTENTIALLY_UNWANTED); test_extension_service_.AddExtensionState(extension2_id, Enabled(true), UserCanDisable(false)); @@ -1080,6 +1144,212 @@ TEST_F(SafetyCheckHandlerTest, CheckExtensions_Error) { SafetyCheckHandler::ExtensionsStatus::kError, 1); } +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) +class SafetyCheckHandlerChromeCleanerIdleTest + : public SafetyCheckHandlerTest, + public testing::WithParamInterface< + std::tuple<safe_browsing::ChromeCleanerController::IdleReason, + SafetyCheckHandler::ChromeCleanerStatus, + base::string16>> { + protected: + void SetUp() override { + SafetyCheckHandlerTest::SetUp(); + idle_reason_ = testing::get<0>(GetParam()); + expected_cct_status_ = testing::get<1>(GetParam()); + expected_display_string_ = testing::get<2>(GetParam()); + } + + safe_browsing::ChromeCleanerController::IdleReason idle_reason_; + SafetyCheckHandler::ChromeCleanerStatus expected_cct_status_; + base::string16 expected_display_string_; +}; + +TEST_P(SafetyCheckHandlerChromeCleanerIdleTest, CheckChromeCleanerIdleStates) { + safe_browsing::ChromeCleanerControllerImpl::ResetInstanceForTesting(); + safe_browsing::ChromeCleanerControllerImpl::GetInstance()->SetIdleForTesting( + idle_reason_); + safety_check_->PerformSafetyCheck(); + // Ensure WebUI event is sent. + const base::DictionaryValue* event = + GetSafetyCheckStatusChangedWithDataIfExists( + kChromeCleaner, static_cast<int>(expected_cct_status_)); + ASSERT_TRUE(event); + VerifyDisplayString(event, expected_display_string_); + // Ensure UMA is logged. + if (expected_cct_status_ == + SafetyCheckHandler::ChromeCleanerStatus::kHidden || + expected_cct_status_ == + SafetyCheckHandler::ChromeCleanerStatus::kChecking) { + // Hidden and checking state should not get recorded. + histogram_tester_.ExpectTotalCount( + "Settings.SafetyCheck.ChromeCleanerResult", 0); + } else { + histogram_tester_.ExpectBucketCount( + "Settings.SafetyCheck.ChromeCleanerResult", expected_cct_status_, 1); + } +} + +INSTANTIATE_TEST_SUITE_P( + CheckChromeCleaner_Initial, + SafetyCheckHandlerChromeCleanerIdleTest, + ::testing::Values(std::make_tuple( + safe_browsing::ChromeCleanerController::IdleReason::kInitial, + SafetyCheckHandler::ChromeCleanerStatus::kHidden, + base::UTF8ToUTF16("")))); + +INSTANTIATE_TEST_SUITE_P(CheckChromeCleaner_ReporterFoundNothing, + SafetyCheckHandlerChromeCleanerIdleTest, + ::testing::Values(std::make_tuple( + safe_browsing::ChromeCleanerController:: + IdleReason::kReporterFoundNothing, + SafetyCheckHandler::ChromeCleanerStatus::kHidden, + base::UTF8ToUTF16("")))); + +INSTANTIATE_TEST_SUITE_P( + CheckChromeCleaner_ReporterFailed, + SafetyCheckHandlerChromeCleanerIdleTest, + ::testing::Values(std::make_tuple( + safe_browsing::ChromeCleanerController::IdleReason::kReporterFailed, + SafetyCheckHandler::ChromeCleanerStatus::kHidden, + base::UTF8ToUTF16("")))); + +INSTANTIATE_TEST_SUITE_P(CheckChromeCleaner_ScanningFoundNothing, + SafetyCheckHandlerChromeCleanerIdleTest, + ::testing::Values(std::make_tuple( + safe_browsing::ChromeCleanerController:: + IdleReason::kScanningFoundNothing, + SafetyCheckHandler::ChromeCleanerStatus::kHidden, + base::UTF8ToUTF16("")))); + +INSTANTIATE_TEST_SUITE_P( + CheckChromeCleaner_ScanningFailed, + SafetyCheckHandlerChromeCleanerIdleTest, + ::testing::Values(std::make_tuple( + safe_browsing::ChromeCleanerController::IdleReason::kScanningFailed, + SafetyCheckHandler::ChromeCleanerStatus::kHidden, + base::UTF8ToUTF16("")))); + +INSTANTIATE_TEST_SUITE_P( + CheckChromeCleaner_ConnectionLost, + SafetyCheckHandlerChromeCleanerIdleTest, + ::testing::Values(std::make_tuple( + safe_browsing::ChromeCleanerController::IdleReason::kConnectionLost, + SafetyCheckHandler::ChromeCleanerStatus::kInfected, + base::UTF8ToUTF16("Browser found harmful software on your computer")))); + +INSTANTIATE_TEST_SUITE_P( + CheckChromeCleaner_UserDeclinedCleanup, + SafetyCheckHandlerChromeCleanerIdleTest, + ::testing::Values(std::make_tuple( + safe_browsing::ChromeCleanerController::IdleReason:: + kUserDeclinedCleanup, + SafetyCheckHandler::ChromeCleanerStatus::kInfected, + base::UTF8ToUTF16("Browser found harmful software on your computer")))); + +INSTANTIATE_TEST_SUITE_P( + CheckChromeCleaner_CleaningFailed, + SafetyCheckHandlerChromeCleanerIdleTest, + ::testing::Values(std::make_tuple( + safe_browsing::ChromeCleanerController::IdleReason::kCleaningFailed, + SafetyCheckHandler::ChromeCleanerStatus::kHidden, + base::UTF8ToUTF16("")))); + +INSTANTIATE_TEST_SUITE_P( + CheckChromeCleaner_CleaningSucceed, + SafetyCheckHandlerChromeCleanerIdleTest, + ::testing::Values(std::make_tuple( + safe_browsing::ChromeCleanerController::IdleReason::kCleaningSucceeded, + SafetyCheckHandler::ChromeCleanerStatus::kHidden, + base::UTF8ToUTF16("")))); + +INSTANTIATE_TEST_SUITE_P(CheckChromeCleaner_CleanerDownloadFailed, + SafetyCheckHandlerChromeCleanerIdleTest, + ::testing::Values(std::make_tuple( + safe_browsing::ChromeCleanerController:: + IdleReason::kCleanerDownloadFailed, + SafetyCheckHandler::ChromeCleanerStatus::kHidden, + base::UTF8ToUTF16("")))); + +class SafetyCheckHandlerChromeCleanerNonIdleTest + : public SafetyCheckHandlerTest, + public testing::WithParamInterface< + std::tuple<safe_browsing::ChromeCleanerController::State, + SafetyCheckHandler::ChromeCleanerStatus, + base::string16>> { + protected: + void SetUp() override { + SafetyCheckHandlerTest::SetUp(); + state_ = testing::get<0>(GetParam()); + expected_cct_status_ = testing::get<1>(GetParam()); + expected_display_string_ = testing::get<2>(GetParam()); + } + + safe_browsing::ChromeCleanerController::State state_; + SafetyCheckHandler::ChromeCleanerStatus expected_cct_status_; + base::string16 expected_display_string_; +}; + +TEST_P(SafetyCheckHandlerChromeCleanerNonIdleTest, + CheckChromeCleanerNonIdleStates) { + safe_browsing::ChromeCleanerControllerImpl::ResetInstanceForTesting(); + safe_browsing::ChromeCleanerControllerImpl::GetInstance()->SetStateForTesting( + state_); + safety_check_->PerformSafetyCheck(); + const base::DictionaryValue* event = + GetSafetyCheckStatusChangedWithDataIfExists( + kChromeCleaner, static_cast<int>(expected_cct_status_)); + ASSERT_TRUE(event); + VerifyDisplayString(event, expected_display_string_); +} + +INSTANTIATE_TEST_SUITE_P( + CheckChromeCleaner_ReporterRunning, + SafetyCheckHandlerChromeCleanerNonIdleTest, + ::testing::Values(std::make_tuple( + safe_browsing::ChromeCleanerController::State::kReporterRunning, + SafetyCheckHandler::ChromeCleanerStatus::kHidden, + base::UTF8ToUTF16("")))); + +INSTANTIATE_TEST_SUITE_P( + CheckChromeCleaner_Scanning, + SafetyCheckHandlerChromeCleanerNonIdleTest, + ::testing::Values(std::make_tuple( + safe_browsing::ChromeCleanerController::State::kScanning, + SafetyCheckHandler::ChromeCleanerStatus::kHidden, + base::UTF8ToUTF16("")))); + +INSTANTIATE_TEST_SUITE_P( + CheckChromeCleaner_Infected, + SafetyCheckHandlerChromeCleanerNonIdleTest, + ::testing::Values(std::make_tuple( + safe_browsing::ChromeCleanerController::State::kInfected, + SafetyCheckHandler::ChromeCleanerStatus::kInfected, + base::UTF8ToUTF16("Browser found harmful software on your computer")))); + +INSTANTIATE_TEST_SUITE_P( + CheckChromeCleaner_RebootRequired, + SafetyCheckHandlerChromeCleanerNonIdleTest, + ::testing::Values(std::make_tuple( + safe_browsing::ChromeCleanerController::State::kRebootRequired, + SafetyCheckHandler::ChromeCleanerStatus::kRebootRequired, + base::UTF8ToUTF16( + "To finish removing harmful software, restart your computer")))); + +TEST_F(SafetyCheckHandlerTest, CheckChromeCleaner_DisabledByAdmin) { + safe_browsing::ChromeCleanerControllerImpl::ResetInstanceForTesting(); + safe_browsing::ChromeCleanerControllerImpl::GetInstance() + ->SetDelegateForTesting(&test_chrome_cleaner_controller_delegate_); + + safety_check_->PerformSafetyCheck(); + const base::DictionaryValue* event = + GetSafetyCheckStatusChangedWithDataIfExists( + kChromeCleaner, + static_cast<int>(SafetyCheckHandler::ChromeCleanerStatus::kHidden)); + ASSERT_TRUE(event); + VerifyDisplayString(event, ""); +} +#endif + TEST_F(SafetyCheckHandlerTest, CheckParentRanDisplayString) { // 1 second before midnight Dec 31st 2020, so that -(24h-1s) is still on the // same day. This test time is hard coded to prevent DST flakiness, see @@ -1113,6 +1383,79 @@ TEST_F(SafetyCheckHandlerTest, CheckParentRanDisplayString) { } } +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) +TEST_F(SafetyCheckHandlerTest, CheckChromeCleanerRanDisplayString) { + // Test string without timestamp. + base::Time null_time; + base::string16 display_string = + safety_check_->GetStringForChromeCleanerRan(null_time, null_time); + ReplaceBrowserName(&display_string); + EXPECT_EQ( + display_string, + base::UTF8ToUTF16("Browser checks for unwanted software once a week")); + // Test strings with timestamp. + // 1 second before midnight Dec 31st 2020, so that -(24h-1s) is still on the + // same day. This test time is hard coded to prevent DST flakiness, see + // crbug.com/1066576. + const base::Time system_time = + base::Time::FromDoubleT(1609459199).LocalMidnight() - + base::TimeDelta::FromSeconds(1); + // Display strings for given time deltas in seconds. + std::vector<std::tuple<std::string, int>> tuples{ + std::make_tuple("Browser checks for unwanted software once a week. Last " + "checked: a moment ago.", + 1), + std::make_tuple("Browser checks for unwanted software once a week. Last " + "checked: a moment ago.", + 59), + std::make_tuple("Browser checks for unwanted software once a week. Last " + "checked: 1 minute ago.", + 60), + std::make_tuple("Browser checks for unwanted software once a week. Last " + "checked: 2 minutes ago.", + 60 * 2), + std::make_tuple("Browser checks for unwanted software once a week. Last " + "checked: 59 minutes ago.", + 60 * 60 - 1), + std::make_tuple("Browser checks for unwanted software once a week. Last " + "checked: 1 hour ago.", + 60 * 60), + std::make_tuple("Browser checks for unwanted software once a week. Last " + "checked: 2 hours ago.", + 60 * 60 * 2), + std::make_tuple("Browser checks for unwanted software once a week. Last " + "checked: 23 hours ago.", + 60 * 60 * 23), + std::make_tuple("Browser checks for unwanted software once a week. Last " + "checked: yesterday.", + 60 * 60 * 24), + std::make_tuple("Browser checks for unwanted software once a week. Last " + "checked: yesterday.", + 60 * 60 * 24 * 2 - 1), + std::make_tuple("Browser checks for unwanted software once a week. Last " + "checked: 2 days ago.", + 60 * 60 * 24 * 2), + std::make_tuple("Browser checks for unwanted software once a week. Last " + "checked: 2 days ago.", + 60 * 60 * 24 * 3 - 1), + std::make_tuple("Browser checks for unwanted software once a week. Last " + "checked: 3 days ago.", + 60 * 60 * 24 * 3), + std::make_tuple("Browser checks for unwanted software once a week. Last " + "checked: 3 days ago.", + 60 * 60 * 24 * 4 - 1)}; + // Test that above time deltas produce the corresponding display strings. + for (auto tuple : tuples) { + const base::Time time = + system_time - base::TimeDelta::FromSeconds(std::get<1>(tuple)); + display_string = + safety_check_->GetStringForChromeCleanerRan(time, system_time); + ReplaceBrowserName(&display_string); + EXPECT_EQ(base::UTF8ToUTF16(std::get<0>(tuple)), display_string); + } +} +#endif + TEST_F(SafetyCheckHandlerTest, CheckSafetyCheckStartedWebUiEvents) { safety_check_->SendSafetyCheckStartedWebUiUpdates(); @@ -1153,11 +1496,17 @@ TEST_F(SafetyCheckHandlerTest, CheckSafetyCheckCompletedWebUiEvents) { // Mock safety check invocation. safety_check_->PerformSafetyCheck(); - // Password mocks need to be triggered with a non-checking state to fire. - // All other mocks fire automatically when invoked. + // Set the password check mock response. test_leak_service_->set_state_and_notify( password_manager::BulkLeakCheckService::State::kSignedOut); +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + // Set the Chrome cleaner mock response. + safe_browsing::ChromeCleanerControllerImpl::ResetInstanceForTesting(); + safe_browsing::ChromeCleanerControllerImpl::GetInstance()->SetStateForTesting( + safe_browsing::ChromeCleanerController::State::kInfected); +#endif + // Check that the parent update is sent after all children checks completed. const base::DictionaryValue* event_parent = GetSafetyCheckStatusChangedWithDataIfExists( diff --git a/chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc b/chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc index 831c737b3fa..e7331b97a04 100644 --- a/chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc @@ -30,7 +30,6 @@ #include "components/browsing_data/core/browsing_data_utils.h" #include "components/browsing_data/core/history_notice_utils.h" #include "components/browsing_data/core/pref_names.h" -#include "components/feature_engagement/buildflags.h" #include "components/prefs/pref_member.h" #include "components/prefs/pref_service.h" #include "components/signin/public/identity_manager/identity_manager.h" @@ -40,11 +39,6 @@ #include "content/public/browser/web_ui.h" #include "ui/base/text/bytes_formatting.h" -#if BUILDFLAG(ENABLE_LEGACY_DESKTOP_IN_PRODUCT_HELP) -#include "chrome/browser/feature_engagement/incognito_window/incognito_window_tracker.h" -#include "chrome/browser/feature_engagement/incognito_window/incognito_window_tracker_factory.h" -#endif - using BrowsingDataType = browsing_data::BrowsingDataType; namespace { @@ -235,7 +229,7 @@ ClearBrowsingDataHandler::ProcessInstalledApps( std::unique_ptr<content::BrowsingDataFilterBuilder> filter_builder( content::BrowsingDataFilterBuilder::Create( - content::BrowsingDataFilterBuilder::BLACKLIST)); + content::BrowsingDataFilterBuilder::Mode::kPreserve)); for (const std::string& domain : excluded_domains) filter_builder->AddRegisterableDomain(domain); return filter_builder; @@ -366,7 +360,7 @@ void ClearBrowsingDataHandler::HandleClearBrowsingData( content::BrowsingDataRemover* remover = content::BrowserContext::GetBrowsingDataRemover(profile_); - base::OnceClosure callback = + base::OnceCallback<void(uint64_t)> callback = base::BindOnce(&ClearBrowsingDataHandler::OnClearingTaskFinished, weak_ptr_factory_.GetWeakPtr(), webui_callback_id, std::move(data_types), std::move(scoped_data_deletion)); @@ -376,44 +370,47 @@ void ClearBrowsingDataHandler::HandleClearBrowsingData( browsing_data_important_sites_util::Remove( remove_mask, origin_mask, time_period, std::move(filter_builder), remover, std::move(callback)); - -#if BUILDFLAG(ENABLE_LEGACY_DESKTOP_IN_PRODUCT_HELP) - feature_engagement::IncognitoWindowTrackerFactory::GetInstance() - ->GetForProfile(profile_) - ->OnBrowsingDataCleared(); -#endif } void ClearBrowsingDataHandler::OnClearingTaskFinished( const std::string& webui_callback_id, const base::flat_set<BrowsingDataType>& data_types, - std::unique_ptr<AccountReconcilor::ScopedSyncedDataDeletion> deletion) { + std::unique_ptr<AccountReconcilor::ScopedSyncedDataDeletion> deletion, + uint64_t failed_data_types) { PrefService* prefs = profile_->GetPrefs(); - int notice_shown_times = prefs->GetInteger( + int history_notice_shown_times = prefs->GetInteger( browsing_data::prefs::kClearBrowsingDataHistoryNoticeShownTimes); // When the deletion is complete, we might show an additional dialog with // a notice about other forms of browsing history. This is the case if - const bool show_notice = + const bool show_history_notice = // 1. The dialog is relevant for the user. show_history_deletion_dialog_ && // 2. The notice has been shown less than |kMaxTimesHistoryNoticeShown|. - notice_shown_times < kMaxTimesHistoryNoticeShown && + history_notice_shown_times < kMaxTimesHistoryNoticeShown && // 3. The selected data types contained browsing history. data_types.find(BrowsingDataType::HISTORY) != data_types.end(); - if (show_notice) { + if (show_history_notice) { // Increment the preference. prefs->SetInteger( browsing_data::prefs::kClearBrowsingDataHistoryNoticeShownTimes, - notice_shown_times + 1); + history_notice_shown_times + 1); } UMA_HISTOGRAM_BOOLEAN( - "History.ClearBrowsingData.ShownHistoryNoticeAfterClearing", show_notice); + "History.ClearBrowsingData.ShownHistoryNoticeAfterClearing", + show_history_notice); - ResolveJavascriptCallback(base::Value(webui_callback_id), - base::Value(show_notice)); + bool show_passwords_notice = + (failed_data_types & + ChromeBrowsingDataRemoverDelegate::DATA_TYPE_PASSWORDS); + + base::Value result(base::Value::Type::DICTIONARY); + result.SetBoolKey("showHistoryNotice", show_history_notice); + result.SetBoolKey("showPasswordsNotice", show_passwords_notice); + + ResolveJavascriptCallback(base::Value(webui_callback_id), std::move(result)); } void ClearBrowsingDataHandler::HandleInitialize(const base::ListValue* args) { diff --git a/chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h b/chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h index 784812552ef..dcfc7343654 100644 --- a/chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h +++ b/chromium/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h @@ -74,7 +74,8 @@ class ClearBrowsingDataHandler : public SettingsPageUIHandler, void OnClearingTaskFinished( const std::string& webui_callback_id, const base::flat_set<browsing_data::BrowsingDataType>& data_types, - std::unique_ptr<AccountReconcilor::ScopedSyncedDataDeletion> deletion); + std::unique_ptr<AccountReconcilor::ScopedSyncedDataDeletion> deletion, + uint64_t failed_data_types); // Initializes the dialog UI. Called by JavaScript when the DOM is ready. void HandleInitialize(const base::ListValue* args); diff --git a/chromium/chrome/browser/ui/webui/settings/settings_default_browser_handler.cc b/chromium/chrome/browser/ui/webui/settings/settings_default_browser_handler.cc index ef43d9631ac..2e81b4eb893 100644 --- a/chromium/chrome/browser/ui/webui/settings/settings_default_browser_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/settings_default_browser_handler.cc @@ -30,9 +30,9 @@ bool DefaultBrowserIsDisabledByPolicy() { } // namespace -DefaultBrowserHandler::DefaultBrowserHandler() {} +DefaultBrowserHandler::DefaultBrowserHandler() = default; -DefaultBrowserHandler::~DefaultBrowserHandler() {} +DefaultBrowserHandler::~DefaultBrowserHandler() = default; void DefaultBrowserHandler::RegisterMessages() { web_ui()->RegisterMessageCallback( @@ -52,9 +52,7 @@ void DefaultBrowserHandler::OnJavascriptAllowed() { prefs::kDefaultBrowserSettingEnabled, base::Bind(&DefaultBrowserHandler::RequestDefaultBrowserState, base::Unretained(this), nullptr)); - default_browser_worker_ = new shell_integration::DefaultBrowserWorker( - base::Bind(&DefaultBrowserHandler::OnDefaultBrowserWorkerFinished, - weak_ptr_factory_.GetWeakPtr())); + default_browser_worker_ = new shell_integration::DefaultBrowserWorker(); } void DefaultBrowserHandler::OnJavascriptDisallowed() { @@ -70,7 +68,9 @@ void DefaultBrowserHandler::RequestDefaultBrowserState( CHECK_EQ(args->GetSize(), 1U); CHECK(args->GetString(0, &check_default_callback_id_)); - default_browser_worker_->StartCheckIsDefault(); + default_browser_worker_->StartCheckIsDefault( + base::BindOnce(&DefaultBrowserHandler::OnDefaultBrowserWorkerFinished, + weak_ptr_factory_.GetWeakPtr())); } void DefaultBrowserHandler::SetAsDefaultBrowser(const base::ListValue* args) { @@ -78,7 +78,9 @@ void DefaultBrowserHandler::SetAsDefaultBrowser(const base::ListValue* args) { AllowJavascript(); RecordSetAsDefaultUMA(); - default_browser_worker_->StartSetAsDefault(); + default_browser_worker_->StartSetAsDefault( + base::BindOnce(&DefaultBrowserHandler::OnDefaultBrowserWorkerFinished, + weak_ptr_factory_.GetWeakPtr())); // If the user attempted to make Chrome the default browser, notify // them when this changes. diff --git a/chromium/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chromium/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc index ccb1ccca58c..79f60e280e6 100644 --- a/chromium/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc +++ b/chromium/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc @@ -31,10 +31,12 @@ #include "chrome/browser/ui/webui/policy_indicator_localized_strings_provider.h" #include "chrome/browser/ui/webui/settings/reset_settings_handler.h" #include "chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.h" +#include "chrome/browser/ui/webui/version_ui.h" #include "chrome/browser/ui/webui/webui_util.h" #include "chrome/common/channel_info.h" #include "chrome/common/chrome_features.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" @@ -52,6 +54,7 @@ #include "components/autofill/core/common/autofill_features.h" #include "components/autofill/core/common/autofill_payments_features.h" #include "components/browsing_data/core/features.h" +#include "components/cloud_devices/common/cloud_devices_urls.h" #include "components/content_settings/core/common/features.h" #include "components/dom_distiller/core/dom_distiller_features.h" #include "components/google/core/common/google_util.h" @@ -59,6 +62,7 @@ #include "components/password_manager/core/browser/leak_detection_dialog_utils.h" #include "components/password_manager/core/browser/manage_passwords_referrer.h" #include "components/password_manager/core/common/password_manager_features.h" +#include "components/prefs/pref_service.h" #include "components/safe_browsing/core/common/safe_browsing_prefs.h" #include "components/signin/public/base/signin_buildflags.h" #include "components/strings/grit/components_chromium_strings.h" @@ -93,10 +97,8 @@ #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h" #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" -#include "chrome/common/pref_names.h" #include "chrome/common/webui_url_constants.h" #include "chromeos/constants/chromeos_features.h" -#include "components/prefs/pref_service.h" #include "components/user_manager/user_manager.h" #include "ui/chromeos/devicetype_utils.h" #else // !defined(OS_CHROMEOS) @@ -140,6 +142,7 @@ void AddCommonStrings(content::WebUIDataSource* html_source, Profile* profile) { {"done", IDS_DONE}, {"edit", IDS_SETTINGS_EDIT}, {"extensionsLinkTooltip", IDS_SETTINGS_MENU_EXTENSIONS_LINK_TOOLTIP}, + {"fonts", IDS_SETTINGS_FONTS}, {"learnMore", IDS_LEARN_MORE}, {"menu", IDS_MENU}, {"menuButtonLabel", IDS_SETTINGS_MENU_BUTTON_LABEL}, @@ -203,6 +206,8 @@ void AddA11yStrings(content::WebUIDataSource* html_source) { IDS_SETTINGS_CAPTIONS_ENABLE_LIVE_CAPTION_TITLE}, {"captionsEnableLiveCaptionSubtitle", IDS_SETTINGS_CAPTIONS_ENABLE_LIVE_CAPTION_SUBTITLE}, + {"caretBrowsingTitle", IDS_SETTINGS_ENABLE_CARET_BROWSING_TITLE}, + {"caretBrowsingSubtitle", IDS_SETTINGS_ENABLE_CARET_BROWSING_SUBTITLE}, #if defined(OS_CHROMEOS) {"manageAccessibilityFeatures", IDS_SETTINGS_ACCESSIBILITY_MANAGE_ACCESSIBILITY_FEATURES}, @@ -275,9 +280,7 @@ void AddAboutStrings(content::WebUIDataSource* html_source, Profile* profile) { ? IDS_VERSION_UI_OFFICIAL : IDS_VERSION_UI_UNOFFICIAL), base::UTF8ToUTF16(chrome::GetChannelName()), - l10n_util::GetStringUTF16(sizeof(void*) == 8 - ? IDS_VERSION_UI_64BIT - : IDS_VERSION_UI_32BIT))); + l10n_util::GetStringUTF16(VersionUI::VersionProcessorVariation()))); html_source->AddString( "aboutProductCopyright", base::i18n::MessageFormatter::FormatWithNumberedArgs( @@ -324,7 +327,6 @@ void AddAppearanceStrings(content::WebUIDataSource* html_source, {"pageZoom", IDS_SETTINGS_PAGE_ZOOM_LABEL}, {"fontSize", IDS_SETTINGS_FONT_SIZE_LABEL}, {"customizeFonts", IDS_SETTINGS_CUSTOMIZE_FONTS}, - {"fonts", IDS_SETTINGS_FONTS}, {"standardFont", IDS_SETTINGS_STANDARD_FONT_LABEL}, {"serifFont", IDS_SETTINGS_SERIF_FONT_LABEL}, {"sansSerifFont", IDS_SETTINGS_SANS_SERIF_FONT_LABEL}, @@ -341,7 +343,7 @@ void AddAppearanceStrings(content::WebUIDataSource* html_source, #else {"resetToDefaultTheme", IDS_SETTINGS_RESET_TO_DEFAULT_THEME}, #endif -#if defined(OS_MACOSX) +#if defined(OS_MAC) {"tabsToLinks", IDS_SETTINGS_TABS_TO_LINKS_PREF}, {"warnBeforeQuitting", IDS_SETTINGS_WARN_BEFORE_QUITTING_PREF}, #endif @@ -390,6 +392,10 @@ void AddClearBrowsingDataStrings(content::WebUIDataSource* html_source, {"historyDeletionDialogTitle", IDS_CLEAR_BROWSING_DATA_HISTORY_NOTICE_TITLE}, {"historyDeletionDialogOK", IDS_CLEAR_BROWSING_DATA_HISTORY_NOTICE_OK}, + {"passwordsDeletionDialogTitle", + IDS_CLEAR_BROWSING_DATA_PASSWORDS_NOTICE_TITLE}, + {"passwordsDeletionDialogOK", + IDS_CLEAR_BROWSING_DATA_PASSWORDS_NOTICE_OK}, {"installedAppsConfirm", IDS_SETTINGS_CLEAR_INSTALLED_APPS_DATA_CONFIRM}, {"installedAppsTitle", IDS_SETTINGS_CLEAR_INSTALLED_APPS_DATA_TITLE}, {"notificationWarning", IDS_SETTINGS_NOTIFICATION_WARNING}, @@ -411,6 +417,11 @@ void AddClearBrowsingDataStrings(content::WebUIDataSource* html_source, IDS_CLEAR_BROWSING_DATA_HISTORY_NOTICE, l10n_util::GetStringUTF16( IDS_SETTINGS_CLEAR_DATA_MYACTIVITY_URL_IN_DIALOG))); + html_source->AddString( + "passwordsDeletionDialogBody", + l10n_util::GetStringFUTF16( + IDS_CLEAR_BROWSING_DATA_PASSWORDS_NOTICE, + l10n_util::GetStringUTF16(IDS_PASSWORDS_WEB_LINK))); AddLocalizedStringsBulk(html_source, kLocalizedStrings); } @@ -660,7 +671,7 @@ void AddLanguagesStrings(content::WebUIDataSource* html_source, IDS_SETTINGS_LANGUAGES_SPELL_CHECK_ENHANCED_LABEL}, {"spellCheckEnhancedDescription", IDS_SETTINGS_LANGUAGES_SPELL_CHECK_ENHANCED_DESCRIPTION}, -#if !defined(OS_MACOSX) +#if !defined(OS_MAC) {"spellCheckDisabledReason", IDS_SETTING_LANGUAGES_SPELL_CHECK_DISABLED_REASON}, {"spellCheckLanguagesListTitle", @@ -815,16 +826,11 @@ void AddAutofillStrings(content::WebUIDataSource* html_source, IDS_SETTINGS_COMPROMISED_PASSWORD_REASON_PHISHED_AND_LEAKED}, {"showCompromisedPassword", IDS_SETTINGS_COMPROMISED_PASSWORD_SHOW}, {"hideCompromisedPassword", IDS_SETTINGS_COMPROMISED_PASSWORD_HIDE}, - {"editCompromisedPassword", IDS_SETTINGS_COMPROMISED_PASSWORD_EDIT}, {"removeCompromisedPassword", IDS_SETTINGS_COMPROMISED_PASSWORD_REMOVE}, {"removeCompromisedPasswordConfirmationTitle", IDS_SETTINGS_REMOVE_COMPROMISED_PASSWORD_CONFIRMATION_TITLE}, {"removeCompromisedPasswordConfirmationDescription", IDS_SETTINGS_REMOVE_COMPROMISED_PASSWORD_CONFIRMATION_DESCRIPTION}, - {"editCompromisedPasswordTitle", - IDS_SETTINGS_COMPROMISED_EDIT_PASSWORD_TITLE}, - {"editCompromisedPasswordFootnote", - IDS_SETTINGS_COMPROMISED_EDIT_PASSWORD_FOOTNOTE}, {"editCompromisedPasswordSite", IDS_SETTINGS_COMPROMISED_EDIT_PASSWORD_SITE}, {"editCompromisedPasswordApp", @@ -871,6 +877,7 @@ void AddAutofillStrings(content::WebUIDataSource* html_source, {"migratableCardsInfoSingle", IDS_SETTINGS_SINGLE_MIGRATABLE_CARD_INFO}, {"migratableCardsInfoMultiple", IDS_SETTINGS_MULTIPLE_MIGRATABLE_CARDS_INFO}, + {"remoteCreditCardLinkLabel", IDS_SETTINGS_REMOTE_CREDIT_CARD_LINK_LABEL}, {"upiIdLabel", IDS_SETTINGS_UPI_ID_LABEL}, {"upiIdExpirationNever", IDS_SETTINGS_UPI_ID_EXPIRATION_NEVER}, {"canMakePaymentToggleLabel", IDS_SETTINGS_CAN_MAKE_PAYMENT_TOGGLE_LABEL}, @@ -900,6 +907,9 @@ void AddAutofillStrings(content::WebUIDataSource* html_source, {"hidePassword", IDS_SETTINGS_PASSWORD_HIDE}, {"passwordDetailsTitle", IDS_SETTINGS_PASSWORDS_VIEW_DETAILS_TITLE}, {"passwordViewDetails", IDS_SETTINGS_PASSWORD_DETAILS}, + {"editPasswordTitle", IDS_SETTINGS_PASSWORD_EDIT_TITLE}, + {"editPassword", IDS_SETTINGS_PASSWORD_EDIT}, + {"editPasswordFootnote", IDS_SETTINGS_PASSWORD_EDIT_FOOTNOTE}, {"copyPassword", IDS_SETTINGS_PASSWORD_COPY}, {"passwordStoredOnDevice", IDS_SETTINGS_PASSWORD_STORED_ON_DEVICE}, {"passwordStoredInAccount", IDS_SETTINGS_PASSWORD_STORED_IN_ACCOUNT}, @@ -1013,11 +1023,22 @@ void AddAutofillStrings(content::WebUIDataSource* html_source, autofill::payments::GetManageInstrumentsUrl().spec()); html_source->AddString("paymentMethodsLearnMoreURL", chrome::kPaymentMethodsLearnMoreURL); - html_source->AddString( - "siteSettingsFlashWildcardsUnsupported", - l10n_util::GetStringFUTF16( - IDS_SETTINGS_SITE_SETTINGS_FLASH_WILDCARD_UNSUPPORTED, - base::UTF8ToUTF16(chrome::kChromeFlashRoadmapURL))); + // The warning message that will be shown if there is a content setting + // pattern with a wildcard in it. The check for wildcards is done on the js + // side. + base::string16 flash_warning_message; + if (base::FeatureList::IsEnabled( + content_settings::kDisallowExtensionsToSetPluginContentSettings)) { + flash_warning_message = l10n_util::GetStringFUTF16( + IDS_SETTINGS_SITE_SETTINGS_FLASH_WILDCARD_UNSUPPORTED_IN_POLICIES, + base::UTF8ToUTF16(chrome::kChromeFlashRoadmapURL)); + } else { + flash_warning_message = l10n_util::GetStringFUTF16( + IDS_SETTINGS_SITE_SETTINGS_FLASH_WILDCARD_UNSUPPORTED, + base::UTF8ToUTF16(chrome::kChromeFlashRoadmapURL)); + } + html_source->AddString("warningAboutIgnoredWildcardedPatternsForFlash", + flash_warning_message); bool is_guest_mode = false; #if defined(OS_CHROMEOS) @@ -1182,11 +1203,10 @@ void AddPeopleStrings(content::WebUIDataSource* html_source, Profile* profile) { AddSyncPageStrings(html_source); } -void AddPrintingStrings(content::WebUIDataSource* html_source) { +void AddPrintingStrings(content::WebUIDataSource* html_source, + Profile* profile) { static constexpr webui::LocalizedString kLocalizedStrings[] = { {"printingPageTitle", IDS_SETTINGS_PRINTING}, - {"printingCloudPrintLearnMoreLabel", - IDS_SETTINGS_PRINTING_CLOUD_PRINT_LEARN_MORE_LABEL}, {"printingNotificationsLabel", IDS_SETTINGS_PRINTING_NOTIFICATIONS_LABEL}, {"printingManageCloudPrintDevices", IDS_SETTINGS_PRINTING_MANAGE_CLOUD_PRINT_DEVICES}, @@ -1197,9 +1217,31 @@ void AddPrintingStrings(content::WebUIDataSource* html_source) { }; AddLocalizedStringsBulk(html_source, kLocalizedStrings); - html_source->AddString("devicesUrl", chrome::kChromeUIDevicesURL); - html_source->AddString("printingCloudPrintLearnMoreUrl", - chrome::kCloudPrintLearnMoreURL); + html_source->AddString("cloudPrintersUrl", + cloud_devices::GetCloudPrintPrintersURL().spec()); + + html_source->AddBoolean("cloudPrintDeprecationWarningsSuppressed", + profile->GetPrefs()->GetBoolean( + prefs::kCloudPrintDeprecationWarningsSuppressed)); + + const bool enterprise_managed = webui::IsEnterpriseManaged(); + html_source->AddLocalizedString( + "cloudPrintWarning", + enterprise_managed + ? IDS_SETTINGS_PRINTING_GOOGLE_CLOUD_PRINT_NOT_SUPPORTED_WARNING_ENTERPRISE + : IDS_SETTINGS_PRINTING_GOOGLE_CLOUD_PRINT_NOT_SUPPORTED_WARNING); + + if (enterprise_managed) { + html_source->AddLocalizedString( + "cloudPrintFullWarning", + IDS_SETTINGS_PRINTING_GOOGLE_CLOUD_PRINT_NOT_SUPPORTED_WARNING_ENTERPRISE); + } else { + html_source->AddString( + "cloudPrintFullWarning", + l10n_util::GetStringFUTF16( + IDS_SETTINGS_PRINTING_GOOGLE_CLOUD_PRINT_NOT_SUPPORTED_FULL_WARNING, + base::ASCIIToUTF16(cloud_devices::kCloudPrintDeprecationHelpURL))); + } } void AddPrivacyStrings(content::WebUIDataSource* html_source, @@ -1422,9 +1464,7 @@ void AddSearchInSettingsStrings(content::WebUIDataSource* html_source) { {"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}, + {"clearSearch", IDS_CLEAR_SEARCH}, }; AddLocalizedStringsBulk(html_source, kLocalizedStrings); @@ -1684,13 +1724,13 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source, IDS_SETTINGS_SITE_SETTINGS_BLUETOOTH_DEVICES_ASK_RECOMMENDED}, {"siteSettingsBluetoothDevicesBlock", IDS_SETTINGS_SITE_SETTINGS_BLUETOOTH_DEVICES_BLOCK}, - {"siteSettingsNativeFileSystemWrite", + {"siteSettingsFileSystemWrite", IDS_SETTINGS_SITE_SETTINGS_NATIVE_FILE_SYSTEM_WRITE}, - {"siteSettingsNativeFileSystemWriteAsk", + {"siteSettingsFileSystemWriteAsk", IDS_SETTINGS_SITE_SETTINGS_NATIVE_FILE_SYSTEM_WRITE_ASK}, - {"siteSettingsNativeFileSystemWriteAskRecommended", + {"siteSettingsFileSystemWriteAskRecommended", IDS_SETTINGS_SITE_SETTINGS_NATIVE_FILE_SYSTEM_WRITE_ASK_RECOMMENDED}, - {"siteSettingsNativeFileSystemWriteBlock", + {"siteSettingsFileSystemWriteBlock", IDS_SETTINGS_SITE_SETTINGS_NATIVE_FILE_SYSTEM_WRITE_BLOCK}, {"siteSettingsRemoveZoomLevel", IDS_SETTINGS_SITE_SETTINGS_REMOVE_ZOOM_LEVEL}, @@ -1935,6 +1975,9 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source, IDS_SETTINGS_SITE_SETTINGS_WINDOW_PLACEMENT_ASK_RECOMMENDED}, {"siteSettingsWindowPlacementBlock", IDS_SETTINGS_SITE_SETTINGS_WINDOW_PLACEMENT_BLOCK}, + {"siteSettingsFontAccessAsk", IDS_SETTINGS_SITE_SETTINGS_FONT_ACCESS_ASK}, + {"siteSettingsFontAccessBlock", + IDS_SETTINGS_SITE_SETTINGS_FONT_ACCESS_BLOCK}, }; AddLocalizedStringsBulk(html_source, kLocalizedStrings); @@ -1978,7 +2021,7 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source, cmd.HasSwitch(::switches::kEnableExperimentalWebPlatformFeatures)); html_source->AddBoolean( - "enableNativeFileSystemWriteContentSetting", + "enableFileSystemWriteContentSetting", base::FeatureList::IsEnabled(::blink::features::kNativeFileSystemAPI)); html_source->AddBoolean( @@ -1991,12 +2034,6 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source, base::FeatureList::IsEnabled(features::kMixedContentSiteSetting)); html_source->AddBoolean( - "showImprovedCookieControlsForThirdParties", - base::FeatureList::IsEnabled( - content_settings :: - kImprovedCookieControlsForThirdPartyCookieBlocking)); - - html_source->AddBoolean( "enableStoragePressureUI", base::FeatureList::IsEnabled(features::kStoragePressureUI)); @@ -2008,6 +2045,10 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source, base::FeatureList::IsEnabled( features::kWebBluetoothNewPermissionsBackend)); + html_source->AddBoolean( + "enableFontAccessContentSetting", + base::FeatureList::IsEnabled(::blink::features::kFontAccess)); + // The exception placeholder should not be translated. See crbug.com/1095878. html_source->AddString("addSiteExceptionPlaceholder", "[*.]example.com"); } @@ -2016,7 +2057,7 @@ void AddSiteSettingsStrings(content::WebUIDataSource* html_source, void AddSystemStrings(content::WebUIDataSource* html_source) { static constexpr webui::LocalizedString kLocalizedStrings[] = { {"systemPageTitle", IDS_SETTINGS_SYSTEM}, -#if !defined(OS_MACOSX) +#if !defined(OS_MAC) {"backgroundAppsLabel", IDS_SETTINGS_SYSTEM_BACKGROUND_APPS_LABEL}, #endif {"hardwareAccelerationLabel", @@ -2177,7 +2218,7 @@ void AddLocalizedStrings(content::WebUIDataSource* html_source, AddLanguagesStrings(html_source, profile); AddOnStartupStrings(html_source); AddPeopleStrings(html_source, profile); - AddPrintingStrings(html_source); + AddPrintingStrings(html_source, profile); AddPrivacyStrings(html_source, profile); AddResetStrings(html_source, profile); AddSearchEnginesStrings(html_source); diff --git a/chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc b/chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc index 85887e9be9a..299fdea9e04 100644 --- a/chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc @@ -205,7 +205,6 @@ void SecureDnsHandler::HandleProbeCustomDnsTemplate( net::DnsConfigOverrides overrides; overrides.search = std::vector<std::string>(); overrides.attempts = 1; - overrides.randomize_ports = false; overrides.secure_dns_mode = net::DnsConfig::SecureDnsMode::SECURE; secure_dns::ApplyTemplate(&overrides, server_template); DCHECK(!runner_); diff --git a/chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler_browsertest.cc b/chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler_browsertest.cc index 81aa1024fc1..378b66eb82a 100644 --- a/chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler_browsertest.cc +++ b/chromium/chrome/browser/ui/webui/settings/settings_secure_dns_handler_browsertest.cc @@ -174,7 +174,7 @@ class SecureDnsHandlerTest : public InProcessBrowserTest { // Sets a policy update which will cause power pref managed change. void SetPolicyForPolicyKey(policy::PolicyMap* policy_map, const std::string& policy_key, - std::unique_ptr<base::Value> value) { + base::Value value) { policy_map->Set(policy_key, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD, std::move(value), nullptr); @@ -225,9 +225,8 @@ IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, SecureDnsModes) { IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, SecureDnsPolicy) { policy::PolicyMap policy_map; - SetPolicyForPolicyKey( - &policy_map, policy::key::kDnsOverHttpsMode, - std::make_unique<base::Value>(SecureDnsConfig::kModeAutomatic)); + SetPolicyForPolicyKey(&policy_map, policy::key::kDnsOverHttpsMode, + base::Value(SecureDnsConfig::kModeAutomatic)); PrefService* local_state = g_browser_process->local_state(); local_state->SetString(prefs::kDnsOverHttpsMode, @@ -245,9 +244,8 @@ IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, SecureDnsPolicy) { IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, SecureDnsPolicyChange) { policy::PolicyMap policy_map; - SetPolicyForPolicyKey( - &policy_map, policy::key::kDnsOverHttpsMode, - std::make_unique<base::Value>(SecureDnsConfig::kModeAutomatic)); + SetPolicyForPolicyKey(&policy_map, policy::key::kDnsOverHttpsMode, + base::Value(SecureDnsConfig::kModeAutomatic)); std::string secure_dns_mode; std::vector<std::string> secure_dns_templates; @@ -258,9 +256,8 @@ IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, SecureDnsPolicyChange) { EXPECT_EQ(static_cast<int>(SecureDnsConfig::ManagementMode::kNoOverride), management_mode); - SetPolicyForPolicyKey( - &policy_map, policy::key::kDnsOverHttpsMode, - std::make_unique<base::Value>(SecureDnsConfig::kModeOff)); + SetPolicyForPolicyKey(&policy_map, policy::key::kDnsOverHttpsMode, + base::Value(SecureDnsConfig::kModeOff)); EXPECT_TRUE(GetLastSettingsChangedMessage( &secure_dns_mode, &secure_dns_templates, &management_mode)); EXPECT_EQ(SecureDnsConfig::kModeOff, secure_dns_mode); @@ -274,7 +271,7 @@ IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, SecureDnsPolicyChange) { IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, OtherPoliciesSet) { policy::PolicyMap policy_map; SetPolicyForPolicyKey(&policy_map, policy::key::kIncognitoModeAvailability, - std::make_unique<base::Value>(1)); + base::Value(1)); PrefService* local_state = g_browser_process->local_state(); local_state->SetString(prefs::kDnsOverHttpsMode, diff --git a/chromium/chrome/browser/ui/webui/settings/settings_ui.cc b/chromium/chrome/browser/ui/webui/settings/settings_ui.cc index 9e29823de46..6f76d852feb 100644 --- a/chromium/chrome/browser/ui/webui/settings/settings_ui.cc +++ b/chromium/chrome/browser/ui/webui/settings/settings_ui.cc @@ -43,7 +43,6 @@ #include "chrome/browser/ui/webui/settings/profile_info_handler.h" #include "chrome/browser/ui/webui/settings/protocol_handlers_handler.h" #include "chrome/browser/ui/webui/settings/reset_settings_handler.h" -#include "chrome/browser/ui/webui/settings/safe_browsing_handler.h" #include "chrome/browser/ui/webui/settings/safety_check_handler.h" #include "chrome/browser/ui/webui/settings/search_engines_handler.h" #include "chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h" @@ -66,7 +65,6 @@ #include "chrome/grit/generated_resources.h" #include "chrome/grit/settings_resources.h" #include "chrome/grit/settings_resources_map.h" -#include "components/content_settings/core/common/features.h" #include "components/favicon_base/favicon_url_parser.h" #include "components/password_manager/core/common/password_manager_features.h" #include "components/pref_registry/pref_registry_syncable.h" @@ -102,6 +100,7 @@ #include "chrome/browser/chromeos/android_sms/android_sms_app_manager.h" #include "chrome/browser/chromeos/android_sms/android_sms_service_factory.h" #include "chrome/browser/chromeos/multidevice_setup/multidevice_setup_client_factory.h" +#include "chrome/browser/chromeos/phonehub/phone_hub_manager_factory.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/ui/webui/certificate_provisioning_ui_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/account_manager_handler.h" @@ -111,6 +110,7 @@ #include "chrome/grit/browser_resources.h" #include "chromeos/components/account_manager/account_manager.h" #include "chromeos/components/account_manager/account_manager_factory.h" +#include "chromeos/components/phonehub/phone_hub_manager.h" #include "chromeos/constants/chromeos_features.h" #include "chromeos/login/auth/password_visibility_utils.h" #include "components/arc/arc_util.h" @@ -125,7 +125,7 @@ #if defined(USE_NSS_CERTS) #include "chrome/browser/ui/webui/certificates_handler.h" -#elif defined(OS_WIN) || defined(OS_MACOSX) +#elif defined(OS_WIN) || defined(OS_MAC) #include "chrome/browser/ui/webui/settings/native_certificates_handler.h" #endif // defined(USE_NSS_CERTS) @@ -162,22 +162,29 @@ SettingsUI::SettingsUI(content::WebUI* web_ui) Profile* profile = Profile::FromWebUI(web_ui); content::WebUIDataSource* html_source = content::WebUIDataSource::Create(chrome::kChromeUISettingsHost); + html_source->OverrideContentSecurityPolicy( + network::mojom::CSPDirectiveName::WorkerSrc, "worker-src blob: 'self';"); AddSettingsPageUIHandler(std::make_unique<AppearanceHandler>(web_ui)); #if defined(USE_NSS_CERTS) AddSettingsPageUIHandler( std::make_unique<certificate_manager::CertificatesHandler>()); -#elif defined(OS_WIN) || defined(OS_MACOSX) +#elif defined(OS_WIN) || defined(OS_MAC) AddSettingsPageUIHandler(std::make_unique<NativeCertificatesHandler>()); #endif // defined(USE_NSS_CERTS) #if defined(OS_CHROMEOS) AddSettingsPageUIHandler( - std::make_unique< - chromeos::cert_provisioning::CertificateProvisioningUiHandler>()); + chromeos::cert_provisioning::CertificateProvisioningUiHandler:: + CreateForProfile(profile)); #endif +#if defined(OS_CHROMEOS) AddSettingsPageUIHandler(std::make_unique<AccessibilityMainHandler>()); +#else + AddSettingsPageUIHandler( + std::make_unique<AccessibilityMainHandler>(profile->GetPrefs())); +#endif // defined(OS_CHROMEOS) AddSettingsPageUIHandler(std::make_unique<BrowserLifetimeHandler>()); AddSettingsPageUIHandler( std::make_unique<ClearBrowsingDataHandler>(web_ui, profile)); @@ -205,7 +212,6 @@ SettingsUI::SettingsUI(content::WebUI* web_ui) AddSettingsPageUIHandler(std::make_unique<PeopleHandler>(profile)); AddSettingsPageUIHandler(std::make_unique<ProfileInfoHandler>(profile)); AddSettingsPageUIHandler(std::make_unique<ProtocolHandlersHandler>()); - AddSettingsPageUIHandler(std::make_unique<SafeBrowsingHandler>(profile)); AddSettingsPageUIHandler(std::make_unique<SearchEnginesHandler>(profile)); AddSettingsPageUIHandler(std::make_unique<SecureDnsHandler>()); AddSettingsPageUIHandler(std::make_unique<SiteSettingsHandler>( @@ -217,7 +223,7 @@ SettingsUI::SettingsUI(content::WebUI* web_ui) AddSettingsPageUIHandler( std::make_unique<SecurityKeysBioEnrollmentHandler>()); -#if defined(OS_WIN) || defined(OS_MACOSX) +#if defined(OS_WIN) || defined(OS_MAC) AddSettingsPageUIHandler(std::make_unique<CaptionsHandler>()); #endif @@ -252,13 +258,6 @@ SettingsUI::SettingsUI(content::WebUI* web_ui) html_source->AddBoolean("signinAllowed", !profile->IsGuestSession() && profile->GetPrefs()->GetBoolean( prefs::kSigninAllowed)); - html_source->AddBoolean( - "improvedCookieControlsEnabled", - base::FeatureList::IsEnabled(content_settings::kImprovedCookieControls)); - - html_source->AddBoolean( - "privacySettingsRedesignEnabled", - base::FeatureList::IsEnabled(features::kPrivacySettingsRedesign)); html_source->AddBoolean( "safeBrowsingEnhancedEnabled", @@ -272,6 +271,11 @@ SettingsUI::SettingsUI(content::WebUI* web_ui) "enablePasswordCheck", base::FeatureList::IsEnabled(password_manager::features::kPasswordCheck)); + html_source->AddBoolean( + "editPasswordsInSettings", + base::FeatureList::IsEnabled( + password_manager::features::kEditPasswordsInDesktopSettings)); + html_source->AddBoolean("showImportPasswords", base::FeatureList::IsEnabled( password_manager::features::kPasswordImport)); @@ -285,6 +289,10 @@ SettingsUI::SettingsUI(content::WebUI* web_ui) "syncSetupFriendlySettings", base::FeatureList::IsEnabled(features::kSyncSetupFriendlySettings)); + html_source->AddBoolean( + "enableContentSettingsRedesign", + base::FeatureList::IsEnabled(features::kContentSettingsRedesign)); + #if defined(OS_WIN) html_source->AddBoolean( "safetyCheckChromeCleanerChildEnabled", @@ -303,13 +311,12 @@ SettingsUI::SettingsUI(content::WebUI* web_ui) chromeos::ProfileHelper::Get() ->GetUserByProfile(profile) ->GetAccountId())); -#endif -#if defined(OS_CHROMEOS) // This is the browser settings page. html_source->AddBoolean("isOSSettings", false); #endif - AddSettingsPageUIHandler(std::make_unique<AboutHandler>()); + + AddSettingsPageUIHandler(std::make_unique<AboutHandler>(profile)); AddSettingsPageUIHandler(std::make_unique<ResetSettingsHandler>(profile)); // Add a handler to provide pluralized strings. @@ -404,11 +411,15 @@ void SettingsUI::InitBrowserSettingsWebUIHandlers() { chromeos::android_sms::AndroidSmsService* android_sms_service = chromeos::android_sms::AndroidSmsServiceFactory::GetForBrowserContext( profile); + chromeos::phonehub::PhoneHubManager* phone_hub_manager = + chromeos::phonehub::PhoneHubManagerFactory::GetForProfile(profile); web_ui()->AddMessageHandler( std::make_unique<chromeos::settings::MultideviceHandler>( profile->GetPrefs(), chromeos::multidevice_setup::MultiDeviceSetupClientFactory:: GetForProfile(profile), + phone_hub_manager ? phone_hub_manager->notification_access_manager() + : nullptr, android_sms_service ? android_sms_service->android_sms_pairing_state_tracker() : nullptr, diff --git a/chromium/chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.cc b/chromium/chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.cc index ae20e5716f0..721c9aa404a 100644 --- a/chromium/chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.cc +++ b/chromium/chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.cc @@ -4,6 +4,8 @@ #include "chrome/browser/ui/webui/settings/shared_settings_localized_strings_provider.h" +#include <string> + #include "base/feature_list.h" #include "base/strings/utf_string_conversions.h" #include "base/system/sys_info.h" @@ -246,7 +248,37 @@ void AddSyncPageStrings(content::WebUIDataSource* html_source) { void AddNearbyShareData(content::WebUIDataSource* html_source) { static constexpr webui::LocalizedString kLocalizedStrings[] = { {"nearbyShareTitle", IDS_SETTINGS_NEARBY_SHARE_TITLE}, - }; + {"nearbyShareDeviceNameRowTitle", + IDS_SETTINGS_NEARBY_SHARE_DEVICE_NAME_ROW_TITLE}, + {"nearbyShareDeviceNameDialogTitle", + IDS_SETTINGS_NEARBY_SHARE_DEVICE_NAME_DIALOG_TITLE}, + {"nearbyShareDeviceNameDialogInputLabel", + IDS_SETTINGS_NEARBY_SHARE_DEVICE_NAME_INPUT_LABEL}, + {"nearbyShareEditDeviceName", IDS_SETTINGS_NEARBY_SHARE_EDIT_DEVICE_NAME}, + {"nearbyShareDeviceNameAriaDescription", + IDS_SETTINGS_NEARBY_SHARE_DEVICE_NAME_ARIA_DESCRIPTION}, + {"editDataUsage", IDS_SETTINGS_NEARBY_SHARE_EDIT_DATA_USAGE}, + {"updateDataUsage", IDS_SETTINGS_NEARBY_SHARE_UPDATE_DATA_USAGE}, + {"nearbyShareDataUsageDialogTitle", + IDS_SETTINGS_NEARBY_SHARE_DATA_USAGE_DIALOG_TITLE}, + {"nearbyShareDataUsageWifiOnlyLabel", + IDS_SETTINGS_NEARBY_SHARE_DATA_USAGE_WIFI_ONLY_LABEL}, + {"nearbyShareDataUsageWifiOnlyDescription", + IDS_SETTINGS_NEARBY_SHARE_DATA_USAGE_WIFI_ONLY_DESCRIPTION}, + {"nearbyShareDataUsageDataLabel", + IDS_SETTINGS_NEARBY_SHARE_DATA_USAGE_DATA_LABEL}, + {"nearbyShareDataUsageDataDescription", + IDS_SETTINGS_NEARBY_SHARE_DATA_USAGE_DATA_DESCRIPTION}, + {"nearbyShareDataUsageOfflineLabel", + IDS_SETTINGS_NEARBY_SHARE_DATA_USAGE_OFFLINE_LABEL}, + {"nearbyShareDataUsageOfflineDescription", + IDS_SETTINGS_NEARBY_SHARE_DATA_USAGE_OFFLINE_DESCRIPTION}, + {"nearbyShareDataUsageDataEditButtonDescription", + IDS_SETTINGS_NEARBY_SHARE_DATA_USAGE_EDIT_BUTTON_DATA_DESCRIPTION}, + {"nearbyShareDataUsageWifiOnlyEditButtonDescription", + IDS_SETTINGS_NEARBY_SHARE_DATA_USAGE_EDIT_BUTTON_WIFI_ONLY_DESCRIPTION}, + {"nearbyShareDataUsageOfflineEditButtonDescription", + IDS_SETTINGS_NEARBY_SHARE_DATA_USAGE_EDIT_BUTTON_OFFLINE_DESCRIPTION}}; AddLocalizedStringsBulk(html_source, kLocalizedStrings); html_source->AddBoolean( diff --git a/chromium/chrome/browser/ui/webui/settings/site_settings_handler.cc b/chromium/chrome/browser/ui/webui/settings/site_settings_handler.cc index bcbafdd8e31..8f9bdf2ebb6 100644 --- a/chromium/chrome/browser/ui/webui/settings/site_settings_handler.cc +++ b/chromium/chrome/browser/ui/webui/settings/site_settings_handler.cc @@ -48,7 +48,6 @@ #include "components/content_settings/core/browser/website_settings_registry.h" #include "components/content_settings/core/common/content_settings_types.h" #include "components/content_settings/core/common/content_settings_utils.h" -#include "components/content_settings/core/common/features.h" #include "components/content_settings/core/common/pref_names.h" #include "components/crx_file/id_util.h" #include "components/permissions/chooser_context_base.h" @@ -139,9 +138,8 @@ void AddExceptionsGrantedByHostedApps( const extensions::URLPatternSet& web_extent = (*extension)->web_extent(); // Add patterns from web extent. - for (auto pattern = web_extent.begin(); pattern != web_extent.end(); - ++pattern) { - std::string url_pattern = pattern->GetAsString(); + for (const auto& pattern : web_extent) { + std::string url_pattern = pattern.GetAsString(); site_settings::AddExceptionForHostedApp(url_pattern, *extension->get(), exceptions); } @@ -292,6 +290,18 @@ bool IsPatternValidForType(const std::string& pattern_string, HostContentSettingsMap* map = HostContentSettingsMapFactory::GetForProfile(profile); + // Don't allow patterns for WebUI schemes, even though it's a valid pattern. + // WebUI permissions are controlled by ContentSettingsRegistry + // WhitelistedSchemes and WebUIAllowlist. Users shouldn't be able to grant + // extra permissions or revoke existing permissions. + if (pattern.GetScheme() == ContentSettingsPattern::SCHEME_CHROME || + pattern.GetScheme() == ContentSettingsPattern::SCHEME_CHROMEUNTRUSTED || + pattern.GetScheme() == ContentSettingsPattern::SCHEME_DEVTOOLS || + pattern.GetScheme() == ContentSettingsPattern::SCHEME_CHROMESEARCH) { + *out_error = l10n_util::GetStringUTF8(IDS_SETTINGS_NOT_VALID_WEB_ADDRESS); + return false; + } + // Don't allow an input of '*', even though it's a valid pattern. This // changes the default setting. if (!pattern.IsValid() || pattern == ContentSettingsPattern::Wildcard()) { @@ -361,10 +371,8 @@ std::string GetCookieSettingDescription(Profile* profile) { } else if (block_third_party) { return l10n_util::GetStringUTF8( IDS_SETTINGS_SITE_SETTINGS_COOKIES_BLOCK_THIRD_PARTY); - } else if (base::FeatureList::IsEnabled( - content_settings::kImprovedCookieControls) && - control_mode == - content_settings::CookieControlsMode::kIncognitoOnly) { + } else if (control_mode == + content_settings::CookieControlsMode::kIncognitoOnly) { return l10n_util::GetStringUTF8( IDS_SETTINGS_SITE_SETTINGS_COOKIES_BLOCK_THIRD_PARTY_INCOGNITO); } else { diff --git a/chromium/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc index 95b114fb5dc..eba93151cc0 100644 --- a/chromium/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc +++ b/chromium/chrome/browser/ui/webui/settings/site_settings_handler_unittest.cc @@ -10,12 +10,12 @@ #include <vector> #include "base/bind_helpers.h" +#include "base/command_line.h" #include "base/files/scoped_temp_dir.h" #include "base/json/json_reader.h" #include "base/logging.h" #include "base/strings/utf_string_conversions.h" #include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_feature_list.h" #include "base/test/simple_test_clock.h" #include "base/values.h" #include "build/build_config.h" @@ -43,7 +43,6 @@ #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/content_settings/core/common/content_settings.h" #include "components/content_settings/core/common/content_settings_types.h" -#include "components/content_settings/core/common/features.h" #include "components/content_settings/core/common/pref_names.h" #include "components/history/core/browser/history_service.h" #include "components/infobars/core/infobar.h" @@ -54,6 +53,7 @@ #include "components/sync_preferences/testing_pref_service_syncable.h" #include "components/ukm/test_ukm_recorder.h" #include "content/public/browser/navigation_controller.h" +#include "content/public/browser/storage_partition.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" @@ -96,6 +96,10 @@ const struct PatternContentTypeTestCase { {{"https://google.com", "cookies"}, {true, ""}}, {{";", "cookies"}, {false, "Not a valid web address"}}, {{"*", "cookies"}, {false, "Not a valid web address"}}, + {{"chrome://test", "popups"}, {false, "Not a valid web address"}}, + {{"chrome-untrusted://test", "popups"}, {false, "Not a valid web address"}}, + {{"devtools://devtools", "popups"}, {false, "Not a valid web address"}}, + {{"chrome-search://search", "popups"}, {false, "Not a valid web address"}}, {{"http://google.com", "location"}, {false, "Origin must be secure"}}, {{"http://127.0.0.1", "location"}, {true, ""}}, // Localhost is secure. {{"http://[::1]", "location"}, {true, ""}}}; @@ -197,8 +201,6 @@ class SiteSettingsHandlerTest : public testing::Test { TestingProfile::Builder profile_builder; profile_builder.SetPath(profile_dir_.GetPath()); profile_ = profile_builder.Build(); - feature_list_.InitAndEnableFeature( - content_settings::kImprovedCookieControls); } void SetUp() override { @@ -206,9 +208,22 @@ class SiteSettingsHandlerTest : public testing::Test { std::make_unique<SiteSettingsHandler>(profile_.get(), app_registrar_); handler()->set_web_ui(web_ui()); handler()->AllowJavascript(); + // AllowJavascript() adds a callback to create leveldb_env::ChromiumEnv + // which reads the FeatureList. Wait for the callback to be finished so that + // we won't destruct |feature_list_| before the callback is executed. + base::RunLoop().RunUntilIdle(); web_ui()->ClearTrackedCalls(); } + void TearDown() override { + if (profile_) { + auto* partition = + content::BrowserContext::GetDefaultStoragePartition(profile_.get()); + if (partition) + partition->WaitForDeletionTasksForTesting(); + } + } + TestingProfile* profile() { return profile_.get(); } TestingProfile* incognito_profile() { return incognito_profile_; } web_app::TestAppRegistrar& app_registrar() { return app_registrar_; } @@ -517,7 +532,6 @@ class SiteSettingsHandlerTest : public testing::Test { web_app::TestAppRegistrar app_registrar_; content::TestWebUI web_ui_; std::unique_ptr<SiteSettingsHandler> handler_; - base::test::ScopedFeatureList feature_list_; #if defined(OS_CHROMEOS) std::unique_ptr<user_manager::ScopedUserManager> user_manager_enabler_; #endif @@ -548,12 +562,7 @@ TEST_F(SiteSettingsHandlerTest, GetAndSetDefault) { } // Flaky on CrOS and Linux. https://crbug.com/930481 -#if defined(OS_CHROMEOS) || defined(OS_LINUX) -#define MAYBE_GetAllSites DISABLED_GetAllSites -#else -#define MAYBE_GetAllSites GetAllSites -#endif -TEST_F(SiteSettingsHandlerTest, MAYBE_GetAllSites) { +TEST_F(SiteSettingsHandlerTest, GetAllSites) { base::ListValue get_all_sites_args; get_all_sites_args.AppendString(kCallbackId); base::Value category_list(base::Value::Type::LIST); @@ -1205,8 +1214,7 @@ TEST_F(SiteSettingsHandlerTest, Origins) { TEST_F(SiteSettingsHandlerTest, NotificationPermissionRevokeUkm) { const std::string google("https://www.google.com"); ukm::TestAutoSetUkmRecorder ukm_recorder; - ASSERT_TRUE(profile()->CreateHistoryService(/* delete_file= */ true, - /* no_db= */ false)); + ASSERT_TRUE(profile()->CreateHistoryService()); auto* history_service = HistoryServiceFactory::GetForProfile( profile(), ServiceAccessType::EXPLICIT_ACCESS); history_service->AddPage(GURL(google), base::Time::Now(), @@ -1262,8 +1270,7 @@ TEST_F(SiteSettingsHandlerTest, NotificationPermissionRevokeUkm) { #define MAYBE_DefaultSettingSource DefaultSettingSource #endif TEST_F(SiteSettingsHandlerTest, MAYBE_DefaultSettingSource) { - ASSERT_TRUE(profile()->CreateHistoryService(/* delete_file= */ true, - /* no_db= */ false)); + ASSERT_TRUE(profile()->CreateHistoryService()); // Use a non-default port to verify the display name does not strip this // off. diff --git a/chromium/chrome/browser/ui/webui/settings/site_settings_helper.cc b/chromium/chrome/browser/ui/webui/settings/site_settings_helper.cc index 28addc32434..32c1db01bda 100644 --- a/chromium/chrome/browser/ui/webui/settings/site_settings_helper.cc +++ b/chromium/chrome/browser/ui/webui/settings/site_settings_helper.cc @@ -10,11 +10,8 @@ #include <string> #include "base/feature_list.h" -#include "base/no_destructor.h" #include "base/stl_util.h" -#include "base/strings/strcat.h" #include "base/strings/string16.h" -#include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "chrome/browser/bluetooth/bluetooth_chooser_context.h" @@ -26,6 +23,9 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/serial/serial_chooser_context.h" #include "chrome/browser/serial/serial_chooser_context_factory.h" +#include "chrome/browser/subresource_filter/subresource_filter_content_settings_manager.h" +#include "chrome/browser/subresource_filter/subresource_filter_profile_context.h" +#include "chrome/browser/subresource_filter/subresource_filter_profile_context_factory.h" #include "chrome/browser/usb/usb_chooser_context.h" #include "chrome/browser/usb/usb_chooser_context_factory.h" #include "chrome/common/pref_names.h" @@ -47,7 +47,6 @@ #include "extensions/browser/extension_registry.h" #include "extensions/common/constants.h" #include "url/origin.h" -#include "url/url_constants.h" namespace site_settings { @@ -106,8 +105,7 @@ const ContentSettingsTypeNameEntry kContentSettingsTypeGroupNames[] = { {ContentSettingsType::BLUETOOTH_SCANNING, "bluetooth-scanning"}, {ContentSettingsType::HID_GUARD, "hid-devices"}, {ContentSettingsType::HID_CHOOSER_DATA, kHidChooserDataGroupType}, - {ContentSettingsType::NATIVE_FILE_SYSTEM_WRITE_GUARD, - "native-file-system-write"}, + {ContentSettingsType::FILE_SYSTEM_WRITE_GUARD, "file-system-write"}, {ContentSettingsType::MIXEDSCRIPT, "mixed-script"}, {ContentSettingsType::VR, "vr"}, {ContentSettingsType::AR, "ar"}, @@ -115,6 +113,7 @@ const ContentSettingsTypeNameEntry kContentSettingsTypeGroupNames[] = { {ContentSettingsType::BLUETOOTH_CHOOSER_DATA, kBluetoothChooserDataGroupType}, {ContentSettingsType::WINDOW_PLACEMENT, "window-placement"}, + {ContentSettingsType::FONT_ACCESS, "font-access"}, // Add new content settings here if a corresponding Javascript string // representation for it is not required. Note some exceptions do have UI in @@ -145,9 +144,10 @@ const ContentSettingsTypeNameEntry kContentSettingsTypeGroupNames[] = { {ContentSettingsType::INSTALLED_WEB_APP_METADATA, nullptr}, {ContentSettingsType::NFC, nullptr}, {ContentSettingsType::SAFE_BROWSING_URL_CHECK_DATA, nullptr}, - {ContentSettingsType::NATIVE_FILE_SYSTEM_READ_GUARD, nullptr}, + {ContentSettingsType::FILE_SYSTEM_READ_GUARD, nullptr}, {ContentSettingsType::STORAGE_ACCESS, nullptr}, {ContentSettingsType::CAMERA_PAN_TILT_ZOOM, nullptr}, + {ContentSettingsType::INSECURE_PRIVATE_NETWORK, nullptr}, }; static_assert(base::size(kContentSettingsTypeGroupNames) == // ContentSettingsType starts at -1, so add 1 here. @@ -162,7 +162,7 @@ struct SiteSettingSourceStringMapping { const SiteSettingSourceStringMapping kSiteSettingSourceStringMapping[] = { {SiteSettingSource::kAllowlist, "allowlist"}, - {SiteSettingSource::kAdsFilterBlacklist, "ads-filter-blacklist"}, + {SiteSettingSource::kAdsFilterBlocklist, "ads-filter-blacklist"}, {SiteSettingSource::kDefault, "default"}, {SiteSettingSource::kDrmDisabled, "drm-disabled"}, {SiteSettingSource::kEmbargo, "embargo"}, @@ -199,13 +199,6 @@ static_assert(base::size(kPolicyIndicatorTypeStringMapping) == "kPolicyIndicatorStringMapping should have " "PolicyIndicatorType::kNumIndicators elements"); -const std::string& GetDevtoolsPatternPrefix() { - static const base::NoDestructor<std::string> kDevtoolsPatternPrefix( - base::StrCat({content_settings::kChromeDevToolsScheme, - url::kStandardSchemeSeparator})); - return *kDevtoolsPatternPrefix; -} - // Retrieves the corresponding string, according to the following precedence // order from highest to lowest priority: // 1. Allowlisted WebUI content setting. @@ -246,12 +239,12 @@ SiteSettingSource CalculateSiteSettingSource( if (content_type == ContentSettingsType::ADS && base::FeatureList::IsEnabled( subresource_filter::kSafeBrowsingSubresourceFilter)) { - HostContentSettingsMap* map = - HostContentSettingsMapFactory::GetForProfile(profile); - if (map->GetWebsiteSetting(origin, GURL(), ContentSettingsType::ADS_DATA, - /*resource_identifier=*/std::string(), - /*setting_info=*/nullptr) != nullptr) { - return SiteSettingSource::kAdsFilterBlacklist; // Source #6. + SubresourceFilterContentSettingsManager* settings_manager = + SubresourceFilterProfileContextFactory::GetForProfile(profile) + ->settings_manager(); + + if (settings_manager->GetSiteActivationFromMetadata(origin)) { + return SiteSettingSource::kAdsFilterBlocklist; // Source #6. } } @@ -306,9 +299,8 @@ bool PatternAppliesToWebUISchemes(const ContentSettingPatternSource& pattern) { ContentSettingsPattern::SchemeType::SCHEME_CHROME || pattern.primary_pattern.GetScheme() == ContentSettingsPattern::SchemeType::SCHEME_CHROMEUNTRUSTED || - base::StartsWith(pattern.primary_pattern.ToString(), - GetDevtoolsPatternPrefix(), - base::CompareCase::INSENSITIVE_ASCII); + pattern.primary_pattern.GetScheme() == + ContentSettingsPattern::SchemeType::SCHEME_DEVTOOLS; } // Retrieves the source of a chooser exception as a string. This method uses the diff --git a/chromium/chrome/browser/ui/webui/settings/site_settings_helper.h b/chromium/chrome/browser/ui/webui/settings/site_settings_helper.h index 8ac89c83c11..afd78140f71 100644 --- a/chromium/chrome/browser/ui/webui/settings/site_settings_helper.h +++ b/chromium/chrome/browser/ui/webui/settings/site_settings_helper.h @@ -72,7 +72,7 @@ constexpr char kIsDiscarded[] = "isDiscarded"; enum class SiteSettingSource { kAllowlist, - kAdsFilterBlacklist, + kAdsFilterBlocklist, kDefault, kDrmDisabled, kEmbargo, |