1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "components/media_message_center/media_notification_background_impl.h"
6 
7 #include <memory>
8 
9 #include "base/i18n/base_i18n_switches.h"
10 #include "base/test/icu_test_util.h"
11 #include "base/test/scoped_command_line.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "ui/gfx/color_analysis.h"
14 #include "ui/gfx/color_utils.h"
15 #include "ui/gfx/skia_util.h"
16 #include "ui/native_theme/test_native_theme.h"
17 #include "ui/views/test/test_views.h"
18 
19 namespace media_message_center {
20 
21 namespace {
22 
23 constexpr double kLightLuma = 0.9;
24 constexpr double kNormalLuma = 0.5;
25 constexpr double kDarkLuma = 0.2;
26 
27 constexpr double kMutedSaturation = 0.2;
28 constexpr double kVibrantSaturation = 0.8;
29 
30 constexpr int kDefaultForegroundArtworkHeight = 100;
31 
32 constexpr SkColor kDarkBackgroundColor = SK_ColorBLACK;
33 
34 class TestDarkTheme : public ui::TestNativeTheme {
35  public:
36   TestDarkTheme() = default;
37   ~TestDarkTheme() override = default;
38 
39   // ui::NativeTheme implementation.
GetSystemColor(ColorId color_id,ColorScheme color_scheme) const40   SkColor GetSystemColor(ColorId color_id,
41                          ColorScheme color_scheme) const override {
42     if (color_id == kColorId_BubbleBackground)
43       return kDarkBackgroundColor;
44     return ui::TestNativeTheme::GetSystemColor(color_id, color_scheme);
45   }
46 };
47 
GetColorFromSL(double s,double l)48 SkColor GetColorFromSL(double s, double l) {
49   return color_utils::HSLToSkColor({0.2, s, l}, SK_AlphaOPAQUE);
50 }
51 
CreateTestBackgroundImage(SkColor first_color,SkColor second_color,int second_height)52 gfx::ImageSkia CreateTestBackgroundImage(SkColor first_color,
53                                          SkColor second_color,
54                                          int second_height) {
55   constexpr SkColor kRightHandSideColor = SK_ColorMAGENTA;
56 
57   DCHECK_NE(kRightHandSideColor, first_color);
58   DCHECK_NE(kRightHandSideColor, second_color);
59 
60   SkBitmap bitmap;
61   bitmap.allocN32Pixels(100, 100);
62 
63   int first_height = bitmap.height() - second_height;
64   int right_width = bitmap.width() / 2;
65 
66   // Fill the right hand side of the image with a constant color. The color
67   // derivation algorithm does not look at the right hand side so we should
68   // never see |kRightHandSideColor|.
69   bitmap.erase(kRightHandSideColor,
70                {right_width, 0, bitmap.width(), bitmap.height()});
71 
72   // Fill the left hand side with |first_color|.
73   bitmap.erase(first_color, {0, 0, right_width, first_height});
74 
75   // Fill the left hand side with |second_color|.
76   bitmap.erase(second_color, {0, first_height, right_width, bitmap.height()});
77 
78   return gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
79 }
80 
CreateTestBackgroundImage(SkColor color)81 gfx::ImageSkia CreateTestBackgroundImage(SkColor color) {
82   return CreateTestBackgroundImage(color, SK_ColorTRANSPARENT, 0);
83 }
84 
85 }  // namespace
86 
87 class MediaNotificationBackgroundImplTest : public testing::Test {
88  public:
89   MediaNotificationBackgroundImplTest() = default;
90   ~MediaNotificationBackgroundImplTest() override = default;
91 
SetUp()92   void SetUp() override {
93     background_ =
94         std::make_unique<MediaNotificationBackgroundImpl>(10, 10, 0.1);
95 
96     EXPECT_FALSE(GetBackgroundColor().has_value());
97   }
98 
TearDown()99   void TearDown() override { background_.reset(); }
100 
background() const101   MediaNotificationBackgroundImpl* background() const {
102     return background_.get();
103   }
104 
GetBackgroundColor() const105   base::Optional<SkColor> GetBackgroundColor() const {
106     return background_->background_color_;
107   }
108 
GetForegroundColor() const109   base::Optional<SkColor> GetForegroundColor() const {
110     return background_->foreground_color_;
111   }
112 
GetBackgroundFaviconColorShadeFactor() const113   double GetBackgroundFaviconColorShadeFactor() const {
114     return MediaNotificationBackgroundImpl::kBackgroundFaviconColorShadeFactor;
115   }
116 
117  private:
118   std::unique_ptr<MediaNotificationBackgroundImpl> background_;
119 
120   DISALLOW_COPY_AND_ASSIGN(MediaNotificationBackgroundImplTest);
121 };
122 
123 // If we have no artwork then we should use the default background color.
TEST_F(MediaNotificationBackgroundImplTest,DeriveBackgroundColor_NoArtwork)124 TEST_F(MediaNotificationBackgroundImplTest, DeriveBackgroundColor_NoArtwork) {
125   background()->UpdateArtwork(gfx::ImageSkia());
126   EXPECT_FALSE(GetBackgroundColor().has_value());
127 }
128 
129 // If we have artwork with no popular color then we should use the default
130 // background color.
TEST_F(MediaNotificationBackgroundImplTest,DeriveBackgroundColor_NoPopularColor)131 TEST_F(MediaNotificationBackgroundImplTest,
132        DeriveBackgroundColor_NoPopularColor) {
133   background()->UpdateArtwork(CreateTestBackgroundImage(SK_ColorTRANSPARENT));
134   EXPECT_FALSE(GetBackgroundColor().has_value());
135 }
136 
137 // If the most popular color is not white or black then we should use that
138 // color.
TEST_F(MediaNotificationBackgroundImplTest,DeriveBackgroundColor_PopularNonWhiteBlackColor)139 TEST_F(MediaNotificationBackgroundImplTest,
140        DeriveBackgroundColor_PopularNonWhiteBlackColor) {
141   constexpr SkColor kTestColor = SK_ColorYELLOW;
142   background()->UpdateArtwork(CreateTestBackgroundImage(kTestColor));
143   EXPECT_EQ(kTestColor, GetBackgroundColor());
144 }
145 
TEST_F(MediaNotificationBackgroundImplTest,DeriveBackgroundColor_NoArtworkAfterHavingOne)146 TEST_F(MediaNotificationBackgroundImplTest,
147        DeriveBackgroundColor_NoArtworkAfterHavingOne) {
148   constexpr SkColor kTestColor = SK_ColorYELLOW;
149   background()->UpdateArtwork(CreateTestBackgroundImage(kTestColor));
150   EXPECT_EQ(kTestColor, GetBackgroundColor());
151 
152   background()->UpdateArtwork(gfx::ImageSkia());
153   EXPECT_FALSE(GetBackgroundColor().has_value());
154 }
155 
156 // Favicons should be used when available but have a shade applying to them.
TEST_F(MediaNotificationBackgroundImplTest,DeriveBackgroundColor_PopularNonWhiteBlackColorFavicon)157 TEST_F(MediaNotificationBackgroundImplTest,
158        DeriveBackgroundColor_PopularNonWhiteBlackColorFavicon) {
159   constexpr SkColor kTestColor = SK_ColorYELLOW;
160   background()->UpdateFavicon(CreateTestBackgroundImage(kTestColor));
161   const SkColor expected_color = SkColorSetRGB(
162       SkColorGetR(kTestColor) * GetBackgroundFaviconColorShadeFactor(),
163       SkColorGetG(kTestColor) * GetBackgroundFaviconColorShadeFactor(),
164       SkColorGetB(kTestColor) * GetBackgroundFaviconColorShadeFactor());
165   EXPECT_EQ(expected_color, GetBackgroundColor());
166 }
167 
TEST_F(MediaNotificationBackgroundImplTest,DeriveBackgroundColor_NoFaviconAfterHavingOne)168 TEST_F(MediaNotificationBackgroundImplTest,
169        DeriveBackgroundColor_NoFaviconAfterHavingOne) {
170   constexpr SkColor kTestColor = SK_ColorYELLOW;
171   background()->UpdateFavicon(CreateTestBackgroundImage(kTestColor));
172   const SkColor expected_color = SkColorSetRGB(
173       SkColorGetR(kTestColor) * GetBackgroundFaviconColorShadeFactor(),
174       SkColorGetG(kTestColor) * GetBackgroundFaviconColorShadeFactor(),
175       SkColorGetB(kTestColor) * GetBackgroundFaviconColorShadeFactor());
176   EXPECT_EQ(expected_color, GetBackgroundColor());
177 
178   background()->UpdateFavicon(gfx::ImageSkia());
179   EXPECT_FALSE(GetBackgroundColor().has_value());
180 }
181 
TEST_F(MediaNotificationBackgroundImplTest,DeriveBackgroundColor_FaviconSetThenArtwork)182 TEST_F(MediaNotificationBackgroundImplTest,
183        DeriveBackgroundColor_FaviconSetThenArtwork) {
184   constexpr SkColor kArtworkColor = SK_ColorYELLOW;
185   constexpr SkColor kFaviconColor = SK_ColorRED;
186 
187   background()->UpdateFavicon(CreateTestBackgroundImage(kFaviconColor));
188   background()->UpdateArtwork(CreateTestBackgroundImage(kArtworkColor));
189 
190   EXPECT_EQ(kArtworkColor, GetBackgroundColor());
191 }
192 
TEST_F(MediaNotificationBackgroundImplTest,DeriveBackgroundColor_ArtworkSetThenFavicon)193 TEST_F(MediaNotificationBackgroundImplTest,
194        DeriveBackgroundColor_ArtworkSetThenFavicon) {
195   constexpr SkColor kArtworkColor = SK_ColorYELLOW;
196   constexpr SkColor kFaviconColor = SK_ColorRED;
197 
198   background()->UpdateArtwork(CreateTestBackgroundImage(kArtworkColor));
199   background()->UpdateFavicon(CreateTestBackgroundImage(kFaviconColor));
200 
201   EXPECT_EQ(kArtworkColor, GetBackgroundColor());
202 }
203 
TEST_F(MediaNotificationBackgroundImplTest,DeriveBackgroundColor_SetAndRemoveArtworkWithFavicon)204 TEST_F(MediaNotificationBackgroundImplTest,
205        DeriveBackgroundColor_SetAndRemoveArtworkWithFavicon) {
206   constexpr SkColor kArtworkColor = SK_ColorYELLOW;
207   constexpr SkColor kFaviconColor = SK_ColorRED;
208 
209   background()->UpdateArtwork(CreateTestBackgroundImage(kArtworkColor));
210   background()->UpdateFavicon(CreateTestBackgroundImage(kFaviconColor));
211   background()->UpdateArtwork(gfx::ImageSkia());
212 
213   const SkColor expected_color = SkColorSetRGB(
214       SkColorGetR(kFaviconColor) * GetBackgroundFaviconColorShadeFactor(),
215       SkColorGetG(kFaviconColor) * GetBackgroundFaviconColorShadeFactor(),
216       SkColorGetB(kFaviconColor) * GetBackgroundFaviconColorShadeFactor());
217   EXPECT_EQ(expected_color, GetBackgroundColor());
218 }
219 
TEST_F(MediaNotificationBackgroundImplTest,GetBackgroundColorRespectsTheme)220 TEST_F(MediaNotificationBackgroundImplTest, GetBackgroundColorRespectsTheme) {
221   TestDarkTheme dark_theme;
222   views::View owner;
223   owner.SetNativeThemeForTesting(&dark_theme);
224   EXPECT_EQ(kDarkBackgroundColor, background()->GetBackgroundColor(owner));
225 }
226 
227 // MediaNotificationBackgroundImplBlackWhiteTest will repeat these tests with a
228 // parameter that is either black or white.
229 class MediaNotificationBackgroundImplBlackWhiteTest
230     : public MediaNotificationBackgroundImplTest,
231       public testing::WithParamInterface<SkColor> {
232  public:
IsBlack() const233   bool IsBlack() const { return GetParam() == SK_ColorBLACK; }
234 
CreateTestForegroundArtwork(const SkColor & first,const SkColor & second,int first_width,int second_height)235   gfx::ImageSkia CreateTestForegroundArtwork(const SkColor& first,
236                                              const SkColor& second,
237                                              int first_width,
238                                              int second_height) {
239     gfx::Rect area(100, 100);
240 
241     SkBitmap bitmap;
242     bitmap.allocN32Pixels(area.width(), area.height());
243     bitmap.eraseColor(GetParam());
244 
245     area.Inset(40, 0, 0, 0);
246     bitmap.erase(first, gfx::RectToSkIRect(area));
247 
248     area.Inset(first_width, area.height() - second_height, 0, 0);
249     bitmap.erase(second, gfx::RectToSkIRect(area));
250 
251     return gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
252   }
253 };
254 
255 INSTANTIATE_TEST_SUITE_P(All,
256                          MediaNotificationBackgroundImplBlackWhiteTest,
257                          testing::Values(SK_ColorBLACK, SK_ColorWHITE));
258 
259 // If the most popular color is black or white but there is no secondary color
260 // we should use the most popular color.
TEST_P(MediaNotificationBackgroundImplBlackWhiteTest,DeriveBackgroundColor_PopularBlackWhiteNoSecondaryColor)261 TEST_P(MediaNotificationBackgroundImplBlackWhiteTest,
262        DeriveBackgroundColor_PopularBlackWhiteNoSecondaryColor) {
263   background()->UpdateArtwork(CreateTestBackgroundImage(GetParam()));
264   EXPECT_EQ(GetParam(), GetBackgroundColor());
265 }
266 
267 // If the most popular color is black or white and there is a secondary color
268 // that is very minor then we should use the most popular color.
TEST_P(MediaNotificationBackgroundImplBlackWhiteTest,DeriveBackgroundColor_VeryPopularBlackWhite)269 TEST_P(MediaNotificationBackgroundImplBlackWhiteTest,
270        DeriveBackgroundColor_VeryPopularBlackWhite) {
271   background()->UpdateArtwork(
272       CreateTestBackgroundImage(GetParam(), SK_ColorYELLOW, 20));
273   EXPECT_EQ(GetParam(), GetBackgroundColor());
274 }
275 
276 // If the most popular color is black or white but it is not that popular then
277 // we should use the secondary color.
TEST_P(MediaNotificationBackgroundImplBlackWhiteTest,DeriveBackgroundColor_NotVeryPopularBlackWhite)278 TEST_P(MediaNotificationBackgroundImplBlackWhiteTest,
279        DeriveBackgroundColor_NotVeryPopularBlackWhite) {
280   constexpr SkColor kTestColor = SK_ColorYELLOW;
281   background()->UpdateArtwork(
282       CreateTestBackgroundImage(GetParam(), kTestColor, 40));
283   EXPECT_EQ(kTestColor, GetBackgroundColor());
284 }
285 
286 // If there are multiple vibrant colors then the foreground color should be the
287 // most popular one.
TEST_P(MediaNotificationBackgroundImplBlackWhiteTest,DeriveForegroundColor_Palette_MultiVibrant)288 TEST_P(MediaNotificationBackgroundImplBlackWhiteTest,
289        DeriveForegroundColor_Palette_MultiVibrant) {
290   const SkColor kTestColor = SK_ColorCYAN;
291 
292   background()->UpdateArtwork(CreateTestForegroundArtwork(
293       kTestColor, GetColorFromSL(kVibrantSaturation, kDarkLuma), 59,
294       kDefaultForegroundArtworkHeight));
295 
296   EXPECT_EQ(GetParam(), GetBackgroundColor());
297   EXPECT_EQ(kTestColor, GetForegroundColor());
298 }
299 
300 // If there is a vibrant and muted color then the foreground color should be the
301 // more vibrant one.
TEST_P(MediaNotificationBackgroundImplBlackWhiteTest,DeriveForegroundColor_Palette_Vibrant)302 TEST_P(MediaNotificationBackgroundImplBlackWhiteTest,
303        DeriveForegroundColor_Palette_Vibrant) {
304   const SkColor kTestColor = GetColorFromSL(kVibrantSaturation, kNormalLuma);
305 
306   background()->UpdateArtwork(CreateTestForegroundArtwork(
307       kTestColor, GetColorFromSL(kMutedSaturation, kNormalLuma), 30,
308       kDefaultForegroundArtworkHeight));
309 
310   EXPECT_EQ(GetParam(), GetBackgroundColor());
311   EXPECT_EQ(kTestColor, GetForegroundColor());
312 }
313 
314 // If there are multiple muted colors then the foreground color should be the
315 // most popular one.
TEST_P(MediaNotificationBackgroundImplBlackWhiteTest,DeriveForegroundColor_Palette_MultiMuted)316 TEST_P(MediaNotificationBackgroundImplBlackWhiteTest,
317        DeriveForegroundColor_Palette_MultiMuted) {
318   const SkColor kTestColor = GetColorFromSL(kMutedSaturation, kNormalLuma);
319 
320   background()->UpdateArtwork(CreateTestForegroundArtwork(
321       kTestColor, GetColorFromSL(kMutedSaturation, kDarkLuma), 59,
322       kDefaultForegroundArtworkHeight));
323 
324   EXPECT_EQ(GetParam(), GetBackgroundColor());
325   EXPECT_EQ(kTestColor, GetForegroundColor());
326 }
327 
328 // If there is a normal and light muted color then the foreground color should
329 // be the normal one.
TEST_P(MediaNotificationBackgroundImplBlackWhiteTest,DeriveForegroundColor_Palette_Muted)330 TEST_P(MediaNotificationBackgroundImplBlackWhiteTest,
331        DeriveForegroundColor_Palette_Muted) {
332   const SkColor kTestColor = GetColorFromSL(kMutedSaturation, kNormalLuma);
333   const SkColor kSecondColor =
334       GetColorFromSL(kMutedSaturation, IsBlack() ? kDarkLuma : kLightLuma);
335 
336   background()->UpdateArtwork(CreateTestForegroundArtwork(
337       kTestColor, kSecondColor, 30, kDefaultForegroundArtworkHeight));
338 
339   EXPECT_EQ(GetParam(), GetBackgroundColor());
340   EXPECT_EQ(kTestColor, GetForegroundColor());
341 }
342 
343 // If the best color is not the most popular one, but the most popular one is
344 // not that popular then we should use the best color.
TEST_P(MediaNotificationBackgroundImplBlackWhiteTest,DeriveForegroundColor_Palette_NotPopular)345 TEST_P(MediaNotificationBackgroundImplBlackWhiteTest,
346        DeriveForegroundColor_Palette_NotPopular) {
347   const SkColor kTestColor = SK_ColorMAGENTA;
348 
349   background()->UpdateArtwork(CreateTestForegroundArtwork(
350       kTestColor, GetColorFromSL(kMutedSaturation, kNormalLuma), 25,
351       kDefaultForegroundArtworkHeight));
352 
353   EXPECT_EQ(GetParam(), GetBackgroundColor());
354   EXPECT_EQ(kTestColor, GetForegroundColor());
355 }
356 
357 // If we do not have a best color but we have a popular one over a threshold
358 // then we should use that one.
TEST_P(MediaNotificationBackgroundImplBlackWhiteTest,DeriveForegroundColor_MostPopular)359 TEST_P(MediaNotificationBackgroundImplBlackWhiteTest,
360        DeriveForegroundColor_MostPopular) {
361   const SkColor kTestColor = GetColorFromSL(kMutedSaturation, kNormalLuma);
362 
363   background()->UpdateArtwork(CreateTestForegroundArtwork(
364       kTestColor, GetColorFromSL(kVibrantSaturation, kNormalLuma), 59, 50));
365 
366   EXPECT_EQ(GetParam(), GetBackgroundColor());
367   EXPECT_EQ(kTestColor, GetForegroundColor());
368 }
369 
370 // If the background color is dark then we should select for a lighter color,
371 // otherwise we should select for a darker one.
TEST_P(MediaNotificationBackgroundImplBlackWhiteTest,DeriveForegroundColor_Palette_MoreVibrant)372 TEST_P(MediaNotificationBackgroundImplBlackWhiteTest,
373        DeriveForegroundColor_Palette_MoreVibrant) {
374   const SkColor kTestColor =
375       GetColorFromSL(kVibrantSaturation, IsBlack() ? kLightLuma : kDarkLuma);
376 
377   background()->UpdateArtwork(CreateTestForegroundArtwork(
378       kTestColor, GetColorFromSL(kVibrantSaturation, kNormalLuma), 30,
379       kDefaultForegroundArtworkHeight));
380 
381   EXPECT_EQ(GetParam(), GetBackgroundColor());
382   EXPECT_EQ(kTestColor, GetForegroundColor());
383 }
384 
385 // If the background color is dark then we should select for a lighter color,
386 // otherwise we should select for a darker one.
TEST_P(MediaNotificationBackgroundImplBlackWhiteTest,DeriveForegroundColor_Palette_MoreMuted)387 TEST_P(MediaNotificationBackgroundImplBlackWhiteTest,
388        DeriveForegroundColor_Palette_MoreMuted) {
389   const SkColor kTestColor =
390       GetColorFromSL(kMutedSaturation, IsBlack() ? kLightLuma : kDarkLuma);
391   const SkColor kSecondColor =
392       GetColorFromSL(kMutedSaturation, IsBlack() ? kDarkLuma : kLightLuma);
393 
394   background()->UpdateArtwork(CreateTestForegroundArtwork(
395       kTestColor, kSecondColor, 30, kDefaultForegroundArtworkHeight));
396 
397   EXPECT_EQ(GetParam(), GetBackgroundColor());
398   EXPECT_EQ(kTestColor, GetForegroundColor());
399 }
400 
401 // If we do not have any colors then we should use the fallback color based on
402 // the background color.
TEST_P(MediaNotificationBackgroundImplBlackWhiteTest,DeriveForegroundColor_Fallback)403 TEST_P(MediaNotificationBackgroundImplBlackWhiteTest,
404        DeriveForegroundColor_Fallback) {
405   background()->UpdateArtwork(CreateTestForegroundArtwork(
406       SK_ColorTRANSPARENT, SK_ColorTRANSPARENT, 0, 0));
407 
408   EXPECT_EQ(GetParam(), GetBackgroundColor());
409   EXPECT_EQ(GetParam() == SK_ColorBLACK ? SK_ColorWHITE : SK_ColorBLACK,
410             GetForegroundColor());
411 }
412 
413 // MediaNotificationBackgroundImplRTLTest will repeat these tests with RTL
414 // disabled and enabled.
415 class MediaNotificationBackgroundImplRTLTest
416     : public MediaNotificationBackgroundImplTest,
417       public testing::WithParamInterface<bool> {
418  public:
SetUp()419   void SetUp() override {
420     command_line_.GetProcessCommandLine()->AppendSwitchASCII(
421         switches::kForceUIDirection, GetParam() ? switches::kForceDirectionRTL
422                                                 : switches::kForceDirectionLTR);
423 
424     MediaNotificationBackgroundImplTest::SetUp();
425 
426     ASSERT_EQ(IsRTL(), base::i18n::IsRTL());
427   }
428 
IsRTL() const429   bool IsRTL() const { return GetParam(); }
430 
431  private:
432   base::test::ScopedRestoreICUDefaultLocale scoped_locale_;
433   base::test::ScopedCommandLine command_line_;
434 };
435 
436 INSTANTIATE_TEST_SUITE_P(All,
437                          MediaNotificationBackgroundImplRTLTest,
438                          testing::Bool());
439 
TEST_P(MediaNotificationBackgroundImplRTLTest,BoundsSanityCheck)440 TEST_P(MediaNotificationBackgroundImplRTLTest, BoundsSanityCheck) {
441   // The test notification will have a width of 200 and a height of 50.
442   gfx::Rect bounds(0, 0, 200, 50);
443   auto owner = std::make_unique<views::StaticSizedView>();
444   owner->SetBoundsRect(bounds);
445   ASSERT_EQ(bounds, owner->GetContentsBounds());
446 
447   // Check the artwork is not visible by default.
448   EXPECT_EQ(0, background()->GetArtworkWidth(bounds.size()));
449   EXPECT_EQ(0, background()->GetArtworkVisibleWidth(bounds.size()));
450   EXPECT_EQ(gfx::Rect(IsRTL() ? 0 : 200, 0, 0, 50),
451             background()->GetArtworkBounds(*owner.get()));
452   EXPECT_EQ(gfx::Rect(IsRTL() ? 0 : 0, 0, 200, 50),
453             background()->GetFilledBackgroundBounds(*owner.get()));
454   EXPECT_EQ(gfx::Rect(0, 0, 0, 0),
455             background()->GetGradientBounds(*owner.get()));
456 
457   // The background artwork image will have an aspect ratio of 2:1.
458   SkBitmap bitmap;
459   bitmap.allocN32Pixels(20, 10);
460   bitmap.eraseColor(SK_ColorWHITE);
461   background()->UpdateArtwork(gfx::ImageSkia::CreateFrom1xBitmap(bitmap));
462 
463   // The artwork width will be 2x the height of the notification and the visible
464   // width will be limited to 10% the width of the notification.
465   EXPECT_EQ(100, background()->GetArtworkWidth(bounds.size()));
466   EXPECT_EQ(20, background()->GetArtworkVisibleWidth(bounds.size()));
467 
468   // Update the visible width % to be greater than the width of the image.
469   background()->UpdateArtworkMaxWidthPct(0.6);
470   EXPECT_EQ(100, background()->GetArtworkVisibleWidth(bounds.size()));
471 
472   // Check the artwork is positioned to the right.
473   EXPECT_EQ(gfx::Rect(IsRTL() ? 0 : 100, 0, 100, 50),
474             background()->GetArtworkBounds(*owner.get()));
475 
476   // Check the filled background is to the left of the image.
477   EXPECT_EQ(gfx::Rect(IsRTL() ? 100 : 0, 0, 100, 50),
478             background()->GetFilledBackgroundBounds(*owner.get()));
479 
480   // Check the gradient is positioned above the artwork.
481   const gfx::Rect gradient_bounds =
482       background()->GetGradientBounds(*owner.get());
483   EXPECT_EQ(gfx::Rect(IsRTL() ? 60 : 100, 0, 40, 50), gradient_bounds);
484 
485   // Check the gradient point X-values are the start and end of
486   // |gradient_bounds|.
487   EXPECT_EQ(100, background()->GetGradientStartPoint(gradient_bounds).x());
488   EXPECT_EQ(IsRTL() ? 60 : 140,
489             background()->GetGradientEndPoint(gradient_bounds).x());
490 
491   // Check both of the gradient point Y-values are half the height.
492   EXPECT_EQ(25, background()->GetGradientStartPoint(gradient_bounds).y());
493   EXPECT_EQ(25, background()->GetGradientEndPoint(gradient_bounds).y());
494 }
495 
496 }  // namespace media_message_center
497