Commit da0e2f8b authored by Richard Knoll's avatar Richard Knoll Committed by Commit Bot

Enable AutoColorReadability for notification text and icons

This enables automatic color contrast checks in these notification views
so that we can use any theme color in a follow-up CL:
- NotificationControlButtonsView
- NotificationHeaderView
- NotificationViewMD

This will make sure that the text and icons are at least readable even
if the colors don't combine well with each other. Note that this will
still render the main notification content text too bright as it already
expect the background to be set to the native theme color.

Bug: 1113313
Change-Id: Ic1bc0816eeb6242b93a1195c2c03aff81726f83c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2398507
Commit-Queue: Richard Knoll <knollr@chromium.org>
Reviewed-by: default avatarPeter Beverloo <peter@chromium.org>
Cr-Commit-Position: refs/heads/master@{#806974}
parent 14cf28d6
......@@ -191,6 +191,8 @@ class MESSAGE_CENTER_EXPORT MessageView
views::FocusRing* focus_ring() { return focus_ring_; }
int bottom_radius() const { return bottom_radius_; }
private:
friend class test::MessagePopupCollectionTest;
......
......@@ -6,8 +6,13 @@
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_unittest_util.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/message_center/public/cpp/notification.h"
#include "ui/message_center/vector_icons.h"
#include "ui/message_center/views/message_view.h"
namespace message_center {
......@@ -50,6 +55,23 @@ class NotificationControlButtonsTest : public testing::Test {
return message_view_->GetControlButtonsView();
}
bool MatchesIcon(PaddedButton* button,
const gfx::VectorIcon& icon,
SkColor color) {
SkBitmap expected = *gfx::CreateVectorIcon(icon, color).bitmap();
SkBitmap actual = *button->GetImage(views::Button::STATE_NORMAL).bitmap();
return gfx::test::AreBitmapsEqual(expected, actual);
}
void ExpectIconColor(SkColor color) {
EXPECT_TRUE(MatchesIcon(buttons_view()->close_button(),
kNotificationCloseButtonIcon, color));
EXPECT_TRUE(MatchesIcon(buttons_view()->settings_button(),
kNotificationSettingsButtonIcon, color));
EXPECT_TRUE(MatchesIcon(buttons_view()->snooze_button(),
kNotificationSnoozeButtonIcon, color));
}
private:
std::unique_ptr<TestMessageView> message_view_;
......@@ -78,4 +100,37 @@ TEST_F(NotificationControlButtonsTest, TestShowAndHideButtons) {
EXPECT_EQ(nullptr, buttons_view()->snooze_button());
}
TEST_F(NotificationControlButtonsTest, IconColor_NoContrastEnforcement) {
buttons_view()->ShowCloseButton(true);
buttons_view()->ShowSettingsButton(true);
buttons_view()->ShowSnoozeButton(true);
// Default icon color.
ExpectIconColor(gfx::kChromeIconGrey);
// Without setting a background color we won't enforce contrast ratios.
buttons_view()->SetButtonIconColors(SK_ColorWHITE);
ExpectIconColor(SK_ColorWHITE);
buttons_view()->SetButtonIconColors(SK_ColorBLACK);
ExpectIconColor(SK_ColorBLACK);
}
TEST_F(NotificationControlButtonsTest, IconColor_ContrastEnforcement) {
buttons_view()->ShowCloseButton(true);
buttons_view()->ShowSettingsButton(true);
buttons_view()->ShowSnoozeButton(true);
// A bright background should enforce dark enough icons.
buttons_view()->SetBackgroundColor(SK_ColorWHITE);
buttons_view()->SetButtonIconColors(SK_ColorWHITE);
ExpectIconColor(
color_utils::BlendForMinContrast(SK_ColorWHITE, SK_ColorWHITE).color);
// A dark background should enforce bright enough icons.
buttons_view()->SetBackgroundColor(SK_ColorBLACK);
buttons_view()->SetButtonIconColors(SK_ColorBLACK);
ExpectIconColor(
color_utils::BlendForMinContrast(SK_ColorBLACK, SK_ColorBLACK).color);
}
} // namespace message_center
......@@ -10,6 +10,7 @@
#include "ui/compositor/layer.h"
#include "ui/events/event.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/message_center/public/cpp/message_center_constants.h"
#include "ui/message_center/vector_icons.h"
......@@ -44,9 +45,9 @@ NotificationControlButtonsView::~NotificationControlButtonsView() = default;
void NotificationControlButtonsView::ShowCloseButton(bool show) {
if (show && !close_button_) {
close_button_ = AddChildView(std::make_unique<PaddedButton>(this));
close_button_->SetImage(
views::Button::STATE_NORMAL,
gfx::CreateVectorIcon(kNotificationCloseButtonIcon, icon_color_));
close_button_->SetImage(views::Button::STATE_NORMAL,
gfx::CreateVectorIcon(kNotificationCloseButtonIcon,
DetermineButtonIconColor()));
close_button_->SetAccessibleName(l10n_util::GetStringUTF16(
IDS_MESSAGE_CENTER_CLOSE_NOTIFICATION_BUTTON_ACCESSIBLE_NAME));
close_button_->SetTooltipText(l10n_util::GetStringUTF16(
......@@ -69,7 +70,8 @@ void NotificationControlButtonsView::ShowSettingsButton(bool show) {
AddChildViewAt(std::make_unique<PaddedButton>(this), position);
settings_button_->SetImage(
views::Button::STATE_NORMAL,
gfx::CreateVectorIcon(kNotificationSettingsButtonIcon, icon_color_));
gfx::CreateVectorIcon(kNotificationSettingsButtonIcon,
DetermineButtonIconColor()));
settings_button_->SetAccessibleName(l10n_util::GetStringUTF16(
IDS_MESSAGE_NOTIFICATION_SETTINGS_BUTTON_ACCESSIBLE_NAME));
settings_button_->SetTooltipText(l10n_util::GetStringUTF16(
......@@ -90,7 +92,8 @@ void NotificationControlButtonsView::ShowSnoozeButton(bool show) {
snooze_button_ = AddChildViewAt(std::make_unique<PaddedButton>(this), 0);
snooze_button_->SetImage(
views::Button::STATE_NORMAL,
gfx::CreateVectorIcon(kNotificationSnoozeButtonIcon, icon_color_));
gfx::CreateVectorIcon(kNotificationSnoozeButtonIcon,
DetermineButtonIconColor()));
snooze_button_->SetAccessibleName(l10n_util::GetStringUTF16(
IDS_MESSAGE_CENTER_NOTIFICATION_SNOOZE_BUTTON_TOOLTIP));
snooze_button_->SetTooltipText(l10n_util::GetStringUTF16(
......@@ -123,22 +126,14 @@ void NotificationControlButtonsView::SetButtonIconColors(SkColor color) {
if (color == icon_color_)
return;
icon_color_ = color;
UpdateButtonIconColors();
}
if (close_button_) {
close_button_->SetImage(
views::Button::STATE_NORMAL,
gfx::CreateVectorIcon(kNotificationCloseButtonIcon, icon_color_));
}
if (settings_button_) {
settings_button_->SetImage(
views::Button::STATE_NORMAL,
gfx::CreateVectorIcon(kNotificationSettingsButtonIcon, icon_color_));
}
if (snooze_button_) {
snooze_button_->SetImage(
views::Button::STATE_NORMAL,
gfx::CreateVectorIcon(kNotificationSnoozeButtonIcon, icon_color_));
}
void NotificationControlButtonsView::SetBackgroundColor(SkColor color) {
if (color == background_color_)
return;
background_color_ = color;
UpdateButtonIconColors();
}
const char* NotificationControlButtonsView::GetClassName() const {
......@@ -164,4 +159,30 @@ void NotificationControlButtonsView::ButtonPressed(views::Button* sender,
}
}
void NotificationControlButtonsView::UpdateButtonIconColors() {
SkColor icon_color = DetermineButtonIconColor();
if (close_button_) {
close_button_->SetImage(
views::Button::STATE_NORMAL,
gfx::CreateVectorIcon(kNotificationCloseButtonIcon, icon_color));
}
if (settings_button_) {
settings_button_->SetImage(
views::Button::STATE_NORMAL,
gfx::CreateVectorIcon(kNotificationSettingsButtonIcon, icon_color));
}
if (snooze_button_) {
snooze_button_->SetImage(
views::Button::STATE_NORMAL,
gfx::CreateVectorIcon(kNotificationSnoozeButtonIcon, icon_color));
}
}
SkColor NotificationControlButtonsView::DetermineButtonIconColor() const {
if (SkColorGetA(background_color_) != SK_AlphaOPAQUE)
return icon_color_;
return color_utils::BlendForMinContrast(icon_color_, background_color_).color;
}
} // namespace message_center
......@@ -52,10 +52,13 @@ class MESSAGE_CENTER_EXPORT NotificationControlButtonsView
// Sets the icon color for the close, settings, and snooze buttons.
void SetButtonIconColors(SkColor color);
// Sets the background color to ensure proper readability.
void SetBackgroundColor(SkColor color);
// Methods for retrieving the control buttons directly.
views::Button* close_button() { return close_button_; }
views::Button* settings_button() { return settings_button_; }
views::Button* snooze_button() { return snooze_button_; }
PaddedButton* close_button() { return close_button_; }
PaddedButton* settings_button() { return settings_button_; }
PaddedButton* snooze_button() { return snooze_button_; }
// views::View
const char* GetClassName() const override;
......@@ -67,6 +70,13 @@ class MESSAGE_CENTER_EXPORT NotificationControlButtonsView
void ButtonPressed(views::Button* sender, const ui::Event& event) override;
private:
// Updates the button icon colors to the value of DetermineButtonIconColor().
void UpdateButtonIconColors();
// Determines the button icon color to use given |icon_color_| and
// |background_color_| ensuring readability.
SkColor DetermineButtonIconColor() const;
MessageView* message_view_;
PaddedButton* close_button_ = nullptr;
......@@ -75,6 +85,8 @@ class MESSAGE_CENTER_EXPORT NotificationControlButtonsView
// The color used for the close, settings, and snooze icons.
SkColor icon_color_;
// The background color for readability of the icons.
SkColor background_color_ = SK_ColorTRANSPARENT;
DISALLOW_COPY_AND_ASSIGN(NotificationControlButtonsView);
};
......
......@@ -45,7 +45,7 @@ constexpr int kInnerHeaderHeight = kHeaderHeight - kHeaderOuterPadding.height();
// Default paddings of the views of texts. Adjusted on Windows.
// Top: 9px = 11px (from the mock) - 2px (outer padding).
// Buttom: 6px from the mock.
// Bottom: 6px from the mock.
constexpr gfx::Insets kTextViewPaddingDefault(9, 0, 6, 0);
// Paddings of the app icon (small image).
......@@ -70,8 +70,8 @@ constexpr int kHeaderTextFontSize = 12;
// Minimum spacing before the control buttons.
constexpr int kControlButtonSpacing = 16;
// ExpandButtton forwards all mouse and key events to NotificationHeaderView,
// but takes tab focus for accessibility purpose.
// ExpandButton forwards all mouse and key events to NotificationHeaderView, but
// takes tab focus for accessibility purpose.
class ExpandButton : public views::ImageView {
public:
ExpandButton();
......@@ -362,6 +362,7 @@ void NotificationHeaderView::SetBackgroundColor(SkColor color) {
summary_text_view_->SetBackgroundColor(color);
timestamp_divider_->SetBackgroundColor(color);
timestamp_view_->SetBackgroundColor(color);
UpdateColors();
}
void NotificationHeaderView::SetSubpixelRenderingEnabled(bool enabled) {
......@@ -404,13 +405,16 @@ void NotificationHeaderView::UpdateColors() {
summary_text_view_->SetEnabledColor(color);
summary_text_divider_->SetEnabledColor(color);
// Get actual color based on readablility requirements.
SkColor actual_color = app_name_view_->GetEnabledColor();
expand_button_->SetImage(gfx::CreateVectorIcon(
is_expanded_ ? kNotificationExpandLessIcon : kNotificationExpandMoreIcon,
kExpandIconSize, color));
kExpandIconSize, actual_color));
if (using_default_app_icon_) {
app_icon_view_->SetImage(
gfx::CreateVectorIcon(kProductIcon, kSmallImageSizeMD, color));
gfx::CreateVectorIcon(kProductIcon, kSmallImageSizeMD, actual_color));
}
}
......
......@@ -9,6 +9,12 @@
#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_unittest_util.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/message_center/vector_icons.h"
#include "ui/strings/grit/ui_strings.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
......@@ -46,6 +52,24 @@ class NotificationHeaderViewTest : public views::ViewsTestBase {
ViewsTestBase::TearDown();
}
bool MatchesAppIconColor(SkColor color) {
SkBitmap expected =
*gfx::CreateVectorIcon(kProductIcon, kSmallImageSizeMD, color).bitmap();
SkBitmap actual =
*notification_header_view_->app_icon_for_testing().bitmap();
return gfx::test::AreBitmapsEqual(expected, actual);
}
bool MatchesExpandIconColor(SkColor color) {
constexpr int kExpandIconSize = 8;
SkBitmap expected = *gfx::CreateVectorIcon(kNotificationExpandMoreIcon,
kExpandIconSize, color)
.bitmap();
SkBitmap actual =
*notification_header_view_->expand_button()->GetImage().bitmap();
return gfx::test::AreBitmapsEqual(expected, actual);
}
protected:
NotificationHeaderView* notification_header_view_ = nullptr;
......@@ -156,4 +180,29 @@ TEST_F(NotificationHeaderViewTest, TimestampHiddenWithProgress) {
EXPECT_TRUE(timestamp_view->GetVisible());
}
TEST_F(NotificationHeaderViewTest, ColorContrastEnforcement) {
notification_header_view_->SetSummaryText(base::ASCIIToUTF16("summary"));
auto* summary_text = notification_header_view_->summary_text_for_testing();
notification_header_view_->ClearAppIcon();
notification_header_view_->SetExpandButtonEnabled(true);
notification_header_view_->SetExpanded(false);
// A bright background should enforce dark enough icons.
notification_header_view_->SetBackgroundColor(SK_ColorWHITE);
notification_header_view_->SetAccentColor(SK_ColorWHITE);
SkColor expected_color =
color_utils::BlendForMinContrast(SK_ColorWHITE, SK_ColorWHITE).color;
EXPECT_EQ(expected_color, summary_text->GetEnabledColor());
EXPECT_TRUE(MatchesAppIconColor(expected_color));
EXPECT_TRUE(MatchesExpandIconColor(expected_color));
// A dark background should enforce bright enough icons.
notification_header_view_->SetBackgroundColor(SK_ColorBLACK);
notification_header_view_->SetAccentColor(SK_ColorBLACK);
expected_color =
color_utils::BlendForMinContrast(SK_ColorBLACK, SK_ColorBLACK).color;
EXPECT_EQ(expected_color, summary_text->GetEnabledColor());
EXPECT_TRUE(MatchesAppIconColor(expected_color));
EXPECT_TRUE(MatchesExpandIconColor(expected_color));
}
} // namespace message_center
......@@ -20,6 +20,7 @@
#include "ui/events/gesture_detection/gesture_provider_config_helper.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/image/image_skia_operations.h"
......@@ -116,7 +117,7 @@ constexpr int kTextFontSizeDelta = 1;
// In progress notification, if both the title and the message are long, the
// message would be prioritized and the title would be elided.
// However, it is not perferable that we completely omit the title, so
// However, it is not preferable that we completely omit the title, so
// the ratio of the message width is limited to this value.
constexpr double kProgressNotificationMessageRatio = 0.7;
......@@ -166,7 +167,6 @@ std::unique_ptr<views::View> CreateItemView(const NotificationItem& item) {
title->SetFontList(font_list);
title->SetCollapseWhenHidden(true);
title->SetHorizontalAlignment(gfx::ALIGN_LEFT);
title->SetAutoColorReadabilityEnabled(false);
view->AddChildView(title);
views::Label* message = view->AddChildView(std::make_unique<views::Label>(
......@@ -177,7 +177,6 @@ std::unique_ptr<views::View> CreateItemView(const NotificationItem& item) {
message->SetFontList(font_list);
message->SetCollapseWhenHidden(true);
message->SetHorizontalAlignment(gfx::ALIGN_LEFT);
message->SetAutoColorReadabilityEnabled(false);
return view;
}
......@@ -342,6 +341,21 @@ void NotificationMdTextButton::UpdateBackgroundColor() {
// Overridden as no-op so we don't draw any background or border.
}
void NotificationMdTextButton::OnThemeChanged() {
views::MdTextButton::OnThemeChanged();
SetEnabledTextColors(text_color_);
label()->SetAutoColorReadabilityEnabled(true);
label()->SetBackgroundColor(GetNativeTheme()->GetSystemColor(
ui::NativeTheme::kColorId_NotificationActionsRowBackground));
}
void NotificationMdTextButton::OverrideTextColor(
base::Optional<SkColor> text_color) {
text_color_ = std::move(text_color);
SetEnabledTextColors(text_color_);
label()->SetAutoColorReadabilityEnabled(true);
}
BEGIN_METADATA(NotificationMdTextButton, views::MdTextButton)
END_METADATA
......@@ -482,6 +496,7 @@ class InlineSettingsRadioButton : public views::RadioButton {
void OnThemeChanged() override {
RadioButton::OnThemeChanged();
SetEnabledTextColors(GetTextColor());
label()->SetAutoColorReadabilityEnabled(true);
label()->SetBackgroundColor(GetNativeTheme()->GetSystemColor(
ui::NativeTheme::kColorId_NotificationInlineSettingsBackground));
}
......@@ -689,7 +704,7 @@ void NotificationViewMD::Layout() {
if (actions_row_->GetVisible()) {
constexpr SkScalar kCornerRadius = SkIntToScalar(kNotificationCornerRadius);
// Use vertically larger clip path, so that actions row's top coners will
// Use vertically larger clip path, so that actions row's top corners will
// not be rounded.
SkPath path;
gfx::Rect bounds = actions_row_->GetLocalBounds();
......@@ -1078,12 +1093,18 @@ void NotificationViewMD::CreateOrUpdateIconView(
void NotificationViewMD::CreateOrUpdateSmallIconView(
const Notification& notification) {
SkColor accent_color =
notification.accent_color().value_or(GetNativeTheme()->GetSystemColor(
ui::NativeTheme::kColorId_NotificationDefaultAccentColor));
SkColor icon_color =
color_utils::BlendForMinContrast(
accent_color, GetNotificationHeaderViewBackgroundColor())
.color;
// TODO(knollr): figure out if this has a performance impact and
// cache images if so. (crbug.com/768748)
gfx::Image masked_small_icon = notification.GenerateMaskedSmallIcon(
kSmallImageSizeMD,
notification.accent_color().value_or(GetNativeTheme()->GetSystemColor(
ui::NativeTheme::kColorId_NotificationDefaultAccentColor)));
gfx::Image masked_small_icon =
notification.GenerateMaskedSmallIcon(kSmallImageSizeMD, icon_color);
if (masked_small_icon.IsEmpty()) {
header_row_->ClearAppIcon();
......@@ -1162,7 +1183,7 @@ void NotificationViewMD::CreateOrUpdateActionButtonViews(
}
// Change action button color to the accent color.
action_buttons_[i]->SetEnabledTextColors(notification.accent_color());
action_buttons_[i]->OverrideTextColor(notification.accent_color());
}
// Inherit mouse hover state when action button views reset.
......@@ -1364,6 +1385,7 @@ void NotificationViewMD::ToggleInlineSettings(const ui::Event& event) {
else
RemoveBackgroundAnimation();
UpdateHeaderViewBackgroundColor();
Layout();
SchedulePaint();
......@@ -1373,13 +1395,36 @@ void NotificationViewMD::ToggleInlineSettings(const ui::Event& event) {
MessageCenter::Get()->DisableNotification(notification_id());
}
void NotificationViewMD::UpdateCornerRadius(int top_radius, int bottom_radius) {
MessageView::UpdateCornerRadius(top_radius, bottom_radius);
void NotificationViewMD::UpdateHeaderViewBackgroundColor() {
SkColor header_background_color = GetNotificationHeaderViewBackgroundColor();
header_row_->SetBackgroundColor(header_background_color);
control_buttons_view_->SetBackgroundColor(header_background_color);
auto* notification =
MessageCenter::Get()->FindVisibleNotificationById(notification_id());
if (notification)
CreateOrUpdateSmallIconView(*notification);
}
SkColor NotificationViewMD::GetNotificationHeaderViewBackgroundColor() const {
bool inline_settings_visible = settings_row_ && settings_row_->GetVisible();
return GetNativeTheme()->GetSystemColor(
inline_settings_visible
? ui::NativeTheme::kColorId_NotificationInlineSettingsBackground
: ui::NativeTheme::kColorId_NotificationDefaultBackground);
}
void NotificationViewMD::UpdateActionButtonsRowBackground() {
action_buttons_row_->SetBackground(views::CreateBackgroundFromPainter(
std::make_unique<NotificationBackgroundPainter>(
0, bottom_radius,
/*top_radius=*/0, bottom_radius(),
GetNativeTheme()->GetSystemColor(
ui::NativeTheme::kColorId_NotificationActionsRowBackground))));
}
void NotificationViewMD::UpdateCornerRadius(int top_radius, int bottom_radius) {
MessageView::UpdateCornerRadius(top_radius, bottom_radius);
UpdateActionButtonsRowBackground();
highlight_path_generator_->set_top_radius(top_radius);
highlight_path_generator_->set_bottom_radius(bottom_radius);
}
......@@ -1422,16 +1467,8 @@ void NotificationViewMD::OnSettingsButtonPressed(const ui::Event& event) {
void NotificationViewMD::OnThemeChanged() {
MessageView::OnThemeChanged();
bool inline_settings_visible = settings_row_ && !settings_row_->GetVisible();
header_row_->SetBackgroundColor(GetNativeTheme()->GetSystemColor(
inline_settings_visible
? ui::NativeTheme::kColorId_NotificationInlineSettingsBackground
: ui::NativeTheme::kColorId_NotificationDefaultBackground));
auto* notification =
MessageCenter::Get()->FindVisibleNotificationById(notification_id());
if (notification)
CreateOrUpdateSmallIconView(*notification);
UpdateHeaderViewBackgroundColor();
UpdateActionButtonsRowBackground();
}
void NotificationViewMD::Activate() {
......
......@@ -48,6 +48,7 @@ class MESSAGE_CENTER_EXPORT NotificationMdTextButton
// views::MdTextButton:
void UpdateBackgroundColor() override;
void OnThemeChanged() override;
const base::Optional<base::string16>& placeholder() const {
return placeholder_;
......@@ -59,8 +60,11 @@ class MESSAGE_CENTER_EXPORT NotificationMdTextButton
return label()->GetEnabledColor();
}
void OverrideTextColor(base::Optional<SkColor> text_color);
private:
base::Optional<base::string16> placeholder_;
base::Optional<SkColor> text_color_;
};
// CompactTitleMessageView shows notification title and message in a single
......@@ -266,6 +270,9 @@ class MESSAGE_CENTER_EXPORT NotificationViewMD
void ToggleExpanded();
void UpdateViewForExpandedState(bool expanded);
void ToggleInlineSettings(const ui::Event& event);
void UpdateHeaderViewBackgroundColor();
SkColor GetNotificationHeaderViewBackgroundColor() const;
void UpdateActionButtonsRowBackground();
// Returns the list of children which need to have their layers created or
// destroyed when the ink drop is visible.
......
......@@ -15,6 +15,8 @@
#include "ui/events/event_utils.h"
#include "ui/events/test/event_generator.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/image/image_unittest_util.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/message_center_observer.h"
......@@ -36,7 +38,7 @@
namespace message_center {
/* Test fixture ***************************************************************/
namespace {
// Used to fill bitmaps returned by CreateBitmap().
static const SkColor kBitmapColor = SK_ColorGREEN;
......@@ -105,6 +107,17 @@ class DummyEvent : public ui::Event {
~DummyEvent() override = default;
};
SkColor DeriveMinContrastColor(SkColor foreground, SkColor background) {
SkColor contrast_color =
color_utils::BlendForMinContrast(foreground, background).color;
float contrast_ratio =
color_utils::GetContrastRatio(background, contrast_color);
EXPECT_GE(contrast_ratio, color_utils::kMinimumReadableContrastRatio);
return contrast_color;
}
} // namespace
class NotificationViewMDTest : public views::InkDropObserver,
public views::ViewsTestBase,
public views::ViewObserver,
......@@ -978,8 +991,13 @@ TEST_F(NotificationViewMDTest, ExpandLongMessage) {
}
TEST_F(NotificationViewMDTest, TestAccentColor) {
constexpr SkColor kActionButtonTextColor = gfx::kGoogleBlue600;
constexpr SkColor kCustomAccentColor = gfx::kGoogleYellow900;
const SkColor kNotificationBackgroundColor = SK_ColorWHITE;
const SkColor kActionButtonBackgroundColor = SkColorSetRGB(0xEE, 0xEE, 0xEE);
const SkColor kActionButtonTextColor =
DeriveMinContrastColor(gfx::kGoogleBlue600, kActionButtonBackgroundColor);
const SkColor kDarkCustomAccentColor = SkColorSetRGB(0x0D, 0x65, 0x2D);
const SkColor kBrightCustomAccentColor = SkColorSetRGB(0x34, 0xA8, 0x53);
std::unique_ptr<Notification> notification = CreateSimpleNotification();
notification->set_buttons(CreateButtons(2));
......@@ -1018,19 +1036,40 @@ TEST_F(NotificationViewMDTest, TestAccentColor) {
// If custom accent color is set, the header and the buttons should have the
// same accent color.
notification->set_accent_color(kCustomAccentColor);
notification->set_accent_color(kDarkCustomAccentColor);
UpdateNotificationViews(*notification);
auto accent_color =
notification_view()->header_row_->accent_color_for_testing();
ASSERT_TRUE(accent_color.has_value());
EXPECT_EQ(kCustomAccentColor, accent_color.value());
EXPECT_EQ(kDarkCustomAccentColor, accent_color.value());
EXPECT_EQ(
kDarkCustomAccentColor,
notification_view()->action_buttons_[0]->enabled_color_for_testing());
EXPECT_EQ(
kDarkCustomAccentColor,
notification_view()->action_buttons_[1]->enabled_color_for_testing());
EXPECT_TRUE(app_icon_color_matches(kDarkCustomAccentColor));
// If the custom accent color is too bright, we expect it to be darkened so
// text and icons are still readable.
SkColor expected_color_title = DeriveMinContrastColor(
kBrightCustomAccentColor, kNotificationBackgroundColor);
// Action buttons have a darker background.
SkColor expected_color_actions = DeriveMinContrastColor(
kBrightCustomAccentColor, kActionButtonBackgroundColor);
notification->set_accent_color(kBrightCustomAccentColor);
UpdateNotificationViews(*notification);
accent_color = notification_view()->header_row_->accent_color_for_testing();
ASSERT_TRUE(accent_color.has_value());
EXPECT_EQ(kBrightCustomAccentColor, accent_color.value());
EXPECT_EQ(
kCustomAccentColor,
expected_color_actions,
notification_view()->action_buttons_[0]->enabled_color_for_testing());
EXPECT_EQ(
kCustomAccentColor,
expected_color_actions,
notification_view()->action_buttons_[1]->enabled_color_for_testing());
EXPECT_TRUE(app_icon_color_matches(kCustomAccentColor));
EXPECT_TRUE(app_icon_color_matches(expected_color_title));
}
TEST_F(NotificationViewMDTest, UseImageAsIcon) {
......
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