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.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 MediaNotificationBackgroundTest : public testing::Test {
88  public:
89   MediaNotificationBackgroundTest() = default;
90   ~MediaNotificationBackgroundTest() override = default;
91 
SetUp()92   void SetUp() override {
93     background_ = std::make_unique<MediaNotificationBackground>(10, 10, 0.1);
94 
95     EXPECT_FALSE(GetBackgroundColor().has_value());
96   }
97 
TearDown()98   void TearDown() override {
99     background_.reset();
100   }
101 
background() const102   MediaNotificationBackground* background() const { return background_.get(); }
103 
GetBackgroundColor() const104   base::Optional<SkColor> GetBackgroundColor() const {
105     return background_->background_color_;
106   }
107 
GetForegroundColor() const108   base::Optional<SkColor> GetForegroundColor() const {
109     return background_->foreground_color_;
110   }
111 
GetBackgroundFaviconColorShadeFactor() const112   double GetBackgroundFaviconColorShadeFactor() const {
113     return MediaNotificationBackground::kBackgroundFaviconColorShadeFactor;
114   }
115 
116  private:
117   std::unique_ptr<MediaNotificationBackground> background_;
118 
119   DISALLOW_COPY_AND_ASSIGN(MediaNotificationBackgroundTest);
120 };
121 
122 // If we have no artwork then we should use the default background color.
TEST_F(MediaNotificationBackgroundTest,DeriveBackgroundColor_NoArtwork)123 TEST_F(MediaNotificationBackgroundTest, DeriveBackgroundColor_NoArtwork) {
124   background()->UpdateArtwork(gfx::ImageSkia());
125   EXPECT_FALSE(GetBackgroundColor().has_value());
126 }
127 
128 // If we have artwork with no popular color then we should use the default
129 // background color.
TEST_F(MediaNotificationBackgroundTest,DeriveBackgroundColor_NoPopularColor)130 TEST_F(MediaNotificationBackgroundTest, DeriveBackgroundColor_NoPopularColor) {
131   background()->UpdateArtwork(CreateTestBackgroundImage(SK_ColorTRANSPARENT));
132   EXPECT_FALSE(GetBackgroundColor().has_value());
133 }
134 
135 // If the most popular color is not white or black then we should use that
136 // color.
TEST_F(MediaNotificationBackgroundTest,DeriveBackgroundColor_PopularNonWhiteBlackColor)137 TEST_F(MediaNotificationBackgroundTest,
138        DeriveBackgroundColor_PopularNonWhiteBlackColor) {
139   constexpr SkColor kTestColor = SK_ColorYELLOW;
140   background()->UpdateArtwork(CreateTestBackgroundImage(kTestColor));
141   EXPECT_EQ(kTestColor, GetBackgroundColor());
142 }
143 
TEST_F(MediaNotificationBackgroundTest,DeriveBackgroundColor_NoArtworkAfterHavingOne)144 TEST_F(MediaNotificationBackgroundTest,
145        DeriveBackgroundColor_NoArtworkAfterHavingOne) {
146   constexpr SkColor kTestColor = SK_ColorYELLOW;
147   background()->UpdateArtwork(CreateTestBackgroundImage(kTestColor));
148   EXPECT_EQ(kTestColor, GetBackgroundColor());
149 
150   background()->UpdateArtwork(gfx::ImageSkia());
151   EXPECT_FALSE(GetBackgroundColor().has_value());
152 }
153 
154 // Favicons should be used when available but have a shade applying to them.
TEST_F(MediaNotificationBackgroundTest,DeriveBackgroundColor_PopularNonWhiteBlackColorFavicon)155 TEST_F(MediaNotificationBackgroundTest,
156        DeriveBackgroundColor_PopularNonWhiteBlackColorFavicon) {
157   constexpr SkColor kTestColor = SK_ColorYELLOW;
158   background()->UpdateFavicon(CreateTestBackgroundImage(kTestColor));
159   const SkColor expected_color = SkColorSetRGB(
160       SkColorGetR(kTestColor) * GetBackgroundFaviconColorShadeFactor(),
161       SkColorGetG(kTestColor) * GetBackgroundFaviconColorShadeFactor(),
162       SkColorGetB(kTestColor) * GetBackgroundFaviconColorShadeFactor());
163   EXPECT_EQ(expected_color, GetBackgroundColor());
164 }
165 
TEST_F(MediaNotificationBackgroundTest,DeriveBackgroundColor_NoFaviconAfterHavingOne)166 TEST_F(MediaNotificationBackgroundTest,
167        DeriveBackgroundColor_NoFaviconAfterHavingOne) {
168   constexpr SkColor kTestColor = SK_ColorYELLOW;
169   background()->UpdateFavicon(CreateTestBackgroundImage(kTestColor));
170   const SkColor expected_color = SkColorSetRGB(
171       SkColorGetR(kTestColor) * GetBackgroundFaviconColorShadeFactor(),
172       SkColorGetG(kTestColor) * GetBackgroundFaviconColorShadeFactor(),
173       SkColorGetB(kTestColor) * GetBackgroundFaviconColorShadeFactor());
174   EXPECT_EQ(expected_color, GetBackgroundColor());
175 
176   background()->UpdateFavicon(gfx::ImageSkia());
177   EXPECT_FALSE(GetBackgroundColor().has_value());
178 }
179 
TEST_F(MediaNotificationBackgroundTest,DeriveBackgroundColor_FaviconSetThenArtwork)180 TEST_F(MediaNotificationBackgroundTest,
181        DeriveBackgroundColor_FaviconSetThenArtwork) {
182   constexpr SkColor kArtworkColor = SK_ColorYELLOW;
183   constexpr SkColor kFaviconColor = SK_ColorRED;
184 
185   background()->UpdateFavicon(CreateTestBackgroundImage(kFaviconColor));
186   background()->UpdateArtwork(CreateTestBackgroundImage(kArtworkColor));
187 
188   EXPECT_EQ(kArtworkColor, GetBackgroundColor());
189 }
190 
TEST_F(MediaNotificationBackgroundTest,DeriveBackgroundColor_ArtworkSetThenFavicon)191 TEST_F(MediaNotificationBackgroundTest,
192        DeriveBackgroundColor_ArtworkSetThenFavicon) {
193   constexpr SkColor kArtworkColor = SK_ColorYELLOW;
194   constexpr SkColor kFaviconColor = SK_ColorRED;
195 
196   background()->UpdateArtwork(CreateTestBackgroundImage(kArtworkColor));
197   background()->UpdateFavicon(CreateTestBackgroundImage(kFaviconColor));
198 
199   EXPECT_EQ(kArtworkColor, GetBackgroundColor());
200 }
201 
TEST_F(MediaNotificationBackgroundTest,DeriveBackgroundColor_SetAndRemoveArtworkWithFavicon)202 TEST_F(MediaNotificationBackgroundTest,
203        DeriveBackgroundColor_SetAndRemoveArtworkWithFavicon) {
204   constexpr SkColor kArtworkColor = SK_ColorYELLOW;
205   constexpr SkColor kFaviconColor = SK_ColorRED;
206 
207   background()->UpdateArtwork(CreateTestBackgroundImage(kArtworkColor));
208   background()->UpdateFavicon(CreateTestBackgroundImage(kFaviconColor));
209   background()->UpdateArtwork(gfx::ImageSkia());
210 
211   const SkColor expected_color = SkColorSetRGB(
212       SkColorGetR(kFaviconColor) * GetBackgroundFaviconColorShadeFactor(),
213       SkColorGetG(kFaviconColor) * GetBackgroundFaviconColorShadeFactor(),
214       SkColorGetB(kFaviconColor) * GetBackgroundFaviconColorShadeFactor());
215   EXPECT_EQ(expected_color, GetBackgroundColor());
216 }
217 
TEST_F(MediaNotificationBackgroundTest,GetBackgroundColorRespectsTheme)218 TEST_F(MediaNotificationBackgroundTest, GetBackgroundColorRespectsTheme) {
219   TestDarkTheme dark_theme;
220   views::View owner;
221   owner.SetNativeThemeForTesting(&dark_theme);
222   EXPECT_EQ(kDarkBackgroundColor, background()->GetBackgroundColor(owner));
223 }
224 
225 // MediaNotificationBackgroundBlackWhiteTest will repeat these tests with a
226 // parameter that is either black or white.
227 class MediaNotificationBackgroundBlackWhiteTest
228     : public MediaNotificationBackgroundTest,
229       public testing::WithParamInterface<SkColor> {
230  public:
IsBlack() const231   bool IsBlack() const { return GetParam() == SK_ColorBLACK; }
232 
CreateTestForegroundArtwork(const SkColor & first,const SkColor & second,int first_width,int second_height)233   gfx::ImageSkia CreateTestForegroundArtwork(const SkColor& first,
234                                              const SkColor& second,
235                                              int first_width,
236                                              int second_height) {
237     gfx::Rect area(100, 100);
238 
239     SkBitmap bitmap;
240     bitmap.allocN32Pixels(area.width(), area.height());
241     bitmap.eraseColor(GetParam());
242 
243     area.Inset(40, 0, 0, 0);
244     bitmap.erase(first, gfx::RectToSkIRect(area));
245 
246     area.Inset(first_width, area.height() - second_height, 0, 0);
247     bitmap.erase(second, gfx::RectToSkIRect(area));
248 
249     return gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
250   }
251 };
252 
253 INSTANTIATE_TEST_SUITE_P(All,
254                          MediaNotificationBackgroundBlackWhiteTest,
255                          testing::Values(SK_ColorBLACK, SK_ColorWHITE));
256 
257 // If the most popular color is black or white but there is no secondary color
258 // we should use the most popular color.
TEST_P(MediaNotificationBackgroundBlackWhiteTest,DeriveBackgroundColor_PopularBlackWhiteNoSecondaryColor)259 TEST_P(MediaNotificationBackgroundBlackWhiteTest,
260        DeriveBackgroundColor_PopularBlackWhiteNoSecondaryColor) {
261   background()->UpdateArtwork(CreateTestBackgroundImage(GetParam()));
262   EXPECT_EQ(GetParam(), GetBackgroundColor());
263 }
264 
265 // If the most popular color is black or white and there is a secondary color
266 // that is very minor then we should use the most popular color.
TEST_P(MediaNotificationBackgroundBlackWhiteTest,DeriveBackgroundColor_VeryPopularBlackWhite)267 TEST_P(MediaNotificationBackgroundBlackWhiteTest,
268        DeriveBackgroundColor_VeryPopularBlackWhite) {
269   background()->UpdateArtwork(
270       CreateTestBackgroundImage(GetParam(), SK_ColorYELLOW, 20));
271   EXPECT_EQ(GetParam(), GetBackgroundColor());
272 }
273 
274 // If the most popular color is black or white but it is not that popular then
275 // we should use the secondary color.
TEST_P(MediaNotificationBackgroundBlackWhiteTest,DeriveBackgroundColor_NotVeryPopularBlackWhite)276 TEST_P(MediaNotificationBackgroundBlackWhiteTest,
277        DeriveBackgroundColor_NotVeryPopularBlackWhite) {
278   constexpr SkColor kTestColor = SK_ColorYELLOW;
279   background()->UpdateArtwork(
280       CreateTestBackgroundImage(GetParam(), kTestColor, 40));
281   EXPECT_EQ(kTestColor, GetBackgroundColor());
282 }
283 
284 // If there are multiple vibrant colors then the foreground color should be the
285 // most popular one.
TEST_P(MediaNotificationBackgroundBlackWhiteTest,DeriveForegroundColor_Palette_MultiVibrant)286 TEST_P(MediaNotificationBackgroundBlackWhiteTest,
287        DeriveForegroundColor_Palette_MultiVibrant) {
288   const SkColor kTestColor = SK_ColorCYAN;
289 
290   background()->UpdateArtwork(CreateTestForegroundArtwork(
291       kTestColor, GetColorFromSL(kVibrantSaturation, kDarkLuma), 59,
292       kDefaultForegroundArtworkHeight));
293 
294   EXPECT_EQ(GetParam(), GetBackgroundColor());
295   EXPECT_EQ(kTestColor, GetForegroundColor());
296 }
297 
298 // If there is a vibrant and muted color then the foreground color should be the
299 // more vibrant one.
TEST_P(MediaNotificationBackgroundBlackWhiteTest,DeriveForegroundColor_Palette_Vibrant)300 TEST_P(MediaNotificationBackgroundBlackWhiteTest,
301        DeriveForegroundColor_Palette_Vibrant) {
302   const SkColor kTestColor = GetColorFromSL(kVibrantSaturation, kNormalLuma);
303 
304   background()->UpdateArtwork(CreateTestForegroundArtwork(
305       kTestColor, GetColorFromSL(kMutedSaturation, kNormalLuma), 30,
306       kDefaultForegroundArtworkHeight));
307 
308   EXPECT_EQ(GetParam(), GetBackgroundColor());
309   EXPECT_EQ(kTestColor, GetForegroundColor());
310 }
311 
312 // If there are multiple muted colors then the foreground color should be the
313 // most popular one.
TEST_P(MediaNotificationBackgroundBlackWhiteTest,DeriveForegroundColor_Palette_MultiMuted)314 TEST_P(MediaNotificationBackgroundBlackWhiteTest,
315        DeriveForegroundColor_Palette_MultiMuted) {
316   const SkColor kTestColor = GetColorFromSL(kMutedSaturation, kNormalLuma);
317 
318   background()->UpdateArtwork(CreateTestForegroundArtwork(
319       kTestColor, GetColorFromSL(kMutedSaturation, kDarkLuma), 59,
320       kDefaultForegroundArtworkHeight));
321 
322   EXPECT_EQ(GetParam(), GetBackgroundColor());
323   EXPECT_EQ(kTestColor, GetForegroundColor());
324 }
325 
326 // If there is a normal and light muted color then the foreground color should
327 // be the normal one.
TEST_P(MediaNotificationBackgroundBlackWhiteTest,DeriveForegroundColor_Palette_Muted)328 TEST_P(MediaNotificationBackgroundBlackWhiteTest,
329        DeriveForegroundColor_Palette_Muted) {
330   const SkColor kTestColor = GetColorFromSL(kMutedSaturation, kNormalLuma);
331   const SkColor kSecondColor =
332       GetColorFromSL(kMutedSaturation, IsBlack() ? kDarkLuma : kLightLuma);
333 
334   background()->UpdateArtwork(CreateTestForegroundArtwork(
335       kTestColor, kSecondColor, 30, kDefaultForegroundArtworkHeight));
336 
337   EXPECT_EQ(GetParam(), GetBackgroundColor());
338   EXPECT_EQ(kTestColor, GetForegroundColor());
339 }
340 
341 // If the best color is not the most popular one, but the most popular one is
342 // not that popular then we should use the best color.
TEST_P(MediaNotificationBackgroundBlackWhiteTest,DeriveForegroundColor_Palette_NotPopular)343 TEST_P(MediaNotificationBackgroundBlackWhiteTest,
344        DeriveForegroundColor_Palette_NotPopular) {
345   const SkColor kTestColor = SK_ColorMAGENTA;
346 
347   background()->UpdateArtwork(CreateTestForegroundArtwork(
348       kTestColor, GetColorFromSL(kMutedSaturation, kNormalLuma), 25,
349       kDefaultForegroundArtworkHeight));
350 
351   EXPECT_EQ(GetParam(), GetBackgroundColor());
352   EXPECT_EQ(kTestColor, GetForegroundColor());
353 }
354 
355 // If we do not have a best color but we have a popular one over a threshold
356 // then we should use that one.
TEST_P(MediaNotificationBackgroundBlackWhiteTest,DeriveForegroundColor_MostPopular)357 TEST_P(MediaNotificationBackgroundBlackWhiteTest,
358        DeriveForegroundColor_MostPopular) {
359   const SkColor kTestColor = GetColorFromSL(kMutedSaturation, kNormalLuma);
360 
361   background()->UpdateArtwork(CreateTestForegroundArtwork(
362       kTestColor, GetColorFromSL(kVibrantSaturation, kNormalLuma), 59, 50));
363 
364   EXPECT_EQ(GetParam(), GetBackgroundColor());
365   EXPECT_EQ(kTestColor, GetForegroundColor());
366 }
367 
368 // If the background color is dark then we should select for a lighter color,
369 // otherwise we should select for a darker one.
TEST_P(MediaNotificationBackgroundBlackWhiteTest,DeriveForegroundColor_Palette_MoreVibrant)370 TEST_P(MediaNotificationBackgroundBlackWhiteTest,
371        DeriveForegroundColor_Palette_MoreVibrant) {
372   const SkColor kTestColor =
373       GetColorFromSL(kVibrantSaturation, IsBlack() ? kLightLuma : kDarkLuma);
374 
375   background()->UpdateArtwork(CreateTestForegroundArtwork(
376       kTestColor, GetColorFromSL(kVibrantSaturation, kNormalLuma), 30,
377       kDefaultForegroundArtworkHeight));
378 
379   EXPECT_EQ(GetParam(), GetBackgroundColor());
380   EXPECT_EQ(kTestColor, GetForegroundColor());
381 }
382 
383 // If the background color is dark then we should select for a lighter color,
384 // otherwise we should select for a darker one.
TEST_P(MediaNotificationBackgroundBlackWhiteTest,DeriveForegroundColor_Palette_MoreMuted)385 TEST_P(MediaNotificationBackgroundBlackWhiteTest,
386        DeriveForegroundColor_Palette_MoreMuted) {
387   const SkColor kTestColor =
388       GetColorFromSL(kMutedSaturation, IsBlack() ? kLightLuma : kDarkLuma);
389   const SkColor kSecondColor =
390       GetColorFromSL(kMutedSaturation, IsBlack() ? kDarkLuma : kLightLuma);
391 
392   background()->UpdateArtwork(CreateTestForegroundArtwork(
393       kTestColor, kSecondColor, 30, kDefaultForegroundArtworkHeight));
394 
395   EXPECT_EQ(GetParam(), GetBackgroundColor());
396   EXPECT_EQ(kTestColor, GetForegroundColor());
397 }
398 
399 // If we do not have any colors then we should use the fallback color based on
400 // the background color.
TEST_P(MediaNotificationBackgroundBlackWhiteTest,DeriveForegroundColor_Fallback)401 TEST_P(MediaNotificationBackgroundBlackWhiteTest,
402        DeriveForegroundColor_Fallback) {
403   background()->UpdateArtwork(CreateTestForegroundArtwork(
404       SK_ColorTRANSPARENT, SK_ColorTRANSPARENT, 0, 0));
405 
406   EXPECT_EQ(GetParam(), GetBackgroundColor());
407   EXPECT_EQ(GetParam() == SK_ColorBLACK ? SK_ColorWHITE : SK_ColorBLACK,
408             GetForegroundColor());
409 }
410 
411 // MediaNotificationBackgroundRTLTest will repeat these tests with RTL disabled
412 // and enabled.
413 class MediaNotificationBackgroundRTLTest
414     : public MediaNotificationBackgroundTest,
415       public testing::WithParamInterface<bool> {
416  public:
SetUp()417   void SetUp() override {
418     command_line_.GetProcessCommandLine()->AppendSwitchASCII(
419         switches::kForceUIDirection, GetParam() ? switches::kForceDirectionRTL
420                                                 : switches::kForceDirectionLTR);
421 
422     MediaNotificationBackgroundTest::SetUp();
423 
424     ASSERT_EQ(IsRTL(), base::i18n::IsRTL());
425   }
426 
IsRTL() const427   bool IsRTL() const { return GetParam(); }
428 
429  private:
430   base::test::ScopedRestoreICUDefaultLocale scoped_locale_;
431   base::test::ScopedCommandLine command_line_;
432 };
433 
434 INSTANTIATE_TEST_SUITE_P(All,
435                          MediaNotificationBackgroundRTLTest,
436                          testing::Bool());
437 
TEST_P(MediaNotificationBackgroundRTLTest,BoundsSanityCheck)438 TEST_P(MediaNotificationBackgroundRTLTest, BoundsSanityCheck) {
439   // The test notification will have a width of 200 and a height of 50.
440   gfx::Rect bounds(0, 0, 200, 50);
441   auto owner = std::make_unique<views::StaticSizedView>();
442   owner->SetBoundsRect(bounds);
443   ASSERT_EQ(bounds, owner->GetContentsBounds());
444 
445   // Check the artwork is not visible by default.
446   EXPECT_EQ(0, background()->GetArtworkWidth(bounds.size()));
447   EXPECT_EQ(0, background()->GetArtworkVisibleWidth(bounds.size()));
448   EXPECT_EQ(gfx::Rect(IsRTL() ? 0 : 200, 0, 0, 50),
449             background()->GetArtworkBounds(*owner.get()));
450   EXPECT_EQ(gfx::Rect(IsRTL() ? 0 : 0, 0, 200, 50),
451             background()->GetFilledBackgroundBounds(*owner.get()));
452   EXPECT_EQ(gfx::Rect(0, 0, 0, 0),
453             background()->GetGradientBounds(*owner.get()));
454 
455   // The background artwork image will have an aspect ratio of 2:1.
456   SkBitmap bitmap;
457   bitmap.allocN32Pixels(20, 10);
458   bitmap.eraseColor(SK_ColorWHITE);
459   background()->UpdateArtwork(gfx::ImageSkia::CreateFrom1xBitmap(bitmap));
460 
461   // The artwork width will be 2x the height of the notification and the visible
462   // width will be limited to 10% the width of the notification.
463   EXPECT_EQ(100, background()->GetArtworkWidth(bounds.size()));
464   EXPECT_EQ(20, background()->GetArtworkVisibleWidth(bounds.size()));
465 
466   // Update the visible width % to be greater than the width of the image.
467   background()->UpdateArtworkMaxWidthPct(0.6);
468   EXPECT_EQ(100, background()->GetArtworkVisibleWidth(bounds.size()));
469 
470   // Check the artwork is positioned to the right.
471   EXPECT_EQ(gfx::Rect(IsRTL() ? 0 : 100, 0, 100, 50),
472             background()->GetArtworkBounds(*owner.get()));
473 
474   // Check the filled background is to the left of the image.
475   EXPECT_EQ(gfx::Rect(IsRTL() ? 100 : 0, 0, 100, 50),
476             background()->GetFilledBackgroundBounds(*owner.get()));
477 
478   // Check the gradient is positioned above the artwork.
479   const gfx::Rect gradient_bounds =
480       background()->GetGradientBounds(*owner.get());
481   EXPECT_EQ(gfx::Rect(IsRTL() ? 60 : 100, 0, 40, 50), gradient_bounds);
482 
483   // Check the gradient point X-values are the start and end of
484   // |gradient_bounds|.
485   EXPECT_EQ(100, background()->GetGradientStartPoint(gradient_bounds).x());
486   EXPECT_EQ(IsRTL() ? 60 : 140,
487             background()->GetGradientEndPoint(gradient_bounds).x());
488 
489   // Check both of the gradient point Y-values are half the height.
490   EXPECT_EQ(25, background()->GetGradientStartPoint(gradient_bounds).y());
491   EXPECT_EQ(25, background()->GetGradientEndPoint(gradient_bounds).y());
492 }
493 
494 }  // namespace media_message_center
495