| // Copyright 2012 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/themes/browser_theme_pack.h" |
| |
| #include <stddef.h> |
| |
| #include <algorithm> |
| #include <array> |
| #include <memory> |
| #include <string_view> |
| |
| #include "base/containers/flat_map.h" |
| #include "base/containers/span.h" |
| #include "base/files/scoped_temp_dir.h" |
| #include "base/json/json_file_value_serializer.h" |
| #include "base/json/json_reader.h" |
| #include "base/path_service.h" |
| #include "base/values.h" |
| #include "build/build_config.h" |
| #include "chrome/browser/themes/theme_properties.h" |
| #include "chrome/browser/ui/color/chrome_color_id.h" |
| #include "chrome/browser/ui/frame/window_frame_util.h" |
| #include "chrome/common/chrome_paths.h" |
| #include "chrome/common/extensions/manifest_handlers/theme_handler.h" |
| #include "chrome/common/themes/autogenerated_theme_util.h" |
| #include "chrome/grit/theme_resources.h" |
| #include "components/tab_groups/tab_group_color.h" |
| #include "content/public/test/browser_task_environment.h" |
| #include "extensions/common/extension.h" |
| #include "extensions/common/extension_resource.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "ui/color/color_mixer.h" |
| #include "ui/color/color_provider.h" |
| #include "ui/color/color_provider_key.h" |
| #include "ui/color/color_recipe.h" |
| #include "ui/color/color_test_ids.h" |
| #include "ui/color/dynamic_color/palette_factory.h" |
| #include "ui/gfx/color_palette.h" |
| #include "ui/gfx/color_utils.h" |
| #include "ui/gfx/image/image.h" |
| #include "ui/gfx/image/image_skia.h" |
| #include "ui/gfx/image/image_skia_rep.h" |
| |
| using extensions::Extension; |
| using TP = ThemeProperties; |
| using ThemeType = ui::ColorProviderKey::ThemeInitializerSupplier::ThemeType; |
| |
| // Maps scale factors (enum values) to file path. |
| // A similar typedef in BrowserThemePack is private. |
| using TestScaleFactorToFileMap = |
| base::flat_map<ui::ResourceScaleFactor, base::FilePath>; |
| |
| // Maps image ids to maps of scale factors to file paths. |
| // A similar typedef in BrowserThemePack is private. |
| using TestFilePathMap = |
| base::flat_map<BrowserThemePack::PersistentID, TestScaleFactorToFileMap>; |
| |
| namespace { |
| |
| extensions::ExtensionResource ExtensionResourceFromFilePath( |
| const base::FilePath& file_path) { |
| const extensions::ExtensionId kExtensionId = |
| "12345678901234567890123456789012"; |
| const base::FilePath kExtensionRoot(FILE_PATH_LITERAL("extension_root")); |
| return extensions::ExtensionResource(kExtensionId, kExtensionRoot, file_path); |
| } |
| |
| extensions::ThemeInfo::ThemeResource ThemeResourceFromRelativePath( |
| std::string_view relative_path, |
| std::string_view scale = "") { |
| return {ExtensionResourceFromFilePath( |
| base::FilePath::FromUTF8Unsafe(relative_path)), |
| std::string(scale)}; |
| } |
| |
| } // namespace |
| |
| // BrowserThemePackTest -------------------------------------------------------- |
| |
| class BrowserThemePackTest : public ::testing::Test { |
| public: |
| BrowserThemePackTest(); |
| ~BrowserThemePackTest() override = default; |
| |
| protected: |
| // Returns a mapping from each COLOR_* constant to the default value for this |
| // constant. Callers get this map, and then modify expected values and then |
| // run the resulting thing through VerifyColorMap(). |
| static std::map<int, SkColor> GetDefaultColorMap(); |
| |
| void VerifyColorMap(const std::map<int, SkColor>& color_map); |
| void LoadColorJSON(const std::string& json); |
| void LoadColorDictionary(const base::Value::Dict* value); |
| void LoadTintJSON(const std::string& json); |
| void LoadTintDictionary(const base::Value::Dict* value); |
| void LoadDisplayPropertiesJSON(const std::string& json); |
| void LoadDisplayPropertiesDictionary(const base::Value::Dict* value); |
| void ParseThemeImages(const extensions::ThemeInfo::ThemeImages* value, |
| TestFilePathMap* out_file_paths); |
| void ResetTabGroupColorPaletteShades(); |
| void LoadTabGroupColorPaletteShadesJSON(const std::string& json); |
| void LoadTabGroupColorPaletteShadesDictionary(const base::Value::Dict* value); |
| void VerifyTabGroupColorPaletteShades(); |
| bool LoadRawBitmapsTo(const TestFilePathMap& out_file_paths); |
| |
| // This function returns void in order to be able use ASSERT_... |
| // The BrowserThemePack is returned in |pack|. |
| static void BuildFromUnpackedExtension(const base::FilePath& extension_path, |
| BrowserThemePack* pack); |
| |
| // Same as BuildFromUnpackedExtension() but also asserts |
| // BrowserThemeBack::is_valid() on the returned browser theme pack. |
| static void BuildFromUnpackedExtensionCheckValid( |
| const base::FilePath& extension_path, |
| BrowserThemePack* pack); |
| |
| // Builds the theme represented by an unpacked extension (located in |
| // {DIR_TEST_DATA}/extensions/|theme_folder|). |
| // Asserts BrowserThemeBack::is_valid(). |
| // The BrowserThemePack is returned in |pack|. |
| static void BuildTestExtensionThemeCheckValid(std::string_view theme_folder, |
| BrowserThemePack* pack); |
| |
| static base::FilePath GetTestExtensionThemePath( |
| std::string_view theme_folder); |
| static base::FilePath GetStarGazingPath(); |
| static base::FilePath GetHiDpiThemePath(); |
| |
| // Verifies the data in star gazing. We do this multiple times for different |
| // BrowserThemePack objects to make sure it works in generated and mmapped |
| // mode correctly. |
| static void VerifyStarGazing(BrowserThemePack* pack); |
| |
| static void VerifyHiDpiTheme(BrowserThemePack* pack); |
| |
| // Verify that the colors in the theme for |color_id_a| and |color_id_b| are |
| // the same. |
| static void VerifyColorsMatch(BrowserThemePack* pack, |
| int color_id_a, |
| int color_id_b); |
| |
| // Verify calculated color contrasts for autogenerated themes. |
| static void VerifyCalculatedColorContrast(base::span<const SkColor> colors, |
| int colors_num, |
| float contrast_ratio); |
| |
| const BrowserThemePack& theme_pack() const { return *theme_pack_; } |
| |
| base::FilePath GetTemporaryPakFile(base::FilePath::StringViewType name) { |
| if (dir_.IsValid() || dir_.CreateUniqueTempDir()) { |
| return dir_.GetPath().Append(name); |
| } |
| ADD_FAILURE() << "Couldn't create temp dir"; |
| return base::FilePath(); |
| } |
| |
| private: |
| // Transformation for link underline colors. |
| static SkColor BuildThirdOpacity(SkColor color_link); |
| |
| // Returns the appropriate default color for |id|. |
| static SkColor GetDefaultColor(int id); |
| |
| static void GenerateDefaultFrameColor(std::map<int, SkColor>* colors, |
| int color, |
| int tint, |
| bool otr); |
| |
| ui::test::ScopedSetSupportedResourceScaleFactors |
| scoped_set_supported_scale_factors_{{ui::k100Percent, ui::k200Percent}}; |
| |
| base::ScopedTempDir dir_; |
| content::BrowserTaskEnvironment task_environment_; |
| scoped_refptr<BrowserThemePack> theme_pack_; |
| }; |
| |
| BrowserThemePackTest::BrowserThemePackTest() |
| : theme_pack_(new BrowserThemePack(ThemeType::kExtension)) { |
| theme_pack_->InitEmptyPack(); |
| } |
| |
| // static |
| std::map<int, SkColor> BrowserThemePackTest::GetDefaultColorMap() { |
| std::map<int, SkColor> colors; |
| |
| for (int i = TP::COLOR_BOOKMARK_TEXT; i <= TP::COLOR_TOOLBAR_TEXT; ++i) { |
| colors[i] = GetDefaultColor(i); |
| } |
| |
| GenerateDefaultFrameColor(&colors, TP::COLOR_FRAME_ACTIVE, TP::TINT_FRAME, |
| false); |
| GenerateDefaultFrameColor(&colors, TP::COLOR_FRAME_INACTIVE, |
| TP::TINT_FRAME_INACTIVE, false); |
| GenerateDefaultFrameColor(&colors, TP::COLOR_FRAME_ACTIVE_INCOGNITO, |
| TP::TINT_FRAME, true); |
| GenerateDefaultFrameColor(&colors, TP::COLOR_FRAME_INACTIVE_INCOGNITO, |
| TP::TINT_FRAME_INACTIVE, true); |
| |
| return colors; |
| } |
| |
| void BrowserThemePackTest::VerifyColorMap( |
| const std::map<int, SkColor>& color_map) { |
| for (auto it = color_map.begin(); it != color_map.end(); ++it) { |
| SkColor color; |
| if (!theme_pack_->GetColor(it->first, &color)) { |
| color = GetDefaultColor(it->first); |
| } |
| EXPECT_EQ(it->second, color) << "Color id = " << it->first; |
| } |
| } |
| |
| void BrowserThemePackTest::LoadColorJSON(const std::string& json) { |
| LoadColorDictionary( |
| &base::JSONReader::Read(json, base::JSON_PARSE_CHROMIUM_EXTENSIONS) |
| ->GetDict()); |
| } |
| |
| void BrowserThemePackTest::LoadColorDictionary(const base::Value::Dict* value) { |
| theme_pack_->SetColorsFromJSON(value); |
| theme_pack_->GenerateFrameColorsFromTints(); |
| } |
| |
| void BrowserThemePackTest::LoadTintJSON(const std::string& json) { |
| LoadTintDictionary( |
| &base::JSONReader::Read(json, base::JSON_PARSE_CHROMIUM_EXTENSIONS) |
| ->GetDict()); |
| } |
| |
| void BrowserThemePackTest::LoadTintDictionary(const base::Value::Dict* value) { |
| theme_pack_->SetTintsFromJSON(value); |
| } |
| |
| void BrowserThemePackTest::LoadDisplayPropertiesJSON(const std::string& json) { |
| LoadDisplayPropertiesDictionary( |
| &base::JSONReader::Read(json, base::JSON_PARSE_CHROMIUM_EXTENSIONS) |
| ->GetDict()); |
| } |
| |
| void BrowserThemePackTest::LoadDisplayPropertiesDictionary( |
| const base::Value::Dict* value) { |
| theme_pack_->SetDisplayPropertiesFromJSON(value); |
| } |
| |
| void BrowserThemePackTest::ParseThemeImages( |
| const extensions::ThemeInfo::ThemeImages* value, |
| TestFilePathMap* out_file_paths) { |
| theme_pack_->ParseImageNamesFromJSON(value, base::FilePath(), out_file_paths); |
| |
| // Build the source image list for HasCustomImage(). |
| theme_pack_->BuildSourceImagesArray(*out_file_paths); |
| } |
| |
| void BrowserThemePackTest::ResetTabGroupColorPaletteShades() { |
| theme_pack_->tab_group_color_palette_shades_ = |
| std::array<BrowserThemePack::TabGroupColorPaletteShadesPair, |
| BrowserThemePack::kTabGroupColorPaletteLength>{}; |
| } |
| |
| void BrowserThemePackTest::LoadTabGroupColorPaletteShadesJSON( |
| const std::string& json) { |
| LoadTabGroupColorPaletteShadesDictionary( |
| &base::JSONReader::Read(json, base::JSON_PARSE_CHROMIUM_EXTENSIONS) |
| ->GetDict()); |
| } |
| |
| void BrowserThemePackTest::LoadTabGroupColorPaletteShadesDictionary( |
| const base::Value::Dict* value) { |
| theme_pack_->SetTabGroupColorPaletteShadesFromJSON(value); |
| } |
| |
| void BrowserThemePackTest::VerifyTabGroupColorPaletteShades() { |
| const std::array<BrowserThemePack::TabGroupColorPaletteShadesPair, |
| BrowserThemePack::kTabGroupColorPaletteLength>& |
| tab_group_color_palette_shades = |
| theme_pack_->tab_group_color_palette_shades_; |
| |
| std::array<BrowserThemePack::TabGroupColorPaletteShadesPair, |
| BrowserThemePack::kTabGroupColorPaletteLength> |
| expected_tab_group_color_palette_shades{}; |
| |
| expected_tab_group_color_palette_shades[0].id = |
| static_cast<int>(tab_groups::TabGroupColorId::kRed); |
| |
| // Expected standard shades for hue = 40 |
| constexpr std::array<SkColor, ui::kGeneratedShadesCount> kExpectedShades = { |
| SkColorSetRGB(0xFF, 0xED, 0xE7), // Shade 50 |
| SkColorSetRGB(0xFF, 0xDC, 0xD0), // Shade 100 |
| SkColorSetRGB(0xFF, 0xC1, 0xAA), // Shade 200 |
| SkColorSetRGB(0xFF, 0xA6, 0x83), // Shade 300 |
| SkColorSetRGB(0xFF, 0x87, 0x56), // Shade 400 |
| SkColorSetRGB(0xFA, 0x6E, 0x2F), // Shade 500 |
| SkColorSetRGB(0xE4, 0x5F, 0x20), // Shade 600 |
| SkColorSetRGB(0xCB, 0x52, 0x19), // Shade 700 |
| SkColorSetRGB(0xB3, 0x46, 0x11), // Shade 800 |
| SkColorSetRGB(0x9F, 0x3D, 0x0E), // Shade 900 |
| SkColorSetRGB(0x5A, 0x3D, 0x32), // Shade 1000 |
| }; |
| |
| std::copy(kExpectedShades.begin(), kExpectedShades.end(), |
| expected_tab_group_color_palette_shades[0].shades.begin()); |
| |
| for (size_t i = 0; i < BrowserThemePack::kTabGroupColorPaletteLength; ++i) { |
| const auto& actual = tab_group_color_palette_shades[i]; |
| const auto& expected = expected_tab_group_color_palette_shades[i]; |
| |
| EXPECT_EQ(actual.id, expected.id) << "Mismatch at index " << i << " for ID"; |
| |
| for (size_t j = 0; j < ui::kGeneratedShadesCount; ++j) { |
| EXPECT_EQ(actual.shades[j], expected.shades[j]) |
| << "Mismatch at index " << i << " shade " << j; |
| } |
| } |
| } |
| |
| bool BrowserThemePackTest::LoadRawBitmapsTo( |
| const TestFilePathMap& out_file_paths) { |
| return theme_pack_->LoadRawBitmapsTo(out_file_paths, &theme_pack_->images_); |
| } |
| |
| // static |
| void BrowserThemePackTest::BuildFromUnpackedExtension( |
| const base::FilePath& extension_path, |
| BrowserThemePack* pack) { |
| base::FilePath manifest_path = extension_path.AppendASCII("manifest.json"); |
| std::string error; |
| JSONFileValueDeserializer deserializer(manifest_path); |
| std::unique_ptr<base::Value> valid_value = |
| deserializer.Deserialize(nullptr, &error); |
| EXPECT_EQ("", error); |
| ASSERT_TRUE(valid_value.get() && valid_value->is_dict()); |
| std::u16string utf16_error; |
| scoped_refptr<Extension> extension(Extension::Create( |
| extension_path, extensions::mojom::ManifestLocation::kInvalidLocation, |
| valid_value->GetDict(), Extension::NO_FLAGS, &utf16_error)); |
| ASSERT_TRUE(extension.get()); |
| ASSERT_EQ(u"", utf16_error); |
| BrowserThemePack::BuildFromExtension(extension.get(), pack); |
| } |
| |
| // static |
| void BrowserThemePackTest::BuildFromUnpackedExtensionCheckValid( |
| const base::FilePath& extension_path, |
| BrowserThemePack* pack) { |
| BuildFromUnpackedExtension(extension_path, pack); |
| ASSERT_TRUE(pack->is_valid()); |
| } |
| |
| // static |
| void BrowserThemePackTest::BuildTestExtensionThemeCheckValid( |
| std::string_view theme_folder, |
| BrowserThemePack* pack) { |
| base::FilePath contrast_theme_path = GetTestExtensionThemePath(theme_folder); |
| BuildFromUnpackedExtensionCheckValid(contrast_theme_path, pack); |
| } |
| |
| // static |
| base::FilePath BrowserThemePackTest::GetTestExtensionThemePath( |
| std::string_view theme_folder) { |
| base::FilePath test_path; |
| const bool result = base::PathService::Get(chrome::DIR_TEST_DATA, &test_path); |
| DCHECK(result); |
| |
| test_path = test_path.AppendASCII("extensions"); |
| test_path = test_path.AppendASCII(theme_folder); |
| return base::FilePath(test_path); |
| } |
| |
| // static |
| base::FilePath BrowserThemePackTest::GetStarGazingPath() { |
| base::FilePath test_path; |
| const bool result = base::PathService::Get(chrome::DIR_TEST_DATA, &test_path); |
| DCHECK(result); |
| |
| test_path = test_path.AppendASCII("profiles"); |
| test_path = test_path.AppendASCII("profile_with_complex_theme"); |
| test_path = test_path.AppendASCII("Default"); |
| test_path = test_path.AppendASCII("Extensions"); |
| test_path = test_path.AppendASCII("mblmlcbknbnfebdfjnolmcapmdofhmme"); |
| test_path = test_path.AppendASCII("1.1"); |
| return base::FilePath(test_path); |
| } |
| |
| // static |
| base::FilePath BrowserThemePackTest::GetHiDpiThemePath() { |
| base::FilePath test_path; |
| const bool result = base::PathService::Get(chrome::DIR_TEST_DATA, &test_path); |
| DCHECK(result); |
| |
| test_path = test_path.AppendASCII("extensions"); |
| test_path = test_path.AppendASCII("theme_hidpi"); |
| return base::FilePath(test_path); |
| } |
| |
| // static |
| void BrowserThemePackTest::VerifyStarGazing(BrowserThemePack* pack) { |
| // First check that values we know exist, exist. |
| SkColor color; |
| EXPECT_TRUE(pack->GetColor(TP::COLOR_BOOKMARK_TEXT, &color)); |
| EXPECT_EQ(SK_ColorBLACK, color); |
| |
| EXPECT_TRUE(pack->GetColor(TP::COLOR_NTP_BACKGROUND, &color)); |
| EXPECT_EQ(SkColorSetRGB(57, 137, 194), color); |
| |
| color_utils::HSL expected = {0.6, 0.553, 0.5}; |
| color_utils::HSL actual; |
| EXPECT_TRUE(pack->GetTint(TP::TINT_BUTTONS, &actual)); |
| EXPECT_DOUBLE_EQ(expected.h, actual.h); |
| EXPECT_DOUBLE_EQ(expected.s, actual.s); |
| EXPECT_DOUBLE_EQ(expected.l, actual.l); |
| |
| int val; |
| EXPECT_TRUE(pack->GetDisplayProperty(TP::NTP_BACKGROUND_ALIGNMENT, &val)); |
| EXPECT_EQ(TP::ALIGN_TOP, val); |
| |
| // The stargazing theme defines the following images: |
| EXPECT_TRUE(pack->HasCustomImage(IDR_THEME_BUTTON_BACKGROUND)); |
| EXPECT_TRUE(pack->HasCustomImage(IDR_THEME_FRAME)); |
| EXPECT_TRUE(pack->HasCustomImage(IDR_THEME_NTP_BACKGROUND)); |
| EXPECT_TRUE(pack->HasCustomImage(IDR_THEME_TAB_BACKGROUND)); |
| EXPECT_TRUE(pack->HasCustomImage(IDR_THEME_TOOLBAR)); |
| EXPECT_TRUE(pack->HasCustomImage(IDR_THEME_WINDOW_CONTROL_BACKGROUND)); |
| |
| // Here are a few images that we shouldn't expect because even though |
| // they're included in the theme pack, they were autogenerated and |
| // therefore shouldn't show up when calling HasCustomImage(). |
| // Verify they do appear when calling GetImageNamed(), though. |
| EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_FRAME_INACTIVE)); |
| EXPECT_FALSE(pack->GetImageNamed(IDR_THEME_FRAME_INACTIVE).IsEmpty()); |
| EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_FRAME_INCOGNITO)); |
| EXPECT_FALSE(pack->GetImageNamed(IDR_THEME_FRAME_INCOGNITO).IsEmpty()); |
| EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_FRAME_INCOGNITO_INACTIVE)); |
| EXPECT_FALSE( |
| pack->GetImageNamed(IDR_THEME_FRAME_INCOGNITO_INACTIVE).IsEmpty()); |
| |
| // The overlay images are missing and they do not fall back to the active |
| // frame image. |
| EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_FRAME_OVERLAY)); |
| EXPECT_TRUE(pack->GetImageNamed(IDR_THEME_FRAME_OVERLAY).IsEmpty()); |
| EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_FRAME_OVERLAY_INACTIVE)); |
| EXPECT_TRUE(pack->GetImageNamed(IDR_THEME_FRAME_OVERLAY_INACTIVE).IsEmpty()); |
| |
| // The incognito and inactive tab background images are missing, but will |
| // still be generated in CreateTabBackgroundImages based on the frame |
| // images. |
| EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_TAB_BACKGROUND_INACTIVE)); |
| EXPECT_FALSE( |
| pack->GetImageNamed(IDR_THEME_TAB_BACKGROUND_INACTIVE).IsEmpty()); |
| EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_TAB_BACKGROUND_INCOGNITO)); |
| EXPECT_FALSE( |
| pack->GetImageNamed(IDR_THEME_TAB_BACKGROUND_INCOGNITO).IsEmpty()); |
| EXPECT_FALSE( |
| pack->HasCustomImage(IDR_THEME_TAB_BACKGROUND_INCOGNITO_INACTIVE)); |
| EXPECT_FALSE(pack->GetImageNamed(IDR_THEME_TAB_BACKGROUND_INCOGNITO_INACTIVE) |
| .IsEmpty()); |
| |
| // Make sure we don't have phantom data. |
| EXPECT_FALSE(pack->GetTint(TP::TINT_FRAME, &actual)); |
| } |
| |
| // static |
| void BrowserThemePackTest::VerifyHiDpiTheme(BrowserThemePack* pack) { |
| // The high DPI theme defines the following images: |
| EXPECT_TRUE(pack->HasCustomImage(IDR_THEME_FRAME)); |
| EXPECT_TRUE(pack->HasCustomImage(IDR_THEME_FRAME_INACTIVE)); |
| EXPECT_TRUE(pack->HasCustomImage(IDR_THEME_FRAME_INCOGNITO)); |
| EXPECT_TRUE(pack->HasCustomImage(IDR_THEME_FRAME_INCOGNITO_INACTIVE)); |
| EXPECT_TRUE(pack->HasCustomImage(IDR_THEME_TOOLBAR)); |
| |
| // The high DPI theme does not define the following images: |
| EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_TAB_BACKGROUND)); |
| #if !BUILDFLAG(IS_MAC) |
| EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_TAB_BACKGROUND_INCOGNITO)); |
| #endif |
| EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_NTP_BACKGROUND)); |
| EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_FRAME_OVERLAY)); |
| EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_FRAME_OVERLAY_INACTIVE)); |
| EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_BUTTON_BACKGROUND)); |
| EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_NTP_ATTRIBUTION)); |
| EXPECT_FALSE(pack->HasCustomImage(IDR_THEME_WINDOW_CONTROL_BACKGROUND)); |
| |
| // Compare some known pixel colors at know locations for a theme |
| // image where two different PNG files were specified for scales 100% |
| // and 200% respectively. |
| int idr = IDR_THEME_FRAME; |
| gfx::Image image = pack->GetImageNamed(idr); |
| EXPECT_FALSE(image.IsEmpty()); |
| const gfx::ImageSkia* image_skia = image.ToImageSkia(); |
| ASSERT_TRUE(image_skia); |
| // Scale 100%. |
| const gfx::ImageSkiaRep& rep1 = image_skia->GetRepresentation(1.0f); |
| ASSERT_FALSE(rep1.is_null()); |
| EXPECT_EQ(80, rep1.GetBitmap().width()); |
| // Bitmap height will be cropped at 60 - kTallestTabHeight + 19. |
| EXPECT_EQ(60, rep1.GetBitmap().height()); |
| EXPECT_EQ(SkColorSetRGB(255, 255, 255), rep1.GetBitmap().getColor(4, 4)); |
| EXPECT_EQ(SkColorSetRGB(255, 255, 255), rep1.GetBitmap().getColor(8, 8)); |
| EXPECT_EQ(SkColorSetRGB(0, 241, 237), rep1.GetBitmap().getColor(16, 16)); |
| EXPECT_EQ(SkColorSetRGB(255, 255, 255), rep1.GetBitmap().getColor(24, 24)); |
| EXPECT_EQ(SkColorSetRGB(0, 241, 237), rep1.GetBitmap().getColor(32, 32)); |
| // Scale 200%. |
| const gfx::ImageSkiaRep& rep2 = image_skia->GetRepresentation(2.0f); |
| ASSERT_FALSE(rep2.is_null()); |
| EXPECT_EQ(160, rep2.GetBitmap().width()); |
| // Cropped height will be 2 * 60. |
| EXPECT_EQ(120, rep2.GetBitmap().height()); |
| EXPECT_EQ(SkColorSetRGB(255, 255, 255), rep2.GetBitmap().getColor(4, 4)); |
| EXPECT_EQ(SkColorSetRGB(223, 42, 0), rep2.GetBitmap().getColor(8, 8)); |
| EXPECT_EQ(SkColorSetRGB(223, 42, 0), rep2.GetBitmap().getColor(16, 16)); |
| EXPECT_EQ(SkColorSetRGB(223, 42, 0), rep2.GetBitmap().getColor(24, 24)); |
| EXPECT_EQ(SkColorSetRGB(255, 255, 255), rep2.GetBitmap().getColor(32, 32)); |
| |
| // TODO(sschmitz): I plan to remove the following (to the end of the fct) |
| // Reason: this test may be brittle. It depends on details of how we scale |
| // an 100% image to an 200% image. If there's filtering etc, this test would |
| // break. Also High DPI is new, but scaling from 100% to 200% is not new |
| // and need not be tested here. But in the interrim it is useful to verify |
| // that this image was scaled and did not appear in the input. |
| |
| // Compare pixel colors and locations for a theme image that had |
| // only one PNG file specified (for scale 100%). The representation |
| // for scale of 200% was computed. |
| idr = IDR_THEME_FRAME_INCOGNITO_INACTIVE; |
| image = pack->GetImageNamed(idr); |
| EXPECT_FALSE(image.IsEmpty()); |
| image_skia = image.ToImageSkia(); |
| ASSERT_TRUE(image_skia); |
| // Scale 100%. |
| const gfx::ImageSkiaRep& rep3 = image_skia->GetRepresentation(1.0f); |
| ASSERT_FALSE(rep3.is_null()); |
| EXPECT_EQ(80, rep3.GetBitmap().width()); |
| // Bitmap height will be cropped at 60 - kTallestTabHeight + 19. |
| EXPECT_EQ(60, rep3.GetBitmap().height()); |
| // We take samples of colors and locations along the diagonal whenever |
| // the color changes. Note these colors are slightly different from |
| // the input PNG file due to input processing. |
| std::vector<std::pair<int, SkColor>> normal; |
| int xy = 0; |
| SkColor color = rep3.GetBitmap().getColor(xy, xy); |
| normal.emplace_back(xy, color); |
| for (xy = 0; xy < 40; ++xy) { |
| SkColor next_color = rep3.GetBitmap().getColor(xy, xy); |
| if (next_color != color) { |
| color = next_color; |
| normal.emplace_back(xy, color); |
| } |
| } |
| EXPECT_EQ(static_cast<size_t>(9), normal.size()); |
| // Scale 200%. |
| const gfx::ImageSkiaRep& rep4 = image_skia->GetRepresentation(2.0f); |
| ASSERT_FALSE(rep4.is_null()); |
| EXPECT_EQ(160, rep4.GetBitmap().width()); |
| // Cropped height will be 2 * 60. |
| EXPECT_EQ(120, rep4.GetBitmap().height()); |
| // We expect the same colors and at locations scaled by 2 |
| // since this bitmap was scaled by 2. |
| for (auto& i : normal) { |
| xy = 2 * i.first; |
| color = i.second; |
| EXPECT_EQ(color, rep4.GetBitmap().getColor(xy, xy)); |
| } |
| } |
| |
| // static |
| void BrowserThemePackTest::VerifyColorsMatch(BrowserThemePack* pack, |
| int color_id_a, |
| int color_id_b) { |
| SkColor color_a; |
| SkColor color_b; |
| |
| bool color_a_set = pack->GetColor(color_id_a, &color_a); |
| bool color_b_set = pack->GetColor(color_id_b, &color_b); |
| |
| SCOPED_TRACE(testing::Message() |
| << "Color A: " << std::hex << color_a << " (ID: " << std::dec |
| << color_id_a << "), Color B: " << std::hex << color_b |
| << " (ID: " << std::dec << color_id_b << ")"); |
| EXPECT_TRUE(color_a_set); |
| EXPECT_TRUE(color_b_set); |
| EXPECT_EQ(color_a, color_b); |
| } |
| |
| // static |
| void BrowserThemePackTest::VerifyCalculatedColorContrast( |
| base::span<const SkColor> colors, |
| int spanification_suspected_redundant_colors_num, |
| float contrast_ratio) { |
| // TODO(crbug.com/431824301): Remove unneeded parameter once validated to be |
| // redundant in M143. |
| CHECK(base::checked_cast<size_t>( |
| spanification_suspected_redundant_colors_num) == colors.size(), |
| base::NotFatalUntil::M143); |
| for (int i = 0; i < spanification_suspected_redundant_colors_num; i++) { |
| SkColor color = colors[i]; |
| scoped_refptr<BrowserThemePack> pack( |
| new BrowserThemePack(ThemeType::kAutogenerated)); |
| BrowserThemePack::BuildFromColor(color, pack.get()); |
| |
| SkColor frame_color, toolbar_color; |
| EXPECT_TRUE(pack->GetColor(TP::COLOR_FRAME_ACTIVE, &frame_color)); |
| EXPECT_TRUE(pack->GetColor(TP::COLOR_TOOLBAR, &toolbar_color)); |
| EXPECT_GE(color_utils::GetContrastRatio(frame_color, toolbar_color), |
| contrast_ratio); |
| } |
| } |
| |
| // static |
| SkColor BrowserThemePackTest::BuildThirdOpacity(SkColor color_link) { |
| return SkColorSetA(color_link, SkColorGetA(color_link) / 3); |
| } |
| |
| // static |
| SkColor BrowserThemePackTest::GetDefaultColor(int id) { |
| // These colors are no longer provided by `ThemeProperties`, since the theme |
| // code does not query for them directly. |
| if (id == TP::COLOR_BOOKMARK_TEXT || id == TP::COLOR_OMNIBOX_BACKGROUND || |
| id == TP::COLOR_OMNIBOX_TEXT || |
| id == TP::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_ACTIVE || |
| id == TP::COLOR_TOOLBAR_BUTTON_ICON) { |
| return gfx::kPlaceholderColor; |
| } |
| |
| // Direct incognito IDs need to be mapped back to the non-incognito versions |
| // (plus passing "true" for |incognito|) to avoid DCHECK failures. |
| switch (id) { |
| case TP::COLOR_FRAME_ACTIVE_INCOGNITO: |
| return TP::GetDefaultColor(TP::COLOR_FRAME_ACTIVE, true); |
| case TP::COLOR_FRAME_INACTIVE_INCOGNITO: |
| return TP::GetDefaultColor(TP::COLOR_FRAME_INACTIVE, true); |
| case TP::COLOR_TAB_BACKGROUND_INACTIVE_FRAME_ACTIVE_INCOGNITO: |
| return TP::GetDefaultColor(TP::COLOR_TAB_BACKGROUND_INACTIVE_FRAME_ACTIVE, |
| true); |
| case TP::COLOR_TAB_BACKGROUND_INACTIVE_FRAME_INACTIVE_INCOGNITO: |
| return TP::GetDefaultColor( |
| TP::COLOR_TAB_BACKGROUND_INACTIVE_FRAME_INACTIVE, true); |
| case TP::COLOR_TAB_FOREGROUND_INACTIVE_FRAME_ACTIVE_INCOGNITO: |
| return TP::GetDefaultColor(TP::COLOR_TAB_FOREGROUND_INACTIVE_FRAME_ACTIVE, |
| true); |
| case TP::COLOR_TAB_FOREGROUND_INACTIVE_FRAME_INACTIVE_INCOGNITO: |
| return TP::GetDefaultColor( |
| TP::COLOR_TAB_FOREGROUND_INACTIVE_FRAME_INACTIVE, true); |
| default: |
| return TP::GetDefaultColor(id, false); |
| } |
| } |
| |
| // static |
| void BrowserThemePackTest::GenerateDefaultFrameColor( |
| std::map<int, SkColor>* colors, |
| int color, |
| int tint, |
| bool otr) { |
| (*colors)[color] = HSLShift(GetDefaultColor(TP::COLOR_FRAME_ACTIVE), |
| TP::GetDefaultTint(tint, otr)); |
| } |
| |
| // Actual tests ---------------------------------------------------------------- |
| |
| // 'ntp_section' used to correspond to COLOR_NTP_SECTION, but COLOR_NTP_SECTION |
| // was since removed because it was never used. While it was in use, |
| // COLOR_NTP_HEADER used 'ntp_section' as a fallback when 'ntp_header' was |
| // absent. We still preserve this fallback for themes that relied on this. |
| TEST_F(BrowserThemePackTest, UseSectionColorAsNTPHeader) { |
| std::string color_json = "{ \"ntp_section\": [190, 190, 190] }"; |
| LoadColorJSON(color_json); |
| |
| std::map<int, SkColor> colors = GetDefaultColorMap(); |
| SkColor ntp_color = SkColorSetRGB(190, 190, 190); |
| colors[TP::COLOR_NTP_HEADER] = ntp_color; |
| VerifyColorMap(colors); |
| } |
| |
| TEST_F(BrowserThemePackTest, ProvideNtpHeaderColor) { |
| std::string color_json = |
| "{ \"ntp_header\": [120, 120, 120], " |
| " \"ntp_section\": [190, 190, 190] }"; |
| LoadColorJSON(color_json); |
| |
| std::map<int, SkColor> colors = GetDefaultColorMap(); |
| colors[TP::COLOR_NTP_HEADER] = SkColorSetRGB(120, 120, 120); |
| VerifyColorMap(colors); |
| } |
| |
| TEST_F(BrowserThemePackTest, SupportsAlpha) { |
| std::string color_json = |
| "{ \"toolbar\": [0, 20, 40, 1], " |
| " \"tab_text\": [60, 80, 100, 1], " |
| " \"tab_background_text\": [120, 140, 160, 0.0], " |
| " \"bookmark_text\": [180, 200, 220, 1.0], " |
| " \"ntp_text\": [240, 255, 0, 0.5] }"; |
| LoadColorJSON(color_json); |
| |
| std::map<int, SkColor> colors = GetDefaultColorMap(); |
| // Verify that valid alpha values are parsed correctly. |
| // The toolbar color's alpha value is intentionally ignored by theme provider. |
| colors[TP::COLOR_TOOLBAR] = SkColorSetARGB(255, 0, 20, 40); |
| colors[TP::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_ACTIVE] = |
| SkColorSetARGB(255, 60, 80, 100); |
| colors[TP::COLOR_TAB_FOREGROUND_INACTIVE_FRAME_ACTIVE] = |
| SkColorSetARGB(0, 120, 140, 160); |
| colors[TP::COLOR_BOOKMARK_TEXT] = SkColorSetARGB(255, 180, 200, 220); |
| colors[TP::COLOR_NTP_TEXT] = SkColorSetARGB(128, 240, 255, 0); |
| VerifyColorMap(colors); |
| } |
| |
| TEST_F(BrowserThemePackTest, OutOfRangeColors) { |
| // Ensure colors with out-of-range values are simply ignored. |
| std::string color_json = |
| "{ \"toolbar\": [0, 20, 40, -1], " |
| " \"tab_text\": [60, 80, 100, 2], " |
| " \"tab_background_text\": [120, 140, 160, 47.6], " |
| " \"bookmark_text\": [256, 0, 0], " |
| " \"ntp_text\": [0, -100, 100] }"; |
| LoadColorJSON(color_json); |
| |
| VerifyColorMap(GetDefaultColorMap()); |
| } |
| |
| TEST_F(BrowserThemePackTest, CanReadTints) { |
| std::string tint_json = "{ \"buttons\": [ 0.5, 0.5, 0.5 ] }"; |
| LoadTintJSON(tint_json); |
| |
| color_utils::HSL expected = {0.5, 0.5, 0.5}; |
| color_utils::HSL actual = {-1, -1, -1}; |
| EXPECT_TRUE(theme_pack().GetTint(TP::TINT_BUTTONS, &actual)); |
| EXPECT_DOUBLE_EQ(expected.h, actual.h); |
| EXPECT_DOUBLE_EQ(expected.s, actual.s); |
| EXPECT_DOUBLE_EQ(expected.l, actual.l); |
| } |
| |
| TEST_F(BrowserThemePackTest, CanReadDisplayProperties) { |
| std::string json = |
| "{ \"ntp_background_alignment\": \"bottom\", " |
| " \"ntp_background_repeat\": \"repeat-x\", " |
| " \"ntp_logo_alternate\": 0 }"; |
| LoadDisplayPropertiesJSON(json); |
| |
| int out_val; |
| EXPECT_TRUE( |
| theme_pack().GetDisplayProperty(TP::NTP_BACKGROUND_ALIGNMENT, &out_val)); |
| EXPECT_EQ(TP::ALIGN_BOTTOM, out_val); |
| |
| EXPECT_TRUE( |
| theme_pack().GetDisplayProperty(TP::NTP_BACKGROUND_TILING, &out_val)); |
| EXPECT_EQ(TP::REPEAT_X, out_val); |
| |
| EXPECT_TRUE( |
| theme_pack().GetDisplayProperty(TP::NTP_LOGO_ALTERNATE, &out_val)); |
| EXPECT_EQ(0, out_val); |
| } |
| |
| TEST_F(BrowserThemePackTest, CanParsePaths) { |
| extensions::ThemeInfo::ThemeImages theme_images{ |
| {"theme_button_background", {ThemeResourceFromRelativePath("one")}}, |
| {"theme_toolbar", {ThemeResourceFromRelativePath("two", "200")}}, |
| }; |
| TestFilePathMap out_file_paths; |
| ParseThemeImages(&theme_images, &out_file_paths); |
| |
| size_t expected_file_paths = 2u; |
| EXPECT_EQ(expected_file_paths, out_file_paths.size()); |
| // "12" and "5" are internal constants to BrowserThemePack and are |
| // PRS_THEME_BUTTON_BACKGROUND and PRS_THEME_TOOLBAR, but they are |
| // implementation details that shouldn't be exported. |
| // By default the scale factor is for 100%. |
| EXPECT_TRUE(base::FilePath(FILE_PATH_LITERAL("one")) == |
| out_file_paths[static_cast<BrowserThemePack::PersistentID>(12)] |
| [ui::k100Percent]); |
| EXPECT_TRUE(base::FilePath(FILE_PATH_LITERAL("two")) == |
| out_file_paths[static_cast<BrowserThemePack::PersistentID>(5)] |
| [ui::k200Percent]); |
| } |
| |
| TEST_F(BrowserThemePackTest, InvalidPathNames) { |
| extensions::ThemeInfo::ThemeImages theme_images{ |
| {"theme_button_background", {ThemeResourceFromRelativePath("one")}}, |
| {"not_a_thing", {ThemeResourceFromRelativePath("blah")}}, |
| }; |
| TestFilePathMap out_file_paths; |
| ParseThemeImages(&theme_images, &out_file_paths); |
| |
| // We should have only parsed one valid path out of that mess above. |
| EXPECT_EQ(1u, out_file_paths.size()); |
| } |
| |
| TEST_F(BrowserThemePackTest, InvalidColors) { |
| std::string invalid_color = |
| "{ \"toolbar\": [\"dog\", \"cat\", [12]], " |
| " \"sound\": \"woof\" }"; |
| LoadColorJSON(invalid_color); |
| std::map<int, SkColor> colors = GetDefaultColorMap(); |
| VerifyColorMap(colors); |
| } |
| |
| TEST_F(BrowserThemePackTest, InvalidTints) { |
| std::string tints = |
| "{ \"buttons\": [ \"dog\", \"cat\", [\"x\"]], " |
| " \"frame\": [-2, 2, 3]," |
| " \"frame_incognito_inactive\": [-1, 2, 0.6]," |
| " \"invalid\": \"entry\" }"; |
| LoadTintJSON(tints); |
| |
| // We should ignore completely invalid (non-numeric) tints. |
| color_utils::HSL actual = {-1, -1, -1}; |
| EXPECT_FALSE(theme_pack().GetTint(TP::TINT_BUTTONS, &actual)); |
| |
| // We should change invalid numeric HSL tint components to the special -1 "no |
| // change" value. |
| EXPECT_TRUE(theme_pack().GetTint(TP::TINT_FRAME, &actual)); |
| EXPECT_EQ(-1, actual.h); |
| EXPECT_EQ(-1, actual.s); |
| EXPECT_EQ(-1, actual.l); |
| |
| // We should correct partially incorrect inputs as well. |
| EXPECT_TRUE(theme_pack().GetTint(TP::TINT_FRAME_INCOGNITO_INACTIVE, &actual)); |
| EXPECT_EQ(-1, actual.h); |
| EXPECT_EQ(-1, actual.s); |
| EXPECT_EQ(0.6, actual.l); |
| } |
| |
| TEST_F(BrowserThemePackTest, InvalidDisplayProperties) { |
| std::string invalid_properties = |
| "{ \"ntp_background_alignment\": [15], " |
| " \"junk\": [15.3] }"; |
| LoadDisplayPropertiesJSON(invalid_properties); |
| |
| int out_val; |
| EXPECT_FALSE( |
| theme_pack().GetDisplayProperty(TP::NTP_BACKGROUND_ALIGNMENT, &out_val)); |
| } |
| |
| // These four tests should just not cause a segmentation fault. |
| TEST_F(BrowserThemePackTest, NullPaths) { |
| TestFilePathMap out_file_paths; |
| ParseThemeImages(nullptr, &out_file_paths); |
| } |
| |
| TEST_F(BrowserThemePackTest, NullTints) { |
| LoadTintDictionary(nullptr); |
| } |
| |
| TEST_F(BrowserThemePackTest, NullColors) { |
| LoadColorDictionary(nullptr); |
| } |
| |
| TEST_F(BrowserThemePackTest, NullDisplayProperties) { |
| LoadDisplayPropertiesDictionary(nullptr); |
| } |
| |
| TEST_F(BrowserThemePackTest, TestHasCustomImage) { |
| // HasCustomImage should only return true for images that exist in the |
| // extension and not for autogenerated images. |
| extensions::ThemeInfo::ThemeImages theme_images{ |
| {"theme_frame", {ThemeResourceFromRelativePath("one")}}, |
| }; |
| TestFilePathMap out_file_paths; |
| ParseThemeImages(&theme_images, &out_file_paths); |
| |
| EXPECT_TRUE(theme_pack().HasCustomImage(IDR_THEME_FRAME)); |
| EXPECT_FALSE(theme_pack().HasCustomImage(IDR_THEME_FRAME_INCOGNITO)); |
| } |
| |
| TEST_F(BrowserThemePackTest, TestNonExistantImages) { |
| extensions::ThemeInfo::ThemeImages theme_images{ |
| {"theme_frame", {ThemeResourceFromRelativePath("does_not_exist")}}, |
| }; |
| TestFilePathMap out_file_paths; |
| ParseThemeImages(&theme_images, &out_file_paths); |
| |
| EXPECT_FALSE(LoadRawBitmapsTo(out_file_paths)); |
| } |
| |
| TEST_F(BrowserThemePackTest, TestCreateColorMixersOmniboxAllValues) { |
| // Tests to make sure that all available colors are properly loaded into the |
| // color provider. |
| ui::ColorProvider provider; |
| ui::ColorMixer& mixer = provider.AddMixer(); |
| mixer[kColorToolbar] = {SK_ColorRED}; |
| mixer[kColorOmniboxText] = {SK_ColorGREEN}; |
| mixer[kColorToolbarBackgroundSubtleEmphasis] = {SK_ColorBLUE}; |
| std::string color_json = R"({ "toolbar": [0, 20, 40], |
| "omnibox_text": [60, 80, 100], |
| "omnibox_background": [120, 140, 160] })"; |
| LoadColorJSON(color_json); |
| theme_pack().AddColorMixers(&provider, ui::ColorProviderKey()); |
| EXPECT_EQ(SkColorSetRGB(0, 20, 40), provider.GetColor(kColorToolbar)); |
| EXPECT_EQ(SkColorSetRGB(60, 80, 100), provider.GetColor(kColorOmniboxText)); |
| EXPECT_EQ(SkColorSetRGB(120, 140, 160), |
| provider.GetColor(kColorToolbarBackgroundSubtleEmphasis)); |
| } |
| |
| // TODO(erg): This test should actually test more of the built resources from |
| // the extension data, but for now, exists so valgrind can test some of the |
| // tricky memory stuff that BrowserThemePack does. |
| TEST_F(BrowserThemePackTest, CanBuildAndReadPack) { |
| base::FilePath file = GetTemporaryPakFile(FILE_PATH_LITERAL("data.pak")); |
| ASSERT_FALSE(file.empty()); |
| |
| // Part 1: Build the pack from an extension. |
| { |
| base::FilePath star_gazing_path = GetStarGazingPath(); |
| scoped_refptr<BrowserThemePack> pack( |
| new BrowserThemePack(ThemeType::kExtension)); |
| BuildFromUnpackedExtensionCheckValid(star_gazing_path, pack.get()); |
| ASSERT_TRUE(pack->WriteToDisk(file)); |
| VerifyStarGazing(pack.get()); |
| } |
| |
| // Part 2: Try to read back the data pack that we just wrote to disk. |
| { |
| scoped_refptr<BrowserThemePack> pack = BrowserThemePack::BuildFromDataPack( |
| file, "mblmlcbknbnfebdfjnolmcapmdofhmme"); |
| ASSERT_TRUE(pack.get()); |
| VerifyStarGazing(pack.get()); |
| } |
| } |
| |
| TEST_F(BrowserThemePackTest, HiDpiThemeTest) { |
| base::FilePath file = |
| GetTemporaryPakFile(FILE_PATH_LITERAL("theme_data.pak")); |
| ASSERT_FALSE(file.empty()); |
| |
| // Part 1: Build the pack from an extension. |
| { |
| base::FilePath hidpi_path = GetHiDpiThemePath(); |
| scoped_refptr<BrowserThemePack> pack( |
| new BrowserThemePack(ThemeType::kExtension)); |
| BuildFromUnpackedExtensionCheckValid(hidpi_path, pack.get()); |
| ASSERT_TRUE(pack->WriteToDisk(file)); |
| VerifyHiDpiTheme(pack.get()); |
| } |
| |
| // Part 2: Try to read back the data pack that we just wrote to disk. |
| { |
| scoped_refptr<BrowserThemePack> pack = |
| BrowserThemePack::BuildFromDataPack(file, "gllekhaobjnhgeag"); |
| ASSERT_TRUE(pack.get()); |
| VerifyHiDpiTheme(pack.get()); |
| } |
| } |
| |
| // Ensure that, given a theme which only specifies a frame color, the calculated |
| // caption button background colors appropriately match the frame color. |
| TEST_F(BrowserThemePackTest, TestWindowControlButtonBGColor_FrameColor) { |
| scoped_refptr<BrowserThemePack> pack( |
| new BrowserThemePack(ThemeType::kExtension)); |
| BuildTestExtensionThemeCheckValid("theme_test_captionbutton_framecolor", |
| pack.get()); |
| |
| // Verify that control button background colors are matching the frame colors. |
| VerifyColorsMatch(pack.get(), |
| TP::COLOR_WINDOW_CONTROL_BUTTON_BACKGROUND_ACTIVE, |
| TP::COLOR_FRAME_ACTIVE); |
| VerifyColorsMatch(pack.get(), |
| TP::COLOR_WINDOW_CONTROL_BUTTON_BACKGROUND_INACTIVE, |
| TP::COLOR_FRAME_INACTIVE); |
| VerifyColorsMatch(pack.get(), |
| TP::COLOR_WINDOW_CONTROL_BUTTON_BACKGROUND_INCOGNITO_ACTIVE, |
| TP::COLOR_FRAME_ACTIVE_INCOGNITO); |
| VerifyColorsMatch( |
| pack.get(), TP::COLOR_WINDOW_CONTROL_BUTTON_BACKGROUND_INCOGNITO_INACTIVE, |
| TP::COLOR_FRAME_INACTIVE_INCOGNITO); |
| } |
| |
| // Ensure that, given a theme which specifies a button background color, the |
| // calculated caption button background colors appropriately match the button |
| // background color blended with the frame color. |
| TEST_F(BrowserThemePackTest, TestWindowControlButtonBGColor_ButtonBGColor) { |
| scoped_refptr<BrowserThemePack> pack( |
| new BrowserThemePack(ThemeType::kExtension)); |
| BuildTestExtensionThemeCheckValid("theme_test_captionbutton_buttoncolor", |
| pack.get()); |
| |
| SkColor button_bg_color; |
| const bool has_button_bg_color = |
| pack->GetColor(TP::COLOR_CONTROL_BUTTON_BACKGROUND, &button_bg_color); |
| ASSERT_TRUE(has_button_bg_color); |
| SkAlpha button_bg_alpha = SkColorGetA(button_bg_color); |
| |
| // Account for the alpha modification that happens in WindowsCaptionButton. |
| button_bg_alpha = |
| WindowFrameUtil::CalculateWindowsCaptionButtonBackgroundAlpha( |
| button_bg_alpha); |
| |
| struct CaptionButtonColorPair { |
| int caption_button_bg_color_id; |
| int frame_color_id; |
| }; |
| const CaptionButtonColorPair color_pairs_to_check[] = { |
| {TP::COLOR_WINDOW_CONTROL_BUTTON_BACKGROUND_ACTIVE, |
| TP::COLOR_FRAME_ACTIVE}, |
| {TP::COLOR_WINDOW_CONTROL_BUTTON_BACKGROUND_INACTIVE, |
| TP::COLOR_FRAME_INACTIVE}, |
| {TP::COLOR_WINDOW_CONTROL_BUTTON_BACKGROUND_INCOGNITO_ACTIVE, |
| TP::COLOR_FRAME_ACTIVE_INCOGNITO}, |
| {TP::COLOR_WINDOW_CONTROL_BUTTON_BACKGROUND_INCOGNITO_INACTIVE, |
| TP::COLOR_FRAME_INACTIVE_INCOGNITO}, |
| }; |
| |
| for (const CaptionButtonColorPair& current_pair : color_pairs_to_check) { |
| SkColor calculated_button_bg_color; |
| SkColor frame_color; |
| |
| pack->GetColor(current_pair.caption_button_bg_color_id, |
| &calculated_button_bg_color); |
| pack->GetColor(current_pair.frame_color_id, &frame_color); |
| |
| SkColor result_color = |
| color_utils::AlphaBlend(button_bg_color, frame_color, button_bg_alpha); |
| |
| EXPECT_EQ(calculated_button_bg_color, result_color); |
| } |
| } |
| |
| // Ensure that, given a theme which specifies a light frame color, but a dark |
| // caption button image, the calculated caption button background color is dark |
| // (to match the bg image). |
| TEST_F(BrowserThemePackTest, TestWindowControlButtonBGColor_ButtonBGImage) { |
| scoped_refptr<BrowserThemePack> pack( |
| new BrowserThemePack(ThemeType::kExtension)); |
| BuildTestExtensionThemeCheckValid("theme_test_captionbutton_buttonimage", |
| pack.get()); |
| |
| // Verify that all of the calculated button background colors are on the |
| // 'dark' end of the spectrum. |
| int colors_to_check[] = { |
| TP::COLOR_WINDOW_CONTROL_BUTTON_BACKGROUND_ACTIVE, |
| TP::COLOR_WINDOW_CONTROL_BUTTON_BACKGROUND_INACTIVE, |
| TP::COLOR_WINDOW_CONTROL_BUTTON_BACKGROUND_INCOGNITO_ACTIVE, |
| TP::COLOR_WINDOW_CONTROL_BUTTON_BACKGROUND_INCOGNITO_INACTIVE, |
| }; |
| for (int color_id : colors_to_check) { |
| SkColor control_button_color; |
| const bool has_color = pack->GetColor(color_id, &control_button_color); |
| EXPECT_TRUE(has_color); |
| EXPECT_EQ(SkColorGetA(control_button_color), SK_AlphaOPAQUE); |
| EXPECT_TRUE(color_utils::IsDark(control_button_color)); |
| } |
| } |
| |
| // Ensure that specified 'toolbar' button and foreground colors are propagated |
| // correctly to their dependent colors |
| TEST_F(BrowserThemePackTest, TestFrameAndToolbarColorPropagation) { |
| scoped_refptr<BrowserThemePack> pack( |
| new BrowserThemePack(ThemeType::kExtension)); |
| BuildTestExtensionThemeCheckValid("theme_test_toolbar_color_no_image", |
| pack.get()); |
| |
| // Toolbar button icon colors. |
| SkColor toolbar_button_icon_hovered_color; |
| SkColor toolbar_button_icon_pressed_color; |
| |
| EXPECT_TRUE(pack->GetColor(TP::COLOR_TOOLBAR_BUTTON_ICON_HOVERED, |
| &toolbar_button_icon_hovered_color)); |
| EXPECT_TRUE(pack->GetColor(TP::COLOR_TOOLBAR_BUTTON_ICON_PRESSED, |
| &toolbar_button_icon_pressed_color)); |
| |
| constexpr SkColor kExpectedToolbarButtonIconColor = SkColorSetRGB(0, 0, 255); |
| EXPECT_EQ(toolbar_button_icon_hovered_color, kExpectedToolbarButtonIconColor); |
| EXPECT_EQ(toolbar_button_icon_pressed_color, kExpectedToolbarButtonIconColor); |
| |
| // Active tab active frame foreground colors. |
| SkColor tab_foreground_color; |
| |
| EXPECT_TRUE(pack->GetColor(TP::COLOR_TAB_FOREGROUND_ACTIVE_FRAME_INACTIVE, |
| &tab_foreground_color)); |
| |
| constexpr SkColor kExpectedTabForegroundColor = SkColorSetRGB(255, 0, 0); |
| EXPECT_EQ(tab_foreground_color, kExpectedTabForegroundColor); |
| } |
| |
| // Ensure that, given an explicit toolbar color and a toolbar image, the output |
| // color in COLOR_TOOLBAR reflects the explicit color. |
| TEST_F(BrowserThemePackTest, |
| TestToolbarColorComputedFromImageOverridesInputColor) { |
| scoped_refptr<BrowserThemePack> pack( |
| new BrowserThemePack(ThemeType::kExtension)); |
| BuildTestExtensionThemeCheckValid( |
| "theme_test_toolbar_frame_images_and_colors", pack.get()); |
| |
| SkColor toolbar_color; |
| EXPECT_TRUE(pack->GetColor(TP::COLOR_TOOLBAR, &toolbar_color)); |
| |
| constexpr SkColor kExplicitColor = SkColorSetRGB(0, 255, 0); |
| EXPECT_EQ(toolbar_color, kExplicitColor); |
| } |
| |
| // Ensure that, given an explicit frame color and a frame image, the output |
| // color in COLOR_FRAME_ACTIVE reflects the explicit color. |
| TEST_F(BrowserThemePackTest, |
| TestFrameColorComputedFromImageOverridesInputColor) { |
| scoped_refptr<BrowserThemePack> pack( |
| new BrowserThemePack(ThemeType::kExtension)); |
| BuildTestExtensionThemeCheckValid( |
| "theme_test_toolbar_frame_images_and_colors", pack.get()); |
| |
| SkColor frame_color; |
| EXPECT_TRUE(pack->GetColor(TP::COLOR_FRAME_ACTIVE, &frame_color)); |
| |
| constexpr SkColor kExplicitColor = SkColorSetRGB(255, 0, 255); |
| EXPECT_EQ(frame_color, kExplicitColor); |
| } |
| |
| // Test theme generation for a given color. |
| TEST_F(BrowserThemePackTest, TestBuildFromColor) { |
| scoped_refptr<BrowserThemePack> pack( |
| new BrowserThemePack(ThemeType::kAutogenerated)); |
| SkColor color = SkColorSetRGB(100, 100, 200); |
| BrowserThemePack::BuildFromColor(color, pack.get()); |
| |
| SkColor frame_color; |
| EXPECT_TRUE(pack->GetColor(TP::COLOR_FRAME_ACTIVE, &frame_color)); |
| EXPECT_TRUE(pack->GetColor(TP::COLOR_TOOLBAR, &frame_color)); |
| EXPECT_TRUE(pack->GetColor(TP::COLOR_NTP_BACKGROUND, &frame_color)); |
| } |
| |
| TEST_F(BrowserThemePackTest, BuildFromColor_BasicTestColors) { |
| constexpr SkColor backgrounds[] = {SK_ColorBLACK, |
| SK_ColorWHITE, |
| SkColorSetRGB(50, 0, 50), |
| SkColorSetRGB(0, 130, 130), |
| SkColorSetRGB(0, 180, 180), |
| SkColorSetRGB(0, 200, 200), |
| SkColorSetRGB(120, 120, 120), |
| SkColorSetRGB(125, 125, 125), |
| SkColorSetRGB(128, 128, 128), |
| SkColorSetRGB(240, 255, 255)}; |
| auto has_readable_contrast = [](SkColor foreground_color, |
| SkColor background_color) { |
| return color_utils::GetContrastRatio(foreground_color, background_color) >= |
| kAutogeneratedThemeTextPreferredContrast; |
| }; |
| |
| for (SkColor color : backgrounds) { |
| scoped_refptr<BrowserThemePack> pack( |
| new BrowserThemePack(ThemeType::kAutogenerated)); |
| BrowserThemePack::BuildFromColor(color, pack.get()); |
| |
| SkColor frame_color, background_tab, background_tab_text; |
| EXPECT_TRUE(pack->GetColor(TP::COLOR_FRAME_ACTIVE, &frame_color)); |
| EXPECT_TRUE(pack->GetColor(TP::COLOR_TAB_BACKGROUND_INACTIVE_FRAME_ACTIVE, |
| &background_tab)); |
| EXPECT_TRUE(pack->GetColor(TP::COLOR_TAB_FOREGROUND_INACTIVE_FRAME_ACTIVE, |
| &background_tab_text)); |
| EXPECT_EQ(frame_color, background_tab); |
| EXPECT_TRUE(has_readable_contrast(background_tab_text, background_tab)); |
| |
| SkColor ntp_background, toolbar_color, toolbar_button_icon, toolbar_text; |
| EXPECT_TRUE(pack->GetColor(TP::COLOR_NTP_BACKGROUND, &ntp_background)); |
| EXPECT_TRUE(pack->GetColor(TP::COLOR_TOOLBAR, &toolbar_color)); |
| EXPECT_TRUE( |
| pack->GetColor(TP::COLOR_TOOLBAR_BUTTON_ICON, &toolbar_button_icon)); |
| EXPECT_TRUE(pack->GetColor(TP::COLOR_TOOLBAR_TEXT, &toolbar_text)); |
| |
| EXPECT_EQ(toolbar_color, ntp_background); |
| EXPECT_EQ(toolbar_text, toolbar_button_icon); |
| EXPECT_TRUE(has_readable_contrast(toolbar_text, toolbar_color)); |
| |
| EXPECT_NE(frame_color, toolbar_color); |
| EXPECT_GE(color_utils::GetContrastRatio(frame_color, toolbar_color), |
| kAutogeneratedThemeActiveTabMinContrast); |
| |
| int ntp_logo_alternate = 0; |
| pack->GetDisplayProperty(TP::NTP_LOGO_ALTERNATE, &ntp_logo_alternate); |
| int expected_logo = ntp_background == SK_ColorWHITE ? 0 : 1; |
| EXPECT_EQ(expected_logo, ntp_logo_alternate); |
| |
| color_utils::HSL hsl; |
| EXPECT_TRUE(pack->GetTint(TP::TINT_FRAME_INACTIVE, &hsl)); |
| EXPECT_EQ(-1, hsl.h); |
| EXPECT_EQ(-1, hsl.s); |
| EXPECT_EQ(-1, hsl.l); |
| |
| color_utils::HSL incognito_hsl; |
| EXPECT_TRUE( |
| pack->GetTint(TP::TINT_FRAME_INCOGNITO_INACTIVE, &incognito_hsl)); |
| EXPECT_EQ(-1, incognito_hsl.h); |
| EXPECT_EQ(-1, incognito_hsl.s); |
| EXPECT_EQ(-1, incognito_hsl.l); |
| } |
| } |
| |
| TEST_F(BrowserThemePackTest, BuildFromColor_TestAdjustedFrameColor) { |
| // Colors close to midpoint that don't have sufficient contrast with white or |
| // dark grey should be adjusted. |
| constexpr SkColor dark_backgrounds[] = {SkColorSetRGB(0, 130, 130), |
| SkColorSetRGB(120, 120, 120)}; |
| constexpr SkColor light_backgrounds[] = {SkColorSetRGB(0, 180, 180), |
| SkColorSetRGB(128, 128, 128)}; |
| |
| for (SkColor color : dark_backgrounds) { |
| scoped_refptr<BrowserThemePack> pack( |
| new BrowserThemePack(ThemeType::kAutogenerated)); |
| BrowserThemePack::BuildFromColor(color, pack.get()); |
| |
| SkColor frame_color; |
| EXPECT_TRUE(pack->GetColor(TP::COLOR_FRAME_ACTIVE, &frame_color)); |
| |
| // Dark backgrounds should get even darker. |
| EXPECT_GT(color_utils::GetRelativeLuminance(color), |
| color_utils::GetRelativeLuminance(frame_color)); |
| } |
| |
| for (SkColor color : light_backgrounds) { |
| scoped_refptr<BrowserThemePack> pack( |
| new BrowserThemePack(ThemeType::kAutogenerated)); |
| BrowserThemePack::BuildFromColor(color, pack.get()); |
| |
| SkColor frame_color; |
| EXPECT_TRUE(pack->GetColor(TP::COLOR_FRAME_ACTIVE, &frame_color)); |
| |
| // Light backgrounds should get even lighter. |
| EXPECT_LT(color_utils::GetRelativeLuminance(color), |
| color_utils::GetRelativeLuminance(frame_color)); |
| } |
| } |
| |
| // TODO(gayane): Consider moving color calculation tests to |
| // autogenerated_theme_util_unittest.cc. |
| TEST_F(BrowserThemePackTest, BuildFromColor_TestPreferredActiveTabContrast) { |
| constexpr SkColor dark_backgrounds[] = {SK_ColorBLACK, |
| SkColorSetRGB(0, 10, 17)}; |
| constexpr SkColor medium_backgrounds[] = {SkColorSetRGB(0, 130, 130), |
| SkColorSetRGB(120, 120, 120)}; |
| constexpr SkColor light_backgrounds[] = {SK_ColorWHITE, |
| SkColorSetRGB(240, 255, 255)}; |
| VerifyCalculatedColorContrast( |
| dark_backgrounds, 2, |
| kAutogeneratedThemeActiveTabPreferredContrastForDark); |
| VerifyCalculatedColorContrast(medium_backgrounds, 2, |
| kAutogeneratedThemeActiveTabPreferredContrast); |
| VerifyCalculatedColorContrast(light_backgrounds, 2, |
| kAutogeneratedThemeActiveTabMinContrast); |
| } |
| |
| TEST_F(BrowserThemePackTest, TestToolbarButtonColor) { |
| scoped_refptr<BrowserThemePack> pack( |
| new BrowserThemePack(ThemeType::kExtension)); |
| BuildTestExtensionThemeCheckValid("theme_test_toolbar_button_color", |
| pack.get()); |
| |
| SkColor button_color; |
| EXPECT_TRUE(pack->GetColor(TP::COLOR_TOOLBAR_BUTTON_ICON, &button_color)); |
| EXPECT_EQ(button_color, SkColorSetRGB(255, 0, 0)); |
| |
| color_utils::HSL hsl; |
| EXPECT_TRUE(pack->GetTint(TP::TINT_BUTTONS, &hsl)); |
| } |
| |
| TEST_F(BrowserThemePackTest, TestNtpTextCaclulation) { |
| // If ntp_text is not specified then it should be calculated based on NTP |
| // background image. |
| scoped_refptr<BrowserThemePack> pack( |
| new BrowserThemePack(ThemeType::kExtension)); |
| BuildTestExtensionThemeCheckValid("theme_ntp_background_image", pack.get()); |
| |
| SkColor ntp_text; |
| EXPECT_TRUE(pack->GetColor(TP::COLOR_NTP_TEXT, &ntp_text)); |
| |
| // If ntp_text is not specified then it should be calculated based on NTP |
| // background color. |
| scoped_refptr<BrowserThemePack> pack_autogenerated( |
| new BrowserThemePack(ThemeType::kAutogenerated)); |
| BrowserThemePack::BuildFromColor(SkColorSetRGB(0, 130, 130), |
| pack_autogenerated.get()); |
| |
| EXPECT_TRUE(pack_autogenerated->GetColor(TP::COLOR_NTP_TEXT, &ntp_text)); |
| } |
| |
| TEST_F(BrowserThemePackTest, TestLogoColors) { |
| // For themes with no background image and no background color, nothing should |
| // be specified. |
| scoped_refptr<BrowserThemePack> theme_minimal( |
| new BrowserThemePack(ThemeType::kExtension)); |
| BuildTestExtensionThemeCheckValid("theme_minimal", theme_minimal.get()); |
| SkColor color; |
| EXPECT_FALSE(theme_minimal->GetColor(TP::COLOR_NTP_LOGO, &color)); |
| |
| // For themes with image logo, colors shouldn't be set. |
| scoped_refptr<BrowserThemePack> theme_with_image( |
| new BrowserThemePack(ThemeType::kExtension)); |
| BuildTestExtensionThemeCheckValid("theme_ntp_background_image", |
| theme_with_image.get()); |
| EXPECT_FALSE(theme_with_image->GetColor(TP::COLOR_NTP_LOGO, &color)); |
| |
| // For themes with no image but with colorful logo, the logo color shouldn't |
| // be specified. |
| scoped_refptr<BrowserThemePack> theme_colorful_logo( |
| new BrowserThemePack(ThemeType::kExtension)); |
| BuildTestExtensionThemeCheckValid("theme_color_ntp_colorful_logo", |
| theme_colorful_logo.get()); |
| EXPECT_FALSE(theme_colorful_logo->GetColor(TP::COLOR_NTP_LOGO, &color)); |
| |
| // For themes with no image and with alternate logo, color should be set. |
| scoped_refptr<BrowserThemePack> theme_alternate_logo( |
| new BrowserThemePack(ThemeType::kExtension)); |
| BuildTestExtensionThemeCheckValid("theme_color_ntp_white_logo", |
| theme_alternate_logo.get()); |
| EXPECT_TRUE(theme_alternate_logo->GetColor(TP::COLOR_NTP_LOGO, &color)); |
| EXPECT_NE(SK_ColorWHITE, color); |
| |
| // For darker then midpoint themes the logo color should be white. |
| scoped_refptr<BrowserThemePack> dark_theme( |
| new BrowserThemePack(ThemeType::kAutogenerated)); |
| BrowserThemePack::BuildFromColor(SkColorSetRGB(120, 120, 120), |
| dark_theme.get()); |
| EXPECT_TRUE(dark_theme->GetColor(TP::COLOR_NTP_LOGO, &color)); |
| EXPECT_EQ(SK_ColorWHITE, color); |
| |
| // For themes with white NTP background the Logo color shouldn't be set |
| // because the colorful logo should be used on white background. |
| scoped_refptr<BrowserThemePack> white_theme( |
| new BrowserThemePack(ThemeType::kAutogenerated)); |
| BrowserThemePack::BuildFromColor(SK_ColorWHITE, white_theme.get()); |
| ASSERT_TRUE(white_theme->GetColor(TP::COLOR_NTP_BACKGROUND, &color)); |
| ASSERT_EQ(SK_ColorWHITE, color); |
| EXPECT_FALSE(white_theme->GetColor(TP::COLOR_NTP_LOGO, &color)); |
| } |
| |
| // Test that building a theme from an extension where "theme_ntp_background" |
| // points to a jpg does not crash. |
| TEST_F(BrowserThemePackTest, JpegNtpBackground) { |
| scoped_refptr<BrowserThemePack> theme( |
| new BrowserThemePack(ThemeType::kExtension)); |
| BuildFromUnpackedExtensionCheckValid( |
| GetTestExtensionThemePath("theme_jpeg_ntp_background"), theme.get()); |
| } |
| |
| // Test that building a theme from an extension where "theme_frame" points to a |
| // jpg fails. |
| TEST_F(BrowserThemePackTest, JpegThemeFrame) { |
| scoped_refptr<BrowserThemePack> theme( |
| new BrowserThemePack(ThemeType::kExtension)); |
| BuildFromUnpackedExtension( |
| GetTestExtensionThemePath("theme_jpeg_theme_frame"), theme.get()); |
| EXPECT_FALSE(theme->is_valid()); |
| } |
| |
| TEST_F(BrowserThemePackTest, SetTabGroupColorPaletteShadesFromJSONTest) { |
| ResetTabGroupColorPaletteShades(); |
| |
| std::string tab_group_color_palette_json = |
| // invalid key with valid value, will be ignored. |
| "{ \"invalid_key\": 23, " |
| // valid key with invalid value, will be ignored. |
| " \"grey_override\": 361, " |
| // valid key with valid value, will be translated. |
| " \"red_override\": 40 } "; |
| LoadTabGroupColorPaletteShadesJSON(tab_group_color_palette_json); |
| |
| VerifyTabGroupColorPaletteShades(); |
| |
| ResetTabGroupColorPaletteShades(); |
| } |
| |
| TEST_F(BrowserThemePackTest, TabGroupColorPaletteCustomizationTest) { |
| // Tests whether the Tab Group-specific colorIds are set correctly based on |
| // the background color and theme provided. |
| ui::ColorProvider provider; |
| ui::ColorMixer& mixer = provider.AddMixer(); |
| |
| // Randomly set the background colors that influence Tab Group-specific |
| // ColorIds. The selected shade depends on whether the background color is |
| // considered dark. |
| mixer[kColorTabBackgroundInactiveFrameActive] = {SkColorSetRGB(20, 20, 20)}; |
| mixer[kColorTabBackgroundInactiveFrameInactive] = {SkColorSetRGB(34, 34, 34)}; |
| mixer[ui::kColorMenuBackground] = {SkColorSetRGB(15, 23, 30)}; |
| mixer[kColorBookmarkBarBackground] = {SkColorSetRGB(255, 250, 200)}; |
| mixer[kColorThumbnailTabStripBackgroundActive] = { |
| SkColorSetRGB(220, 230, 240)}; |
| mixer[kColorThumbnailTabStripBackgroundInactive] = { |
| SkColorSetRGB(245, 245, 245)}; |
| |
| // Customizing the red Tab Group color using hue 40. |
| std::string tab_group_color_palette_json = R"({ "red_override": 40 })"; |
| LoadTabGroupColorPaletteShadesJSON(tab_group_color_palette_json); |
| theme_pack().AddColorMixers(&provider, ui::ColorProviderKey()); |
| |
| // Standard shades of hue 40. |
| constexpr std::array<SkColor, ui::kGeneratedShadesCount> shades = { |
| SkColorSetRGB(0xFF, 0xED, 0xE7), // Shade 50 |
| SkColorSetRGB(0xFF, 0xDC, 0xD0), // Shade 100 |
| SkColorSetRGB(0xFF, 0xC1, 0xAA), // Shade 200 |
| SkColorSetRGB(0xFF, 0xA6, 0x83), // Shade 300 |
| SkColorSetRGB(0xFF, 0x87, 0x56), // Shade 400 |
| SkColorSetRGB(0xFA, 0x6E, 0x2F), // Shade 500 |
| SkColorSetRGB(0xE4, 0x5F, 0x20), // Shade 600 |
| SkColorSetRGB(0xCB, 0x52, 0x19), // Shade 700 |
| SkColorSetRGB(0xB3, 0x46, 0x11), // Shade 800 |
| SkColorSetRGB(0x9F, 0x3D, 0x0E), // Shade 900 |
| SkColorSetRGB(0x5A, 0x3D, 0x32), // Shade 1000 |
| }; |
| |
| enum ShadeIndex { |
| k50, |
| k100, |
| k200, |
| k300, |
| k400, |
| k500, |
| k600, |
| k700, |
| k800, |
| k900, |
| k1000 |
| }; |
| |
| SkColor expected; |
| SkColor actual; |
| |
| // kColorTabGroupTabStripFrameActiveRed |
| expected = color_utils::IsDark( |
| provider.GetColor(kColorTabBackgroundInactiveFrameActive)) |
| ? shades[k300] |
| : shades[k600]; |
| actual = provider.GetColor(kColorTabGroupTabStripFrameActiveRed); |
| EXPECT_EQ(expected, actual); |
| |
| // kColorTabGroupTabStripFrameInactiveRed |
| expected = color_utils::IsDark( |
| provider.GetColor(kColorTabBackgroundInactiveFrameInactive)) |
| ? shades[k300] |
| : shades[k600]; |
| actual = provider.GetColor(kColorTabGroupTabStripFrameInactiveRed); |
| EXPECT_EQ(expected, actual); |
| |
| // kColorTabGroupDialogRed |
| expected = provider.GetColor(kColorTabGroupContextMenuRed); |
| actual = provider.GetColor(kColorTabGroupDialogRed); |
| EXPECT_EQ(expected, actual); |
| |
| // kColorTabGroupContextMenuRed |
| expected = color_utils::IsDark(provider.GetColor(ui::kColorMenuBackground)) |
| ? shades[k300] |
| : shades[k600]; |
| actual = provider.GetColor(kColorTabGroupContextMenuRed); |
| EXPECT_EQ(expected, actual); |
| |
| // kColorSavedTabGroupForegroundRed |
| expected = color_utils::IsDark(provider.GetColor(kColorBookmarkBarBackground)) |
| ? shades[k100] |
| : shades[k800]; |
| actual = provider.GetColor(kColorSavedTabGroupForegroundRed); |
| EXPECT_EQ(expected, actual); |
| |
| // kColorSavedTabGroupOutlineRed |
| expected = color_utils::IsDark(provider.GetColor(kColorBookmarkBarBackground)) |
| ? shades[k300] |
| : shades[k700]; |
| actual = provider.GetColor(kColorSavedTabGroupOutlineRed); |
| EXPECT_EQ(expected, actual); |
| |
| // kColorTabGroupBookmarkBarRed |
| expected = color_utils::IsDark(provider.GetColor(kColorBookmarkBarBackground)) |
| ? shades[k1000] |
| : shades[k50]; |
| actual = provider.GetColor(kColorTabGroupBookmarkBarRed); |
| EXPECT_EQ(expected, actual); |
| |
| // kColorThumbnailTabStripTabGroupFrameActiveRed |
| expected = color_utils::IsDark( |
| provider.GetColor(kColorThumbnailTabStripBackgroundActive)) |
| ? shades[k300] |
| : shades[k600]; |
| actual = provider.GetColor(kColorThumbnailTabStripTabGroupFrameActiveRed); |
| EXPECT_EQ(expected, actual); |
| |
| // kColorThumbnailTabStripTabGroupFrameInactiveRed |
| expected = color_utils::IsDark( |
| provider.GetColor(kColorThumbnailTabStripBackgroundInactive)) |
| ? shades[k300] |
| : shades[k600]; |
| actual = provider.GetColor(kColorThumbnailTabStripTabGroupFrameInactiveRed); |
| EXPECT_EQ(expected, actual); |
| } |