blob: 8442fecff60ad87f1e83f58f530cdff05d75240b [file] [log] [blame]
// Copyright 2019 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/ui/views/frame/browser_frame.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "chrome/browser/devtools/devtools_window_testing.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/themes/theme_service.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/views/chrome_views_delegate.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
#include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
#include "chrome/browser/web_applications/web_app_install_info.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/invalidate_type.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "ui/base/ui_base_features.h"
#include "ui/color/color_id.h"
#include "ui/color/color_mixer.h"
#include "ui/color/color_provider.h"
#include "ui/color/color_provider_manager.h"
#include "ui/color/color_recipe.h"
#include "ui/views/views_delegate.h"
class BrowserFrameBoundsChecker : public ChromeViewsDelegate {
public:
BrowserFrameBoundsChecker() {}
void OnBeforeWidgetInit(
views::Widget::InitParams* params,
views::internal::NativeWidgetDelegate* delegate) override {
ChromeViewsDelegate::OnBeforeWidgetInit(params, delegate);
if (params->name == "BrowserFrame")
EXPECT_FALSE(params->bounds.IsEmpty());
}
};
class BrowserFrameTest : public InProcessBrowserTest {
public:
BrowserFrameTest()
: InProcessBrowserTest(std::make_unique<BrowserFrameBoundsChecker>()) {}
};
// Verifies that the tools are loaded with initial bounds.
IN_PROC_BROWSER_TEST_F(BrowserFrameTest, DevToolsHasBoundsOnOpen) {
// Open undocked tools.
DevToolsWindow* devtools_ =
DevToolsWindowTesting::OpenDevToolsWindowSync(browser(), false);
DevToolsWindowTesting::CloseDevToolsWindowSync(devtools_);
}
// Verifies that the web app is loaded with initial bounds.
IN_PROC_BROWSER_TEST_F(BrowserFrameTest, WebAppsHasBoundsOnOpen) {
auto web_app_info = std::make_unique<WebAppInstallInfo>();
web_app_info->start_url = GURL("http://example.org/");
web_app::AppId app_id = web_app::test::InstallWebApp(browser()->profile(),
std::move(web_app_info));
Browser* app_browser =
web_app::LaunchWebAppBrowser(browser()->profile(), app_id);
ASSERT_TRUE(app_browser->is_type_app());
app_browser->window()->Close();
}
// Runs browser color scheme tests with ChromeRefresh2023 enabled and disabled.
class BrowserFrameColorModeTest : public BrowserFrameTest,
public testing::WithParamInterface<bool> {
public:
static constexpr SkColor kLightColor = SK_ColorWHITE;
static constexpr SkColor kDarkColor = SK_ColorBLACK;
BrowserFrameColorModeTest() {
feature_list_.InitWithFeatureState(features::kChromeRefresh2023,
GetParam());
}
// BrowserFrameTest:
void SetUpOnMainThread() override {
BrowserFrameTest::SetUpOnMainThread();
// Force a light / dark color to be returned for `kColorSysPrimary`
// depending on the ColorMode.
ui::ColorProviderManager::ResetForTesting();
ui::ColorProviderManager::GetForTesting().AppendColorProviderInitializer(
base::BindRepeating(&AddColor));
// Set the default browser pref to follow system color mode.
profile()->GetPrefs()->SetInteger(
prefs::kBrowserColorScheme,
static_cast<int>(ThemeService::BrowserColorScheme::kSystem));
}
protected:
static void AddColor(ui::ColorProvider* provider,
const ui::ColorProviderManager::Key& key) {
// Add a postprocessing mixer to ensure it is appended to the end of the
// pipeline.
ui::ColorMixer& mixer = provider->AddPostprocessingMixer();
mixer[ui::kColorSysPrimary] = {
key.color_mode == ui::ColorProviderManager::ColorMode::kDark
? kDarkColor
: kLightColor};
}
// Sets the `kBrowserColorScheme` pref for the `profile`.
void SetBrowserColorScheme(Profile* profile,
ThemeService::BrowserColorScheme color_scheme) {
profile->GetPrefs()->SetInteger(prefs::kBrowserColorScheme,
static_cast<int>(color_scheme));
}
Profile* profile() { return browser()->profile(); }
private:
base::test::ScopedFeatureList feature_list_;
};
// Verifies the BrowserFrame honors the BrowserColorScheme pref.
IN_PROC_BROWSER_TEST_P(BrowserFrameColorModeTest, TracksBrowserColorScheme) {
// Assert the browser follows the system color mode. Simulate the system color
// mode by setting the widget level color mode override.
views::Widget* browser_frame =
BrowserView::GetBrowserViewForBrowser(browser())->GetWidget();
browser_frame->SetColorModeOverride(
ui::ColorProviderManager::ColorMode::kLight);
EXPECT_EQ(kLightColor,
browser_frame->GetColorProvider()->GetColor(ui::kColorSysPrimary));
browser_frame->SetColorModeOverride(
ui::ColorProviderManager::ColorMode::kDark);
EXPECT_EQ(kDarkColor,
browser_frame->GetColorProvider()->GetColor(ui::kColorSysPrimary));
// Set the BrowserColorScheme pref. The BrowserFrame should ignore the system
// color mode if running ChromeRefresh2023. Otherwise BrowserFrame should
// track the system color mode.
browser_frame->SetColorModeOverride(
ui::ColorProviderManager::ColorMode::kLight);
SetBrowserColorScheme(profile(), ThemeService::BrowserColorScheme::kDark);
if (features::IsChromeRefresh2023()) {
EXPECT_EQ(kDarkColor, browser_frame->GetColorProvider()->GetColor(
ui::kColorSysPrimary));
} else {
EXPECT_EQ(kLightColor, browser_frame->GetColorProvider()->GetColor(
ui::kColorSysPrimary));
}
browser_frame->SetColorModeOverride(
ui::ColorProviderManager::ColorMode::kDark);
SetBrowserColorScheme(profile(), ThemeService::BrowserColorScheme::kLight);
if (features::IsChromeRefresh2023()) {
EXPECT_EQ(kLightColor, browser_frame->GetColorProvider()->GetColor(
ui::kColorSysPrimary));
} else {
EXPECT_EQ(kDarkColor, browser_frame->GetColorProvider()->GetColor(
ui::kColorSysPrimary));
}
}
// Verifies incognito browsers will always use the dark ColorMode.
IN_PROC_BROWSER_TEST_P(BrowserFrameColorModeTest, IncognitoAlwaysDarkMode) {
// Create an incognito browser.
Browser* incognito_browser = CreateIncognitoBrowser(profile());
views::Widget* incognito_browser_frame =
BrowserView::GetBrowserViewForBrowser(incognito_browser)->GetWidget();
// The incognito browser should reflect the dark color mode irrespective of
// the current BrowserColorScheme.
SetBrowserColorScheme(incognito_browser->profile(),
ThemeService::BrowserColorScheme::kLight);
EXPECT_EQ(kDarkColor, incognito_browser_frame->GetColorProvider()->GetColor(
ui::kColorSysPrimary));
SetBrowserColorScheme(incognito_browser->profile(),
ThemeService::BrowserColorScheme::kDark);
EXPECT_EQ(kDarkColor, incognito_browser_frame->GetColorProvider()->GetColor(
ui::kColorSysPrimary));
}
INSTANTIATE_TEST_SUITE_P(All, BrowserFrameColorModeTest, testing::Bool());