blob: f111417adc12447bdd8eb00a8ad5198ad3ecd669 [file] [log] [blame]
// Copyright 2022 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/themes/theme_service.h"
#include <cmath>
#include "base/containers/fixed_flat_set.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/run_loop.h"
#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
#include "base/test/task_environment.h"
#include "chrome/browser/browser_features.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_service_test_base.h"
#include "chrome/browser/themes/custom_theme_supplier.h"
#include "chrome/browser/themes/test/theme_service_changed_waiter.h"
#include "chrome/browser/themes/theme_properties.h"
#include "chrome/browser/themes/theme_service_factory.h"
#include "chrome/browser/themes/theme_service_test_utils.h"
#include "chrome/browser/ui/color/chrome_color_id.h"
#include "chrome/browser/ui/color/chrome_color_mixers.h"
#include "chrome/common/buildflags.h"
#include "chrome/common/chrome_features.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_util.h"
#include "extensions/browser/test_extension_registry_observer.h"
#include "extensions/common/extension.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/color_utils.h"
#include "ui/native_theme/test_native_theme.h"
#include "ui/ozone/public/ozone_platform.h"
#include "ui/views/linux_ui/linux_ui.h"
#include "ui/views/linux_ui/linux_ui_factory.h"
#include "ui/views/views_features.h"
namespace theme_service_internal {
class ThemeServiceTest : public extensions::ExtensionServiceTestBase {
public:
ThemeServiceTest() = default;
~ThemeServiceTest() override = default;
void SetUp() override {
extensions::ExtensionServiceTestBase::SetUp();
extensions::ExtensionServiceTestBase::ExtensionServiceInitParams params =
CreateDefaultInitParams();
params.pref_file = base::FilePath();
InitializeExtensionService(params);
service_->Init();
registry_ = extensions::ExtensionRegistry::Get(profile());
ASSERT_TRUE(registry_);
theme_service_ = ThemeServiceFactory::GetForProfile(profile());
ASSERT_TRUE(theme_service_);
}
SkColor GetColor(ThemeService* theme_service, int id, bool incognito) const {
return theme_service->theme_helper_.GetColor(
id, incognito, theme_service->GetThemeSupplier());
}
protected:
ui::TestNativeTheme test_native_theme_;
raw_ptr<extensions::ExtensionRegistry> registry_ = nullptr;
raw_ptr<ThemeService> theme_service_ = nullptr;
};
class ThemeProviderRedirectedEquivalenceLinuxTest : public ThemeServiceTest {
public:
ThemeProviderRedirectedEquivalenceLinuxTest() = default;
// ThemeServiceTest:
void SetUp() override {
ThemeServiceTest::SetUp();
// Only perform mixer initialization once.
static bool initialized_mixers = false;
if (!initialized_mixers) {
// Ensures the toolkit is configured on supported linux platforms.
// Initializing the toolkit also adds the native toolkit ColorMixers.
ui::OzonePlatform::InitParams ozone_params;
ozone_params.single_process = true;
ui::OzonePlatform::InitializeForUI(ozone_params);
auto linux_ui = CreateLinuxUi();
linux_ui_ = linux_ui.get();
ASSERT_TRUE(linux_ui_);
views::LinuxUI::SetInstance(std::move(linux_ui));
// Add the Chrome ColorMixers after native ColorMixers.
ui::ColorProviderManager::Get().AppendColorProviderInitializer(
base::BindRepeating(AddChromeColorMixers));
initialized_mixers = true;
}
// Always use system theme.
views::LinuxUI::instance()->SetUseSystemThemeCallback(
base::BindRepeating([](aura::Window* window) { return true; }));
theme_service_->UseSystemTheme();
}
void TearDown() override {
// Restore the original NativeTheme parameters.
ThemeServiceTest::TearDown();
}
protected:
views::LinuxUI* linux_ui_;
};
// TODO(crbug.com/1310397): There're mismatched colors in some Linux themes.
// Enable this test after fixing them.
// TODO(crbug.com/1323745): Fix consecutive failures on Linux.
#if BUILDFLAG(IS_LINUX)
#define MAYBE_GetColor DISABLED_GetColor
#else
#define MAYBE_GetColor GetColor
#endif // BUILDFLAG(IS_LINUX)
TEST_F(ThemeProviderRedirectedEquivalenceLinuxTest, MAYBE_GetColor) {
const ui::ThemeProvider& theme_provider =
ThemeService::GetThemeProviderForProfile(profile());
static constexpr const auto ignored_color_ids = base::MakeFixedFlatSet<
ui::ColorId>(
{// Ignore IPH colors due to behavior change.
// Original: always Google blue, redirected: follow the accent color.
ThemeProperties::COLOR_FEATURE_PROMO_BUBBLE_BACKGROUND,
ThemeProperties::COLOR_FEATURE_PROMO_BUBBLE_CLOSE_BUTTON_INK_DROP,
ThemeProperties::COLOR_FEATURE_PROMO_BUBBLE_DEFAULT_BUTTON_FOREGROUND});
std::vector<std::string> themes =
linux_ui_->GetAvailableSystemThemeNamesForTest();
for (const std::string& theme : themes) {
linux_ui_->SetSystemThemeByNameForTest(theme);
for (auto color_id : theme_service::test::kTestColorIds) {
if (ignored_color_ids.contains(color_id))
continue;
std::string error_message =
base::StrCat({"GTK theme ", theme, ": ",
theme_service::test::ColorIdToString(color_id),
" has mismatched values"});
theme_service::test::TestOriginalAndRedirectedColorMatched(
theme_provider, color_id, error_message);
}
}
}
} // namespace theme_service_internal