Commit 509fe7c0 authored by Monica Basta's avatar Monica Basta Committed by Commit Bot

[settings] Add a color picker to manage profile page

This CL adds a cr-customize-themes element to
chrome://settings/manageProfile page behind a feature flag. This CL
focuses on the native side and it doesn't include necessary style
changes which will be included in future CLs. When the UI is ready, this
element will be put under the "NewProfilePicker" feature.

In order to use a cr-customize-themes component in WebUI, a
WebUIController class must enable mojo bindings and implement
customize_themes::mojom::CustomizeThemesHandlerFactory interface.
This CL applies these necessary changes to SettingsUI.

Screenshot with the feature flag enabled:
https://drive.google.com/file/d/1W1NITMHGbzHRzq1LeClp96Mh98B2MNGv/view?usp=sharing

Bug: 1129186
Change-Id: I18ead20f57e3bb0486e4821a946ea4e0aff3a242
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2414301
Commit-Queue: Monica Basta <msalama@chromium.org>
Reviewed-by: default avatarMustafa Emre Acer <meacer@chromium.org>
Reviewed-by: default avatardpapad <dpapad@chromium.org>
Cr-Commit-Position: refs/heads/master@{#809749}
parent 4eeee824
...@@ -120,6 +120,7 @@ ...@@ -120,6 +120,7 @@
#include "chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.h" #include "chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.h"
#include "chrome/browser/ui/webui/read_later/read_later.mojom.h" #include "chrome/browser/ui/webui/read_later/read_later.mojom.h"
#include "chrome/browser/ui/webui/read_later/read_later_ui.h" #include "chrome/browser/ui/webui/read_later/read_later_ui.h"
#include "chrome/browser/ui/webui/settings/settings_ui.h"
#include "chrome/browser/ui/webui/tab_search/tab_search.mojom.h" #include "chrome/browser/ui/webui/tab_search/tab_search.mojom.h"
#include "chrome/browser/ui/webui/tab_search/tab_search_ui.h" #include "chrome/browser/ui/webui/tab_search/tab_search_ui.h"
#include "chrome/common/caption.mojom.h" #include "chrome/common/caption.mojom.h"
...@@ -609,7 +610,7 @@ void PopulateChromeWebUIFrameBinders( ...@@ -609,7 +610,7 @@ void PopulateChromeWebUIFrameBinders(
customize_themes::mojom::CustomizeThemesHandlerFactory, NewTabPageUI customize_themes::mojom::CustomizeThemesHandlerFactory, NewTabPageUI
#if !defined(OS_CHROMEOS) #if !defined(OS_CHROMEOS)
, ,
ProfilePickerUI ProfilePickerUI, settings::SettingsUI
#endif // !defined(OS_CHROMEOS) #endif // !defined(OS_CHROMEOS)
>(map); >(map);
......
...@@ -33,7 +33,11 @@ if (optimize_webui) { ...@@ -33,7 +33,11 @@ if (optimize_webui) {
":unpak", ":unpak",
"../../../../ui/webui/resources:preprocess", "../../../../ui/webui/resources:preprocess",
] ]
excludes = [ "chrome://resources/js/cr.m.js" ] excludes = [
"chrome://resources/js/cr.m.js",
"chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js",
"chrome://resources/mojo/skia/public/mojom/skcolor.mojom-lite.js",
]
} }
unpak("unpak") { unpak("unpak") {
......
...@@ -153,6 +153,7 @@ if (!is_chromeos) { ...@@ -153,6 +153,7 @@ if (!is_chromeos) {
"..:route", "..:route",
"..:router.m", "..:router.m",
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
"//ui/webui/resources/cr_components/customize_themes",
] ]
} }
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
--cr-input-error-display: none; --cr-input-error-display: none;
} }
#selector { #avatarSelector {
margin: 16px 48px; margin: 16px 48px;
} }
</style> </style>
...@@ -27,6 +27,10 @@ ...@@ -27,6 +27,10 @@
</cr-toggle> </cr-toggle>
</div> </div>
</template> </template>
<cr-profile-avatar-selector id="selector" avatars="[[availableIcons]]" <template is="dom-if" if="[[isCustomizeThemesVisible_]]">
<cr-customize-themes id="themeSelector" auto-confirm-theme-changes>
</cr-customize-themes>
</template>
<cr-profile-avatar-selector id="avatarSelector" avatars="[[availableIcons]]"
selected-avatar="{{profileAvatar_}}" ignore-modified-key-events> selected-avatar="{{profileAvatar_}}" ignore-modified-key-events>
</cr-profile-avatar-selector> </cr-profile-avatar-selector>
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
import 'chrome://resources/cr_elements/cr_input/cr_input.m.js'; import 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
import 'chrome://resources/cr_elements/cr_toggle/cr_toggle.m.js'; import 'chrome://resources/cr_elements/cr_toggle/cr_toggle.m.js';
import 'chrome://resources/cr_elements/shared_style_css.m.js'; import 'chrome://resources/cr_elements/shared_style_css.m.js';
import 'chrome://resources/cr_components/customize_themes/customize_themes.js';
import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js'; import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
import 'chrome://resources/polymer/v3_0/paper-styles/shadow.js'; import 'chrome://resources/polymer/v3_0/paper-styles/shadow.js';
import '../settings_shared_css.m.js'; import '../settings_shared_css.m.js';
...@@ -76,6 +77,15 @@ Polymer({ ...@@ -76,6 +77,15 @@ Polymer({
*/ */
isProfileShortcutSettingVisible_: Boolean, isProfileShortcutSettingVisible_: Boolean,
/**
* True if the customize themes feature is enabled.
* @private
*/
isCustomizeThemesVisible_: {
type: Boolean,
value: () => loadTimeData.getBoolean('profileThemeSelectorEnabled')
},
/** /**
* TODO(dpapad): Move this back to the HTML file when the Polymer2 version * TODO(dpapad): Move this back to the HTML file when the Polymer2 version
* of the code is deleted. Because of "\" being a special character in a JS * of the code is deleted. Because of "\" being a special character in a JS
......
...@@ -42,6 +42,11 @@ const base::Feature kNewTabstripAnimation{"NewTabstripAnimation", ...@@ -42,6 +42,11 @@ const base::Feature kNewTabstripAnimation{"NewTabstripAnimation",
const base::Feature kPermissionChip{"PermissionChip", const base::Feature kPermissionChip{"PermissionChip",
base::FEATURE_DISABLED_BY_DEFAULT}; base::FEATURE_DISABLED_BY_DEFAULT};
// Enables the theme selector in the manage profile settings.
// https://crbug.com/1129186
const base::Feature kProfileThemeSelectorInSettings{
"ProfileThemeSelectorInSettings", base::FEATURE_DISABLED_BY_DEFAULT};
// Enables a more prominent active tab title in dark mode to aid with // Enables a more prominent active tab title in dark mode to aid with
// accessibility. // accessibility.
const base::Feature kProminentDarkModeActiveTabTitle{ const base::Feature kProminentDarkModeActiveTabTitle{
......
...@@ -34,6 +34,8 @@ extern const base::Feature kNewTabstripAnimation; ...@@ -34,6 +34,8 @@ extern const base::Feature kNewTabstripAnimation;
extern const base::Feature kPermissionChip; extern const base::Feature kPermissionChip;
extern const base::Feature kProfileThemeSelectorInSettings;
extern const base::Feature kProminentDarkModeActiveTabTitle; extern const base::Feature kProminentDarkModeActiveTabTitle;
extern const base::Feature kReadLater; extern const base::Feature kReadLater;
......
...@@ -1189,6 +1189,12 @@ void AddPeopleStrings(content::WebUIDataSource* html_source, Profile* profile) { ...@@ -1189,6 +1189,12 @@ void AddPeopleStrings(content::WebUIDataSource* html_source, Profile* profile) {
IDS_SETTINGS_SYNC_DISCONNECT_DELETE_PROFILE_WARNING_WITH_COUNTS_PLURAL}, IDS_SETTINGS_SYNC_DISCONNECT_DELETE_PROFILE_WARNING_WITH_COUNTS_PLURAL},
{"deleteProfileWarningWithoutCounts", {"deleteProfileWarningWithoutCounts",
IDS_SETTINGS_SYNC_DISCONNECT_DELETE_PROFILE_WARNING_WITHOUT_COUNTS}, IDS_SETTINGS_SYNC_DISCONNECT_DELETE_PROFILE_WARNING_WITHOUT_COUNTS},
// Color picker strings:
{"colorPickerLabel", IDS_NTP_CUSTOMIZE_COLOR_PICKER_LABEL},
{"defaultThemeLabel", IDS_NTP_CUSTOMIZE_DEFAULT_LABEL},
{"thirdPartyThemeDescription", IDS_NTP_CUSTOMIZE_3PT_THEME_DESC},
{"uninstallThirdPartyThemeButton", IDS_NTP_CUSTOMIZE_3PT_THEME_UNINSTALL},
}; };
AddLocalizedStringsBulk(html_source, kLocalizedStrings); AddLocalizedStringsBulk(html_source, kLocalizedStrings);
......
...@@ -118,6 +118,7 @@ ...@@ -118,6 +118,7 @@
#include "ui/base/ui_base_features.h" #include "ui/base/ui_base_features.h"
#else // !defined(OS_CHROMEOS) #else // !defined(OS_CHROMEOS)
#include "chrome/browser/signin/account_consistency_mode_manager.h" #include "chrome/browser/signin/account_consistency_mode_manager.h"
#include "chrome/browser/ui/webui/customize_themes/chrome_customize_themes_handler.h"
#include "chrome/browser/ui/webui/settings/settings_default_browser_handler.h" #include "chrome/browser/ui/webui/settings/settings_default_browser_handler.h"
#include "chrome/browser/ui/webui/settings/settings_manage_profile_handler.h" #include "chrome/browser/ui/webui/settings/settings_manage_profile_handler.h"
#include "chrome/browser/ui/webui/settings/system_handler.h" #include "chrome/browser/ui/webui/settings/system_handler.h"
...@@ -155,7 +156,13 @@ web_app::AppRegistrar& GetRegistrarForProfile(Profile* profile) { ...@@ -155,7 +156,13 @@ web_app::AppRegistrar& GetRegistrarForProfile(Profile* profile) {
} }
SettingsUI::SettingsUI(content::WebUI* web_ui) SettingsUI::SettingsUI(content::WebUI* web_ui)
: content::WebUIController(web_ui), :
#if !defined(OS_CHROMEOS)
ui::MojoWebUIController(web_ui, /*enable_chrome_send=*/true),
customize_themes_factory_receiver_(this),
#else // !defined(OS_CHROMEOS)
content::WebUIController(web_ui),
#endif
webui_load_timer_(web_ui->GetWebContents(), webui_load_timer_(web_ui->GetWebContents(),
"Settings.LoadDocumentTime.MD", "Settings.LoadDocumentTime.MD",
"Settings.LoadCompletedTime.MD") { "Settings.LoadCompletedTime.MD") {
...@@ -311,7 +318,11 @@ SettingsUI::SettingsUI(content::WebUI* web_ui) ...@@ -311,7 +318,11 @@ SettingsUI::SettingsUI(content::WebUI* web_ui)
// This is the browser settings page. // This is the browser settings page.
html_source->AddBoolean("isOSSettings", false); html_source->AddBoolean("isOSSettings", false);
#endif #else // defined(OS_CHROMEOS)
html_source->AddBoolean(
"profileThemeSelectorEnabled",
base::FeatureList::IsEnabled(features::kProfileThemeSelectorInSettings));
#endif // !defined(OS_CHROMEOS)
AddSettingsPageUIHandler(std::make_unique<AboutHandler>(profile)); AddSettingsPageUIHandler(std::make_unique<AboutHandler>(profile));
AddSettingsPageUIHandler(std::make_unique<ResetSettingsHandler>(profile)); AddSettingsPageUIHandler(std::make_unique<ResetSettingsHandler>(profile));
...@@ -430,7 +441,16 @@ void SettingsUI::InitBrowserSettingsWebUIHandlers() { ...@@ -430,7 +441,16 @@ void SettingsUI::InitBrowserSettingsWebUIHandlers() {
web_ui()->AddMessageHandler( web_ui()->AddMessageHandler(
std::make_unique<chromeos::settings::AndroidAppsHandler>(profile)); std::make_unique<chromeos::settings::AndroidAppsHandler>(profile));
} }
#endif // defined(OS_CHROMEOS) #else // defined(OS_CHROMEOS)
void SettingsUI::BindInterface(
mojo::PendingReceiver<
customize_themes::mojom::CustomizeThemesHandlerFactory>
pending_receiver) {
if (customize_themes_factory_receiver_.is_bound())
customize_themes_factory_receiver_.reset();
customize_themes_factory_receiver_.Bind(std::move(pending_receiver));
}
#endif // !defined(OS_CHROMEOS)
void SettingsUI::AddSettingsPageUIHandler( void SettingsUI::AddSettingsPageUIHandler(
std::unique_ptr<content::WebUIMessageHandler> handler) { std::unique_ptr<content::WebUIMessageHandler> handler) {
...@@ -448,4 +468,18 @@ void SettingsUI::TryShowHatsSurveyWithTimeout() { ...@@ -448,4 +468,18 @@ void SettingsUI::TryShowHatsSurveyWithTimeout() {
} }
} }
#if !defined(OS_CHROMEOS)
void SettingsUI::CreateCustomizeThemesHandler(
mojo::PendingRemote<customize_themes::mojom::CustomizeThemesClient>
pending_client,
mojo::PendingReceiver<customize_themes::mojom::CustomizeThemesHandler>
pending_handler) {
customize_themes_handler_ = std::make_unique<ChromeCustomizeThemesHandler>(
std::move(pending_client), std::move(pending_handler),
web_ui()->GetWebContents(), Profile::FromWebUI(web_ui()));
}
#endif // !defined(OS_CHROMEOS)
WEB_UI_CONTROLLER_TYPE_IMPL(SettingsUI)
} // namespace settings } // namespace settings
...@@ -6,10 +6,19 @@ ...@@ -6,10 +6,19 @@
#define CHROME_BROWSER_UI_WEBUI_SETTINGS_SETTINGS_UI_H_ #define CHROME_BROWSER_UI_WEBUI_SETTINGS_SETTINGS_UI_H_
#include "base/macros.h" #include "base/macros.h"
#include "build/build_config.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/webui_load_timer.h" #include "chrome/browser/ui/webui/webui_load_timer.h"
#include "content/public/browser/web_ui_controller.h" #include "content/public/browser/web_ui_controller.h"
#if !defined(OS_CHROMEOS)
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "ui/webui/mojo_web_ui_controller.h"
#include "ui/webui/resources/cr_components/customize_themes/customize_themes.mojom.h"
#endif // !defined(OS_CHROMEOS)
namespace content { namespace content {
class WebUIMessageHandler; class WebUIMessageHandler;
} // namespace content } // namespace content
...@@ -18,10 +27,23 @@ namespace user_prefs { ...@@ -18,10 +27,23 @@ namespace user_prefs {
class PrefRegistrySyncable; class PrefRegistrySyncable;
} }
#if !defined(OS_CHROMEOS)
class ChromeCustomizeThemesHandler;
#endif // !defined(OS_CHROMEOS)
namespace settings { namespace settings {
// The WebUI handler for chrome://settings. // The WebUI handler for chrome://settings.
class SettingsUI : public content::WebUIController { class SettingsUI :
#if !defined(OS_CHROMEOS)
// chrome://settings/manageProfile which only exists on !OS_CHROMEOS
// requires mojo bindings.
public ui::MojoWebUIController,
public customize_themes::mojom::CustomizeThemesHandlerFactory
#else // !defined(OS_CHROMEOS)
public content::WebUIController
#endif // defined(OS_CHROMEOS)
{
public: public:
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
...@@ -32,7 +54,14 @@ class SettingsUI : public content::WebUIController { ...@@ -32,7 +54,14 @@ class SettingsUI : public content::WebUIController {
// Initializes the WebUI message handlers for CrOS-specific settings that are // Initializes the WebUI message handlers for CrOS-specific settings that are
// still shown in the browser settings UI. // still shown in the browser settings UI.
void InitBrowserSettingsWebUIHandlers(); void InitBrowserSettingsWebUIHandlers();
#endif // defined(OS_CHROMEOS) #else // defined(OS_CHROMEOS)
// Instantiates the implementor of the
// customize_themes::mojom::CustomizeThemesHandlerFactory mojo interface
// passing the pending receiver that will be internally bound.
void BindInterface(mojo::PendingReceiver<
customize_themes::mojom::CustomizeThemesHandlerFactory>
pending_receiver);
#endif // !defined(OS_CHROMEOS)
private: private:
void AddSettingsPageUIHandler( void AddSettingsPageUIHandler(
...@@ -41,8 +70,23 @@ class SettingsUI : public content::WebUIController { ...@@ -41,8 +70,23 @@ class SettingsUI : public content::WebUIController {
// Makes a request to show a HaTS survey. // Makes a request to show a HaTS survey.
void TryShowHatsSurveyWithTimeout(); void TryShowHatsSurveyWithTimeout();
#if !defined(OS_CHROMEOS)
// customize_themes::mojom::CustomizeThemesHandlerFactory:
void CreateCustomizeThemesHandler(
mojo::PendingRemote<customize_themes::mojom::CustomizeThemesClient>
pending_client,
mojo::PendingReceiver<customize_themes::mojom::CustomizeThemesHandler>
pending_handler) override;
std::unique_ptr<ChromeCustomizeThemesHandler> customize_themes_handler_;
mojo::Receiver<customize_themes::mojom::CustomizeThemesHandlerFactory>
customize_themes_factory_receiver_;
#endif // !defined(OS_CHROMEOS)
WebuiLoadTimer webui_load_timer_; WebuiLoadTimer webui_load_timer_;
WEB_UI_CONTROLLER_TYPE_DECL();
DISALLOW_COPY_AND_ASSIGN(SettingsUI); DISALLOW_COPY_AND_ASSIGN(SettingsUI);
}; };
......
...@@ -81,11 +81,7 @@ suite('ManageProfileTests', function() { ...@@ -81,11 +81,7 @@ suite('ManageProfileTests', function() {
browserProxy = new TestManageProfileBrowserProxy(); browserProxy = new TestManageProfileBrowserProxy();
ManageProfileBrowserProxyImpl.instance_ = browserProxy; ManageProfileBrowserProxyImpl.instance_ = browserProxy;
PolymerTest.clearBody(); PolymerTest.clearBody();
manageProfile = document.createElement('settings-manage-profile'); manageProfile = createManageProfileElement();
manageProfile.profileIconUrl = 'fake-icon-1.png';
manageProfile.profileName = 'Initial Fake Name';
manageProfile.syncStatus = {supervisedUser: false, childUser: false};
document.body.appendChild(manageProfile);
Router.getInstance().navigateTo(routes.MANAGE_PROFILE); Router.getInstance().navigateTo(routes.MANAGE_PROFILE);
}); });
...@@ -93,6 +89,16 @@ suite('ManageProfileTests', function() { ...@@ -93,6 +89,16 @@ suite('ManageProfileTests', function() {
manageProfile.remove(); manageProfile.remove();
}); });
function createManageProfileElement() {
const manageProfileElement =
document.createElement('settings-manage-profile');
manageProfileElement.profileIconUrl = 'fake-icon-1.png';
manageProfileElement.profileName = 'Initial Fake Name';
manageProfileElement.syncStatus = {supervisedUser: false, childUser: false};
document.body.appendChild(manageProfileElement);
return manageProfileElement;
}
// Tests that the manage profile subpage // Tests that the manage profile subpage
// - gets and receives all the available icons // - gets and receives all the available icons
// - can select a new icon // - can select a new icon
...@@ -101,8 +107,9 @@ suite('ManageProfileTests', function() { ...@@ -101,8 +107,9 @@ suite('ManageProfileTests', function() {
return browserProxy.whenCalled('getAvailableIcons') return browserProxy.whenCalled('getAvailableIcons')
.then(function() { .then(function() {
flush(); flush();
items = manageProfile.$.selector.$['avatar-grid'].querySelectorAll( items =
'.avatar'); manageProfile.$.avatarSelector.$['avatar-grid'].querySelectorAll(
'.avatar');
assertFalse(!!manageProfile.profileAvatar); assertFalse(!!manageProfile.profileAvatar);
assertEquals(3, items.length); assertEquals(3, items.length);
...@@ -167,6 +174,27 @@ suite('ManageProfileTests', function() { ...@@ -167,6 +174,27 @@ suite('ManageProfileTests', function() {
const hasShortcutToggle = manageProfile.$$('#hasShortcutToggle'); const hasShortcutToggle = manageProfile.$$('#hasShortcutToggle');
assertFalse(!!hasShortcutToggle); assertFalse(!!hasShortcutToggle);
}); });
// Tests that the theme selector is hidden if profile colors feature is
// disabled.
test('ProfileThemeSelectorHidden', function() {
assertFalse(!!manageProfile.$$('#themeSelector'));
});
// Tests that the theme selector is visible if profile colors feature is
// enabled.
test('ProfileThemeSelectorVisible', function() {
// Recreate a manage profile element with overridden loadTimeData.
PolymerTest.clearBody();
loadTimeData.overrideValues({
profileThemeSelectorEnabled: true,
});
manageProfile = createManageProfileElement();
flush();
assertTrue(!!manageProfile.$$('#themeSelector'));
});
}); });
suite('ManageProfileTestsProfileShortcutsEnabled', function() { suite('ManageProfileTestsProfileShortcutsEnabled', function() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment